I maintain two scripts, one for MS Word, and the other for MS Excel. Other than the application-specifics, they are identical. My thought was to go to maintaining one script, with a dialog-driven switch at the top, like so:
display dialog "Please pick your application." buttons {"Cancel", "MS Word", "MS Excel"} cancel button 1 default button 3 with icon caution
if result is {button returned:"MS Word"} then
set AppId to "com.microsoft.Word"
set AppProcess to "Microsoft Word"
else
set AppId to "com.microsoft.Excel"
set AppProcess to "Microsoft Excel"
end if
tell application "System Events"
tell application id AppId to activate
tell application process AppProcess --scripting the GUI
set myList to (get name of windows)
repeat with i from 1 to count of myList
try
if last word of item i of myList is "Code" then
exit repeat
end if
end try
end repeat
perform action "AXRaise" of window i
end tell
keystroke "a" using command down
delay 1
keystroke "c" using command down
delay 1
--if nothing happens, make sure your code window is frontmost.
end tell
It beeps twice, but doesn’t run. If I hardcode the application id, it does run, which leads me to believe either that I can’t set the id by variable, or more probable, I don’t know how to do it. The scripts are meant to run in the Visual Basic Editor environment, copying vba to the clipboard for follow-on processing.
A work-around. Using a boolean plus hardcoding worked.
property MSword : false
display dialog "Please pick your application." buttons {"Cancel", "MS Word", "MS Excel"} cancel button 1 default button 3 with icon caution
if result is {button returned:"MS Word"} then
set MSword to true
set AppProcess to "Microsoft Word"
else
set MSword to false
set AppProcess to "Microsoft Excel"
end if
tell application "System Events"
if MSword then
tell application id "com.microsoft.Word" to activate
else
tell application id "com.microsoft.Excel" to activate
end if
tell application process AppProcess --scripting the GUI
set myList to (get name of windows)
repeat with i from 1 to count of myList
try
if last word of item i of myList is "Code" then
exit repeat
end if
end try
end repeat
perform action "AXRaise" of window i
end tell
keystroke "a" using command down
delay 1
keystroke "c" using command down
delay 1
--if nothing happens, make sure your code window is frontmost.
end tell
This seems to run beeping for each keystroke without needing the id, unless the id is needed by vba. I don’t have the vba set up.
display dialog "Please pick your application." buttons {"Cancel", "MS Word", "MS Excel"} cancel button 1 default button 3 with icon caution
set UserChoice to button returned of result
if UserChoice is "MS Word" then
launch application "Microsoft Word"
tell application "Microsoft Word" to activate
set AppProcess to "Microsoft Word"
else
launch application "Microsoft Excel"
tell application "Microsoft Excel" to activate
set AppProcess to "Microsoft Excel"
end if
tell application "System Events"
tell application process AppProcess --scripting the GUI
set myList to (get name of windows)
repeat with i from 1 to count of myList
try
if last word of item i of myList is "Code" then
exit repeat
end if
end try
end repeat
perform action "AXRaise" of window i
end tell
keystroke "a" using command down
delay 1
keystroke "c" using command down
delay 1
--if nothing happens, make sure your code window is frontmost.
end tell
Presumably by “doesn’t run” you mean “runs but doesn’t work”. Which bits don’t work? Is there an error message?
In theory, your first script should be OK. activate is a command defined by AppleScript for an event issued by the system and is the same for all applications capable of activating. It doesn’t need to be specifically compiled against the target.
One thing you could try would be to correct the position of that line and put it in front of (ie. outside) the System Events ‘tell’ statement. Nesting ‘tell’ statements to different applications is best avoided where possible, to minimise delays and the chance of conflicts. (But an 'application process, of course, is an element of System Events, so any ‘tell’ to one of those must be nested.)
Another thing you could try for good luck is to set the ‘frontmost’ of the process to ‘true’ as well, just in case anything happens to change the focus after the application activates.
Just shots in the dark, but they’re the only things I can think of which may have a bearing on the odd problem you describe.
tell application id AppId to activate -- or 'activate application id AppId'
tell application "System Events"
tell application process AppProcess
set frontmost to true
set myList to (get name of windows)
-- etc.
By the way, having the ‘perform action’ line after ‘end repeat’ means that the last window will be raised if none of them has a name whose last word is “Code”. If you move the line to before the ‘exit repeat’, it will only be executed when there’s a hit.
Thank you all. Many lessons there. My concept is working. I only had to make the necessary adjustments in one script.
It indeed was “running but not working”. All that part did was to “Select All” and copy to the clipboard from a certain window. When It worked, the window text was highlighted. As first constructed, no highlights, and two beeps, no errors.