Very new to AppleScript and have looked for solutions elsewhere unsuccessfully, apologies if I simply missed the answer elsewhere. Thanks for any help.
Background: I am using AppleScript to prompt the user for a directory, then create numerous folders in that directory with other prompts. As prompts are answered, I want to create a CSV that records these answers to prevent repeated answers and also allow the user to terminate the script and return later without losing items stored in lists. CSV seems the simplest way to do this.
Question- if I target the CSV to a static path I can successfully create the CSV and record to it. If I create a path from a prompt I receive the error: Finder got an error: Can’t make alias "Macintosh HD:Users:MyAccount:_Sample_Directory:" into type constant. number -1700 from alias "Macintosh HD:Users:MyAccount:_Sample_Directory:" to constant
What am I missing?
FYI- using this as basis for the WriteTo function.
Sample Script:
set MyList to {"A", "B", "C"}
tell application "Finder"
--This Works, but doesn't nest in the variable folder--
--set CSVFile to (path to desktop as text) & "List.csv"
--This is the goal:dynamic directory--
set ParentFolder to (choose folder with prompt "Select Folder")
set CSVFile to (path to ParentFolder as string & "List.csv") as POSIX file as alias
end tell
set TheResult to writeto(CSVFile, MyList, list, true)
on writeto(targetFile, theData, dataType, apendData)
try
set openFile to open for access file targetFile with write permission
if apendData is false then set eof of openFile to 0
write theData to openFile starting at eof as dataType
close access openFile
return true
on error
try
close access file targetFile
end try
return false
end try
end writeto
In your script, you do not need to tell application "Finder". So you can remove the tell / end tell.
The error in your script comes from line:
set CSVFile to (path to ParentFolder as string & "List.csv") as POSIX file as alias
Your sub-routine writeto accepts the targetfile to be in form of string like :
"disk:Users:me:folder:list.csv.
Therefore your first line could be reduced to :
set CSVFile to (ParentFolder as string) & "List.csv"
Yes, you can write your data in csv. But I am not sure it is the best choice. When you write the list {"A","B","C"} in your file, you are not writing text. So Applescript does a conversion from list to text. In this example the result is "listutxtAutxtButxtC". It depends what you want to do with that file, but to make it readable, it is better to write text in text file. You can do this by looping through all items of MyList to write each one as a text:
repeat with x in MyList
set TheResult to writeto(CSVFile, x, list, true)
end repeat
In above example, I still use datatype = list, instead of text. It does not matter because the subroutine does not use that parameter.I guess this is for future use.
Still it may not give you the result you're looking for. The text in file will be "ABC". To avoid this, I suggest you to add a return (or a tab) for each data you write in the file. Do to so, change the line in the writeto sub-routine :
write (theData & return) to openFile starting at eof as dataType
Then your cvs file will be
A
B
C
Which is easy to read.
Related
Can you guy please help?
I have a problem to load data from excel into database with dynamic file name in my source files.
For example, for this month, my filename is ABC 31122017.xlsx. I successfully loaded data from each tab in this excel file into database.
But how do I make it dynamic? For example next month I have excel file
ABC 31012018.xlsx. How to make the job dynamic to pick up the new file?
I able to put the date in variable, but I don't know how to proceed with the filepath in SSIS.
#[User::InputPath] + "ABC " + #[User::Report_DT_DDMMYYYY] + ".xlsx"
I used this in Expressions in the Connection already, set up ExcelFilePath, but it couldn't work.
As in Excel Source connector in SSIS, I already chose the 31122017.xlsx and chose the first tab. But after I put in the Expressions, it couldn't find the first tab I chosen already.
Please help me guys. Thank you.
May be below explanation will help you in overcome this issue (I have SSIS 2012) -
First SSIS variable will hold date value i.e., "20180218". Variable Name- TodayDate. This variable value will be change according to today date.
Second SSIS variable will hold FileName i.e., ""D:\SSIS\StackOverFlowTest1\InputFiles\AB " + #[User::TodayDate] + ".xlsx". Variable Name- FileNameExcel.
Create connection manager for excel and under its properties window change expressions and set ExcelFilePath to "FileNameExcel".
Change "Delay Validation" to True under "Data Flow Task" property.
Using a foreach:
Set up a string variable fileName (put in the actual file path / file name so you can develop your package.
Add a Foreach Loop (File Enumerator which is default)
Set Expression for Directory = #InputPath
Set Files to the proper mask for your excel file (i.e. "ABD *.xlsx")
Go to variable mappings and link to fileName
Add an Excel connection and connect to your actual file.
Set an expression on properties to ExcelFilePath = #fileName
Delay Validation
Develop your data flow(s) as normal.
Any help is much appreciated. I am trying to create an SSIS package to loop through files in the folder and get the Path + filename and finally execute the stored proc with parameter as path+filename. I am not sure how to get the path+filename and insert the into the Stored proc as parameter. I have attached the screenshot for your reference:
Looks like you have the right idea in general and the link #Speedbirt186 provided has some good details but it sounds like there are a couple of nuances that I thought I might point out in regards to flow and variables.
The foreach loop can assign the entire path or the file name or file name & extension to a variable. The latter will be the most help in your case if you don't want to add a script task to split the Filename from the path. If you start by adding 5 variables to your project it will make it a little easier. 1 will be the Source Directory Path, another the Destination (Archive) Directory Path, and then 1 to hold the File Name and Extension assigned by the for each loop. Then 2 additional dynamic variables that simply combine the source directory and file name to get the source full path and the destination with file name to get the destination full path.
Next make sure you set up your database and Excel file connections. In your Excel file connection after setting it up go to Expressions in the properties window and set the "Connection String" property to SourceFullPath. This will tell the connection to change the file path at every iteration of your loop.
Now you just need to setup your loop etc. Add the fore each loop container setting a directory, filter, and choose File Name and Extension.
Now in the expression box on the collection page set the directory property to be that of your Source Directory variable.
The last part of the Fore each loop is to set your variable mappings to store the file name in your variable. so go to that tab choose your file name variable and set index to 0.
At this point you can add your data flow and setup your import just like you would with a normal file (note your default value for your file name parameter should be to an actual file with the structure you will want to import).
After your data flow drop in your Execute SQL task and set it up how you need. here is an example of direct input and you can see an easy way to reference a parameter is simply a question mark (?).
Next in your sql task setup your parameter mapping by adding in the details you need such as:
Now you are on to your file task. Drop your file task and setup as you desire, but choose your destination and source full path variables to tell the task which file to move.
that's it your are done. there is 1 more thing to note though. The way you have your precedence set in the image you posted you show going from your data flow to your sql and to your file task simultaneously. If your stored procedure relies on your file you may want to put it after your sql task. You can always change the constraint options to "completion" if you want to move the file even if your stored proc fails.
What you want to do is to create a variable in your package, call it something like Filename. In the Edit window of the Foreach you can configure that variable to be set (on the Variable Mappings page- set index to 0).
To create a variable, you will need to have the Variables window showing. Use the View menu to show it if it's not currently open.
Then when calling your stored procedure you can pass the then current value of the variable as a parameter.
This link might help: https://www.simple-talk.com/sql/ssis/ssis-basics-introducing-the-foreach-loop-container/
I have a Foreach File Enumerator that will read pdf files name from a folder and place the filename into database. However, i wan it to exclude reading filename that has more less than 3 underscore.
AAA_BBB_000004554_060420161906_S1234567H_M.pdf
AAA_BBB_000003345_060420161906_S9876543H_S.pdf
AAA_BBB_000008546_060420161906_S1234123H_V.pdf
AAA_BBB_201604.pdf
etc
AAA_BBB_201604.pdf should be excluded in the loop as the filename only has 2 underscore.
How can i archive that? i did some search and it seems like using expression is the key, but i had no idea how to do it. Kindly help thank you.
This can be done using TOKENCOUNT function in an Expression.
Create 2 variables
FileName of String type
TokenCount of Int32 type
Foreach Loop Container
Use Foreach Loop Container and set the Collection - Foreach File
Enumerator
Specify the folder location where your .pdf files exists
set ".pdf* under Files: Select the radio button Retrieve File Name -
Name only
Map the File Name retrieved
Next, put an Expression task inside the Foreach Loop Container and using the following expression
Next, drop an Execute SQL Task and connect it from Expression task
#[User::TokenCount] = TOKENCOUNT( #[User::FileName] ,"_")
This uses the TOKENCOUNT function - Returns the number of tokens in a string (FileName in your case) that contains tokens separated by the specified delimiters ('_' in your case)
Assign the token count to an int variable - #[User::TokenCount]
In the Precedence constraint Editor, provide the following Constraint Options
Configure the Execute SQL Task
Finally, it should like this
I put script task between Expression task and Execute SQL task for debugging purpose, if you want you my use this
Running the package - let's say you want to load these file names from this folder
Since, we gave the condition in the expression (Token count > 3), after running the package, these file names will be loading in the database
Hope this helps.
I am trying to use an automated macro to export a Ms-Access table to a csv file. I want the destination file to have a unique name, and I reckoned that using now()yyyymmddhhnn would be a good way to achieve this.
I have got transfer text working ok from my macro, and I have set up an export file spec for the transfer.
I am using ="C:\batchfile_" & Format(Now(),"yyyymmddhhnn") & ".csv" in the filename argument in the macro. This bit works.
But when I try to run the macro, it tells me that the filename doesn't exist and then the export doesn't complete. I am not sure why this is, but I think it is because the export file specification is expecting the destination file to have the same filename and column structure as the source table.
Does anyone know a way around this?
Eric
This is very old thread, I am posting my solution so that it may be usefull for some one else
transfer text works fine, as long as variables are supplied properly, you can check for other options other than filename, datasource alternatively create using file open statement
by opening text file and convert recordset data into CSV format.
I've had quite a hard time with this--can anyone help?
I need code for a command button that will import a file (the file will be different each time but will always be either txt. or csv), run an import specification that converts all data types to text (the spec is called SpecsTest), then call the table "Scrubbed" (not the original file name). I've also been unable to create a macro that works--the challenge has been that each time this is run the raw file name will be different.
Haven't used Access, but have done this a lot with Excel. Try this:
Dim ds As FileDialog
Set ds = Application.FileDialog(msoFileDialogOpen)
ds.Show
Dim path as String
path = ds.SelectedItems(1)
You'll have to add some check to ensure that a file was selected, etc, but this should get you on the right track.
BTW, you can configure default directories, filters, ... in the FileDialog so you should be able to limit the tendency of your users to screw up the import, but you never can tell.