Can application id be set by a variable?

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.

Can what I want to do be done? :slight_smile:

Thanks,
…Mick

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

Have no idea why this is better.

…Mick

When you want variable application targets you need to scope your code at compile time. You can try to use an using terms from block around it.


set appID to "com.apple.Finder"

using terms from application "Finder"
	tell application id appID
		get name of disk 1
	end tell
end using terms from

Otherwise the code won’t compile and run.

P.S. I responded only to your remarks about application id and how it’s possible to store them in an variable.

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

Hi Mick.

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.

DJ, flex, Nigel -

Thank you all. Many lessons there. My concept is working. I only had to make the necessary adjustments in one script. :slight_smile:

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.

Thank you for your time.

…Mick