Is there any way (or are there any tools) to batch change the source of a Table Occurrence from a local file to an externally sourced file?
Situation: I manage a hosted database with hundreds of Table Occurrences of 15 or so tables. Some of my users access the database with slow internet connections. While many of the tables need to be updated for the entire workgroup, some data on other tables and UI information is mostly static.
I'd like to take a copy of the database, change the Table Occurrences of the tables which must be shared from a Local File source to an External Source (of the existing server.) I can do this by hand, but it would require thousands of clicks and be prone to inaccuracy. Much better if I can automate the process. (To specify, say, that all Occurrences of my Sales Table move from Local File to External Source.)
I realize that I might be able to so something with AppleScript's UI Scripting if there's not a better way to do it.
No answers so far, so I wrote this yesterday. It's dirty, long-winded and doesn't catch errors but it'll do the job and is something to build off of for the future.
--to prepare to run this script, you should already have the External Data Source set up
--you should also open the Manage > Database menu and select the "Relationships" tab
--set newDataSource to the name of the new external data source
set newDataSource to ""
--obtain tableOccurrences from TableNames ( Get ( FileName ) ) in the Data Viewer and copy the list into the tableOccurrences variable below
--note that tableOccurrences will be a return-separated list which is quite long when set
set tableOccurrences to ""
--a list of which tables should be moved from the local file to the hosted file. Note that these should be proper table names not table occurrences
set tablesToReplace to {"table1", "table2", ..., "tableN"}
tell application "FileMaker Pro Advanced"
activate
end tell
set AppleScript's text item delimiters to {return}
set j to the number of text items of tableOccurrences
repeat until j < 1
tell application "System Events"
tell application Process "FileMaker Pro Advanced"
keystroke text item j of tableOccurrences
keystroke "o" using command down
delay 1
set i to 1
repeat until ((i > (count of rows of table 1 of scroll area 1 of window 1)) or selected of row i of table 1 of scroll area 1 of window 1)
set i to i + 1
end repeat
if (i <= (count of rows of table 1 of scroll area 1 of window 1) and name of static text of row i of table 1 of scroll area 1 of window 1 is in tablestoReplace) then
set currentMasterTable to name of static text of row i of table 1 of scroll area 1 of window 1
set currentOccurrenceName to value of text field 1 of window 1
click pop up button 1 of window 1
tell menu 1 of pop up button 1 of window 1
click menu item newDataSource
end tell
set k to 1
set tableSelected to false
repeat until tableSelected or k > (count of rows of table 1 of scroll area 1 of window 1)
if name of static text of row k of table 1 of scroll area 1 of window 1 = currentMasterTable then
select row k of table 1 of scroll area 1 of window 1
set tableSelected to true
end if
set k to k + 1
end repeat
set value of text field 1 of scroll area 1 of window 1 to currentOccurrenceName
click button "OK" of window 1
else
click button "Cancel" of window 1
end if
end tell
end tell
set j to j - 1
end repeat
Related
I don't know a lot about AppleScript but I have the following computer generated code that I got from automator on Mac. It automates sequential clicks of the same two images on Safari. Sometimes the website gets overloaded and it throws an error 508 for resource limit reached, causing the script to fail as there's no links available for it to click.
My question is whether there's a way to refresh the website every time it throws back the error (by pressing "Command+R" or similar) so that the script may continue running.
Please feel free to re-write the code if it needs help elsewhere
set timeoutSeconds to 120.0
set firstClick to "click image 1 of group 1 of UI Element 38 of UI Element 1 of scroll area 1 of group 1 of group 1 of tab group 1 of splitter group 1 of window \"Inventory - game.net\" of application process \"Safari Technology Preview\""
set secondClick to "click image 1 of UI Element 2 of group 25 of UI Element 1 of scroll area 1 of group 1 of group 1 of tab group 1 of splitter group 1 of window \"Inventory - game.net\" of application process \"Safari Technology Preview\""
repeat 40000 times
my doWithTimeout(firstClick, timeoutSeconds)
delay (random number from 0.2 to 0.75)
my doWithTimeout(secondClick, timeoutSeconds)
delay (random number from 0.2 to 0.75)
end repeat
on doWithTimeout(uiScript, timeoutSeconds)
set endDate to (current date) + timeoutSeconds
repeat
try
run script "tell application \"System Events\"
" & uiScript & "
end tell"
exit repeat
on error errorMessage
if ((current date) > endDate) then
error "Can not " & uiScript
end if
end try
end repeat
end doWithTimeout
Errors
I had written the code below, and it seems to work until it select the row.
However, click checkbox doesn't work even though it doesn't give any errors.
tell application "System Preferences"
activate
reveal anchor "shortcutsTab" of pane id "com.apple.preference.keyboard"
end tell
tell application "System Events"
tell application process "System Preferences"
repeat while not (window 1 exists)
end repeat
tell window 1
repeat while not (rows of table 1 of scroll area 1 of splitter group 1 of tab group 1 exists)
end repeat
repeat with current_row in (rows of table 1 of scroll area 1 of splitter group 1 of tab group 1)
if value of static text 1 of current_row is equal to "Input Sources" then
select current_row
exit repeat
end if
end repeat
repeat while not (rows of outline 1 of scroll area 2 of splitter group 1 of tab group 1 exists)
end repeat
repeat with current_row in rows of outline 1 of scroll area 2 of splitter group 1 of tab group 1
if name of UI element 2 of current_row is equal to "Select next source in input menu" then
select current_row
click checkbox of current_row
exit repeat
end if
end repeat
end tell
end tell
end tell
What I have tried
I wrote below alternatively, but they all not work.
set value of checkbox of selected_row
set checkbox of selected_row to true
References
I searched many articles, but it doesn't solve.
How to click a checkbox of a drop-down tab in System Preferences
http://hints.macworld.com/article.php?story=20040317131326880
Any help is appreciated.
Change:
click checkbox of current_row
To:
click checkbox of UI element 1 of current_row
Tested your script on macOS Mojave, making the change shown above, and it worked as desired.
The general question from my specific problem is how to interact WITH a running Applescript without leaving the program you a currently in. Its kind of the opposite question of how to USE Applescript to interact with other programs.
I need to go through a lot of web pages and input information from them into a spreadsheet. I have somewhat automated the process with an Applescript that takes an webpage as input and then opens its relevant links one by one, waiting for a click in a dialog box before proceeding to the next.
If you want to run the script, use http://www.resultat.dk/tennis/challenger-singler/champaign/resultater/ as input to the dialog box
--Let the user input the the main webpage
display dialog "Linkzor" default answer ""
set tunering to text returned of result
--get the javascript of the web page
tell application "Safari"
tell window 1
open location tunering
end tell
delay 5
set listen to "" as string
tell front document to set ¬
startText to {name, do JavaScript "window.document.documentElement.outerHTML"}
end tell
set listen to {}
set teksten to startText as string
--Gets all the relevant link variables of the web page
repeat with i from 1 to 500
set forekomst to text (nthOffset(teksten, "g_2_", i) + 4) thru (nthOffset(teksten, "g_2_", i) + 11) of teksten
if nthOffset(teksten, "g_2_", i) = 0 then exit repeat
set punkt to "http://www.resultat.dk/kamp/" & forekomst & "/#kampreferat"
set listen to listen & punkt
end repeat
set lengde to count of listen
--opens the links one by one.
repeat with x from 1 to lengde
tell application "Safari"
tell window 1
set URL of document 1 to item x of listen
end tell
end tell
--THIS IS THE PART I WANT TO INTERACT WITH FROM OUTSIDE THE SCRIPT
set question to display dialog "forsæt?" buttons {"Ja", "nej"} default button 1
set answer to button returned of question
if answer is "nej" then exit repeat
end repeat
on nthOffset(myText, subString, n)
set astid to AppleScript's text item delimiters
set AppleScript's text item delimiters to subString
-- There will be one more text item than there are instances of the substring in the string, so:
if (count myText's text items) > n then
-- There are at least n instances of the substring in the text.
-- The first character of the nth instance comes immediately after the last
-- character of the nth text item.
set o to (count text from text item 1 to text item n of myText) + 1
else
-- There isn't an nth instance of the substring in this text.
set o to 0
end if
set AppleScript's text item delimiters to astid
return o
end nthOffset
Now I would like to automate it a bit further so I didn´t have to leave the spreadsheet to click the dialog box when going to the next webpage. Is there a way to force the Applescript proceed without me actually clicking the dialog box? I have tried to save the script as an application ("hent2") and made another script to sent an "enter" keystroke to it while it is running (and then activate the new script through some kind of hotkey):
tell application "System Events"
tell application "hent2" to activate
key code 36
end tell
It does´t do anything.
Any suggestions on how to proceed? Either with the "sent keystroke to Applescript" or a more elegant solution?
EDIT:
I go it to work with the "Hitting a button" solution from Jerry below.
But I can´t get the handler solution to work. It clearly communicating with the main script because it tells me it can´t find the list "listen" of urls:
"error "hent3 got an error: The variable listen is not defined." number -2753 from "listen""
I define and assign values to "listen" in the part that is autorun when I save and run the script as a program. But when I call the subroutine from another Applescript it knows nothing about "listen"
Here is my attempt:
--Let the user input the the main webpage
display dialog "Linkzor" default answer ""
set tunering to text returned of result
--get the javascript of the web page
tell application "Safari"
tell window 1
open location tunering
end tell
delay 5
tell front document to set ¬
startText to {name, do JavaScript "window.document.documentElement.outerHTML"}
end tell
set listen to {} --HERE I DEFINE THE VARIABLE
set teksten to startText as string
--Gets all the relevant link variables of the web page
repeat with i from 1 to 500
set forekomst to text (nthOffset(teksten, "g_2_", i) + 4) thru (nthOffset(teksten, "g_2_", i) + 11) of teksten
if nthOffset(teksten, "g_2_", i) = 0 then exit repeat
set punkt to "http://www.resultat.dk/kamp/" & forekomst & "/#kampreferat"
set listen to listen & punkt -HERE I ASSIGN VALUES TO IT
end repeat
set lengde to count of listen
set i to 1
on ContinueOnward()
tell application "Safari"
tell window 1
set URL of document 1 to item i of listen --HERE IT ISN`T RECOGNISED
end tell
end tell
set i to i + 1
if i > lengde then
display notification "slut"
end if
end ContinueOnward
on nthOffset(myText, subString, n)
set astid to AppleScript's text item delimiters
set AppleScript's text item delimiters to subString
-- There will be one more text item than there are instances of the substring in the string, so:
if (count myText's text items) > n then
-- There are at least n instances of the substring in the text.
-- The first character of the nth instance comes immediately after the last
-- character of the nth text item.
set o to (count text from text item 1 to text item n of myText) + 1
else
-- There isn't an nth instance of the substring in this text.
set o to 0
end if
set AppleScript's text item delimiters to astid
return o
end nthOffset
Hitting a button
First, when scripting dialogs, if you want to press a button, use System Event’s click button:
tell application "System Events"
tell application process "hent2"
tell window 1
click button "Ja"
end tell
end tell
end tell
This works even if the process being hit is not front-most, so it might be all you need.
Activating via handler
You can also activate handlers in one AppleScript via a tell in another AppleScript. For example, save this as Test Handler, as Application and Stay Open After Run:
on ContinueOnward()
display notification "Continuing Onward"
end ContinueOnward
Then, in Script Editor, write the following script:
tell application "Test Handler"
ContinueOnward()
end tell
You should see a notification pop up saying “Continuing Onward” when you run that script. In your own script, of course, you could use that handler to move on to the next URL.
In order to maintain variables across different handlers, you will need to use either properties or globals or some combination. Properties maintain their values across runs of the application; globals only maintain their values across one run of the application. As I read your needs, you will need globals. In every handler that needs access to the global, use:
global variablename
And you’ll also need to initialize the variable outside of the handler.
For example, this application (Save As Application, Stay Open) will change its notification message, and then quit, after the fourth time:
set currentCount to 0
on ContinueOnward()
global currentCount
set currentCount to currentCount + 1
if currentCount < 5 then
display notification "Continuing with item " & currentCount
else
display notification "Quitting"
quit
end if
end ContinueOnward
In your case, you will want to make i, listen, and lengde be global variables. Put:
global i, listen, lengde
at the top of your handler, as I did with currentCount at the top of the example ContinueOnward handler.
In Microsoft Excel, I'm trying to use AppleScript to hide a bunch of rows that match a simple query: if the value of column F is 0.0. I have it working, but the script has to loop through each match to hide it, which is slower – and less elegant – than I'd like:
tell application "Microsoft Excel"
tell used range of active sheet of active workbook
set row_references to ((every row whose value of cell 6 is 0.0))
repeat with current_row in row_references
set hidden of entire row of current_row to true
end repeat
end tell
end tell
What I would really like, is if I could hide each row just using one Apple Event:
tell application "Microsoft Excel"
tell used range of active sheet of active workbook
set hidden of (entire row of (every row whose value of cell 6 is 0.0)) to true
end tell
end tell
… but this throws an error: "Can’t set hidden of entire row of every row of used range of active sheet of active workbook whose value of cell 6 = 0.0 to true."
If I used the "delete" verb, I can do something close to what I'm after:
tell application "Microsoft Excel"
tell used range of active sheet of active workbook
delete (every row whose value of cell 6 is 0.0)
end tell
end tell
This just deletes every matching row in one fell swoop, no looping required.
(Note that I had to use the "entire row" reference in the first two examples, because the "hidden" property will only work if you specify an entire row or column as a range. The delete command doesn't have this requirement.)
So my question is: is what I'm trying to do even possible? Why does the "delete" verb work with no problems, but it doesn't seem to like "set"?
Thanks.
I'm trying to use AppleScript to click an item in a select box.
When clicking the 'More...' item manually with the mouse a standard OSX file chooser dialog opens up, but when I try to do it using AppleScript, the 'More...' item shows up as the chosen item for the select box, but no dialog shows up.
So far I've tried... (element names came from Automator recorder)
tell application "System Events"
click static text 1 of window 1 of application process "DYMO Word Addin"
-- combo box arrow
click UI Element 1 of combo box 2 of group 1 of window 1 of application process "DYMO Word Addin"
set labelsList to (list 1 of scroll area 1 of combo box 2 of group 1 of window 1 of application process "DYMO Word Addin")
set numLabelsInList to (count text fields of labelsList)
set theTextField to (text field numLabelsInList of labelsList)
if numLabelsInList > 1 then
repeat with z from 1 to (numLabelsInList - 1)
key code 125 -- down arrow
end repeat
end if
-- stuff I've tried
click theTextField
keystroke return
key code 36 -- return
set focused of theTextField to true
set value of attribute "AXFocused" of theTextField to true
perform action "AXConfirm" of theTextField
end tell
... and now I'm out of ideas.
After a bunch more testing, it turns out that the file dialog only opens when the combo box has focus, and that clicking the combo box arrow button and menu items doesn't actually give it focus.
http://lists.apple.com/archives/accessibility-dev/2006/Oct/msg00013.html
After trying all of the methods from that thread to give the element focus, even 'click at' didn't work.
https://apple.stackexchange.com/questions/40141/when-mousekeys-are-on-how-do-i-click-or-move-the-mouse-using-applescript#answer-40859
That answer recommends cliclick as another way to move and click the mouse, which worked.
So in the end I ended up with
click static text 1 of window 1 of application process "DYMO Word Addin"
set labelsComboBox to (combo box 2 of group 1 of window 1 of application process "DYMO Word Addin")
tell labelsComboBox
set {xPosition, yPosition} to position of labelsComboBox
set {xSize, ySize} to size
end tell
set {realXPosition, realYPosition} to {(xPosition + (xSize div 2)) as string, (yPosition + (ySize div 2)) as string}
do shell script "/usr/local/bin/cliclick m:" & realXPosition & "," & realYPosition & " dc:" & realXPosition & "," & realYPosition
-- combo box arrow
click UI element 1 of labelsComboBox
...
Here you can find someone with a similar question and the answer was also cliclick
https://discussions.apple.com/message/17662850#17662850