I am a beginner in AppleScript and I am trying to code a script that will write data into a list directly from a Numbers table.
So I coded this function:
on readTableABC(sheetName)
set readTable to {}
tell table "Table 1" of sheetName
set rowCellCount to count of cells of column "A"
tell column "B"
repeat with i from 2 to rowCellCount
set the end of readTable to value of cell i
end repeat
end tell
end tell
return readTable
end readTableABC
sheetName will actually take the sheet name of the Numbers file.
When I compile, I get an error which says:
Syntax Error: Expected end of line but found """ .
And the cursor shows this character:
[Character pointed out by the compiler][1]
[1]: https://i.stack.imgur.com/VUqxa.png
Would you have any idea where the mistake would be?
Thanks a lot for your help.
Nicolas
As mentioned by red_menace:
In order for the scripting terminology from the Numbers application to be used, they need to be included in a tell application "Numbers" statement, or a use application "Numbers" statement needs to be declared.
Related
PreNote: I am open and hungry for any information, advice, tip etc.
Hello Everyone!
I am trying to create automation with applescript. This is my first personal applescript task but I have some valuable questions. Basically I am trying to catch live notifications from a website and display them in mac os notification.
I am trying to build process for a few days but I don't want to give a mess to you :) so I have roughly explained my process below.
(* Variables used in whole process
set $webToCheck > This is Safari webpage which I want to run my script on it. It won't be front window, script should be run with its name or other property.
set $theClass > This is class name of DOM element to check if it is exist or not. This class is not always exist on DOM of $webpage. It comes with notifications so when use it in "do Javascript" I got error "variable is not defined"
set $num > number of class to use in "do Javascript"
set $input > variable to assign HTML text
set $modifiedInput > Text of input seperated from HTML tags
*)
-- Step 1
tell application "Safari"
work on $webToCheck
-- Step 2
repeat until $input is not empty
set input do Javascript
document.getElementsByClassName > $theClass, $num of $webToCheck
end repeat
-- Step 3
modify text of $input to seperate from RAW HTML -- For example: <a class="" value=""> TEXT to be seperated </a>
Display notification $modifiedInput
-- Step 4
Go back to step 1 or 2 to check and display notification again
First of all, here are some general tips though:
Applescript won't accept $ at the start of variable names.
The variable assignment you are looking for is set {variable} to {value}. You can optionally at the end of it clarify the variable's class using as {class} at the end of the assignment.
Focusing a certain website does not happen with work on {URL} but as with most object oriented things in Applescript with the tell-statement. It will be shown in the full solution.
Text concatenation in Applescript happens with &. So something like "Hello " & "World" is the standard way to do it.
Modification of most things in Applescript happens with set.
It is easier to use innerText instead of innerHTML as splitting text in Applescript is a bit of a pain.
There is no goto but you could wrap the first few steps into a function, which are declared with on or to in Applescript.
Here is the full code with some documentation sprinkled in there:
global webToCheck, theClass, num, input --This says that all variables can be used even in functions.
set webToCheck to "youtube.com" --Strings can only use double quotes.
set theClass to "style-scope yt-alert-with-actions-renderer" --I will use an actual demo to prove that it is working
set num to 0 as integer -- This is the type declaration I was talking about. For numbers we have integer, real(float) and number.
set input to "" -- You don't have define everything at the top, but I will do so for this.
on displayNotification()
tell application "Safari"
tell window 1 -- This will target only the first window. For multiple windows you would have to write a repeat with-loop(for-loop), which I'm not going to do, for the sake of simplicity.
tell (first tab whose URL contains webToCheck) -- This targets just the first tab which contains the webToCheck variable.
set input to do JavaScript "document.getElementsByClassName('" & theClass & "')[" & num & "].innerText" -- This is the way I would go about writing the Javascript. I think you had something different in mind, but this works for my example.
display notification (paragraph 1 of input) with title webToCheck -- This displays the first line of my input since that is the relevant part. I also set a title so I doesn't just say "Script Editor"
end tell
end tell
end tell
end displayNotification
repeat 4 times -- I think this is quite obvious. Adjust this to your needs.
displayNotification()
delay 4
end repeat
Running this while having not used youtube on Safari in a while it displays this:
Note that this isn't the most elegant solution, but I think it is readable and it (hopefully) works for your needs.
I've created an AppleScript to parse MS Word XML files in order to generate a tab-separated document to be opened in Excel. Everything works great for small to medium sized XML files. However, I receive the error, "System Events got an error: Connection is invalid. (-609)", when parsing larger files. Below is the tell block where the error occurs:
tell application "System Events"
activate
with timeout of 0 seconds
set quit delay to 0
set theXMLFile to XML file theDocument
set theRecords to XML elements of XML element "wx:sect" of XML element "w:body" of XML element "w:wordDocument" of theXMLFile whose name is "w:p"
end timeout
end tell
I've attempted to adjust both the timeout and quit delay parameters, including commenting them out, but I still receive the error even with these set to 0. I've tested the script to make sure it makes it passed the "set theXMLFile..." line, but does not make it passed the "set theRecords..." line.
To confirm there is not an issue with the XML file, I manually split the document into two smaller files. Each of these files processed just fine through the scrip. This leads me to believe the error is either to do the size of the theRecords variable or some sort of timeout as a result of the time it takes to parse the file.
Any help in resolving or troubleshooting this error would be greatly appreciated. Thank you.
As I checked the problem is to using whose clause with property which is not direct property of XML elements. You can check this in the Script Debugger. Following works with large XML files. At least for me it worked:
-- set theDocument to "HARD_DISK:Users:123:Desktop:TEST files:SampleLarge.xml"
set aList to {}
tell application "System Events"
activate
tell (contents of XML file theDocument) to tell (XML element "w:wordDocument")
tell (XML element "wx:sect" of XML element "w:body")
set XMLElements to XML elements
set XMLElementNames to name of XML elements
repeat with i from 1 to count XMLElementNames
if (item i of XMLElementNames) is "w:p" then
set end of my aList to item i of my XMLElements
end if
end repeat
end tell
end tell
end tell
return aList
So I'm a novice with AppleScript but learning a lot. I'm trying to create an AppleScript to let me know when Apple Compressor is finished encoding and notify me if it was successful or not. I have the part down about telling when compressor is done and the notification but having difficulty getting the file name and status (complete/fail/cancelled) from Compressor's history log.
Originally tried with UI scripting, but Compressor's window hierarchy list changes with every new encode. So now onto pulling it from the history log, which is in the user folder "Library/Application Support/" folder like this:
And then, the file itself contains the status (whether it was successful or failed) near the bottom of the file like this:
So getting confused about how to A) find the last file and its name, and B) get the value of the last "ElementStatusState" in the document.
This is where I started but get errors when trying to resolve the path to the folder:
tell application "Finder"
set latestFile to (last item of (sort (get files in folder "~/Library/Application Support/Compressor/History/V4" of application "System Events") by name)) as text
set fileName to latestFile's name
end tell
This code throws an error about not being able to make it into the expected file type but also, I can see that It's grabbing a file that's not the last one modified.
In the end I want 2 variables that are 1) theFileName = ie name of encoded movie(s), and 2) theStatus = ie number 4,5, or 6)
Any ideas out there?
You'll want to do something like the script below. This script finds the most recently modified file, then drills down through the plist file to find the various status numbers, and the names of the records they are logged in. I'm assuming that every file Compressor generates has the same structure; if not, you may find you have to alter the script. But this should give you an idea how to do that.
Names and status values are stored in the nameList and valueList variables, in order of depth.
set filePath to POSIX file "~/Library/Application Support/Compressor/History/V4"
-- sort the file list by modification date, then get the last item.
tell application "Finder"
set mostRecentFile to last item of (sort files of folder filePath by modification date) as alias
end tell
set mostRecentFilePath to POSIX path of mostRecentFile
set nameList to {}
set valueList to {}
tell application "System Events"
set plistFile to property list file mostRecentFilePath
tell plistFile
tell (first property list item whose kind is record)
copy value of property list item "ElementInfoName" to end of nameList
copy value of property list item "ElementStatusState" to end of valueList
tell (first property list item whose kind is list)
tell (first property list item whose kind is record)
copy value of property list item "ElementInfoName" to end of nameList
copy value of property list item "ElementStatusState" to end of valueList
tell (first property list item whose kind is list)
tell (first property list item whose kind is record)
copy value of property list item "ElementInfoName" to end of nameList
copy value of property list item "ElementStatusState" to end of valueList
end tell
end tell
end tell
end tell
end tell
end tell
end tell
I have an filemaker Pro 13 database with around 120 records (it's for a conference). I want to team it up with BBEdit to create individual files for each abstract, thus applescript. Much to my surprise (and despite a lot of web tips on scripting) '[tag:current record]' is not recognised in the script.
The relevant bit is this:
FM Script:
Loop
Perform Applescript
tell application "FileMaker Pro"
activate
set MyFileName to cell "WebAbstractFileName" of table "SelectionProcess"
set MyWebAbstract to cell "WebAbstract" of table "SelectionProcess" as text
end tell
-- (BBEdit bit, which works fine in testing)
Go to Next Record (exit after last)
End Loop
This works fine if I only want to retrieve the first record!
This applescript is set within a filemaker script which loops through the records but the script doesn't care which record it's in.
I've tried adding 'of current record' before the table reference but it then gives me errors (eg error "FileMaker Pro got an error: Object not found." number -1728 from cell "WebAbstractFileName" of current record of table "SelectionProcess") Without 'current record' it works fine, but only gives me the first record.
Here's (roughly) how you could do this in a Filemaker script:
Go to Layout [ “YourTable” ]
# FIND THE RECORDS OF INTEREST
Perform Find [ Restore ]
Go to Record/Request/Page [ First ]
Loop
New Window [ ]
# ISOLATE THE CURRENT RECORD
Show All Records
Omit Record
Show Omitted Only
Set Variable [ $path; Value:Get ( DocumentsPath ) & "someFolder/" & YourTable::Somefield & ".html" ]
Export Records [ No dialog; “$path” ]
Close Window [ Current Window ]
Go to Record/Request/Page [ Next; Exit after last ]
End Loop
This will export every record in the found set as an individual file into the folder "someFolder" located in the user's Documents folder, using the contents of the YourTable::Somefield field as the filename.
If, as you say, you don't need the separate files, then of course this can be much simpler.
More tinkering solved this. The crucial bit was to change the syntax. The script now reads:
tell application "FileMaker Pro"
activate
tell current record to set MyFileName to cell "WebAbstractFileName"
tell current record to set MyWebAbstract to cell "WebAbstract"
end tell
What seems to happen is that the fields must be visible (yet I had that not be a problem at one point...go figure. If they're visible, you can drop the table specification). This script, wrapped in a Loop block, will act on the found set and (if instructed) exit after the last record.
I append the bbedit script to create a new file and save it with a variable taken from another field in case it's of interest.
tell application "BBEdit"
set notesPath to ":Users:ophiochos:Dropbox:TL Conference Admin:Webpage materials:Abstracts:"
set newFilePath to notesPath & MyFileName & ".html"
set newDoc to make new text document with properties {contents:MyWebAbstract}
tell newDoc
set source language to "HTML"
save to newFilePath
close window
end tell
end tell
Or you could simply create a calculated field that contains the contents of the desired export file for each record, loop through the records one by one, and just use an Export Field Contents ['YourCalculatedField_c'] script step.
You can also use FM to preview the html output by using a web viewer to display your html. This, along with exporting individually, you can get all this functionality without the need for an external program.
If you need to change the text encoding for output files, you can also specify those in an xslt for outputting files:
http://filemakerhacks.com/2012/09/23/export-field-contents-as-utf-8/
Also, if performing applescript from within FileMaker, the "tell application" line is not needed since it is implied.
I am trying to create a service in OSX leopard that counts the number of words of selected text. I have automator set to run an applescript, with the following put in it:
on run {input, parameters}
count words of input
display alert "Words: " & input
return input
end run
When I compile the script, it says it cannot count every word. What am I doing wrong?
Thanks for the help,
Elliott
First of all, I presume you are testing this in Automator, and that's where the error is taking place? If so, the likely problem is that there is no input—so it can't count the words of nothing. In order to test it successfully, you need to temporarily add a "Get Specified Text" action before the Run AppleScript action, and enter some test text into that field. You'll have to remove the Get Specified Text action before using it as an actual service.
Secondly, you need to use
count words of (input as string)
in order to get a proper count, otherwise it'll return zero.
I made one here, on Github:
https://gist.github.com/1616556
The current source is:
on run {input, parameters}
tell application "System Events"
set _appname to name of first process whose frontmost is true
end tell
set word_count to count words of (input as string)
set character_count to count characters of (input as string)
tell application _appname
display alert "" & word_count & " words, " & character_count & " characters"
end tell
return input
end run
Use Automator.app to create a new service, and then select the Run AppleScript action. Paste this code in to the text box, and save as Word and Character Count. Now switch to a new app, select some text, and open the context menu to find the new option.