How do I run UI elements from Script Menu?

I have an AppleScript that helps process a Numbers worksheet. The script has to use “System Events” UI elements to do some of its work. The script runs okay when executed from Script Editor, but I would like to run it directly from Numbers using the Script Menu. When I run it from the Script Menu, it does nothing, because UI elements are not enabled.

The following mini script illustrates the problem:

tell application "System Events"
	display dialog "UI elements enabled: " & (UI elements enabled) as text
end tell

When I run this little script from Script Editor, it says “UI elements enabled: true”; but when I run it from Script Menu, it says “UI elements enabled: false”. I would like to be able to set UI elements to true, but the UI elements enabled property is read only.

How can I enable UI elements in an AppleScript that I run from the Script Menu?

Model: MacBook Air
AppleScript: 2.8.1
Browser: Safari 601.5.17
Operating System: Mac OS X (10.10)

I figured out a solution to this problem, but I still have a mystery. I got the solution from the following item in Apple support:
https://support.apple.com/en-us/HT202802

However, this item says that I should get an alert: “not allowed assistive access”. I never got that alert, but I went directly to System Preferences → Security & Privacy → Privacy → Accessibility. There, I was able to allow SystemUIServer to control my computer. After turning that on, my script runs from the Script Menu in Numbers.

The mystery is, I then un-checked SystemUIServer in the “Allow the apps below to control your computer”. Now my script tells me that UI events are NOT enabled, but my script is still working.

Here is my script. It is designed to fill-down a formula from a selected cell or cells to the bottom of the table. In this demo version, it first displays a dialog saying whether UI elements are enabled.

tell application "System Events"
	display dialog "UI elements enabled: " & (UI elements enabled) as text
end tell


tell application "Numbers"
	activate
	tell active sheet of front document
		set selectedTable to (the first table whose class of selection range is range)
		my fillToBottom(selectedTable, selection range of selectedTable)
	end tell
end tell

on fillToBottom(theTable, startRange)
	tell application "Numbers"
		activate
		tell theTable
			set theColumns to columns of startRange
			set col1 to address of first column of startRange
			set coln to address of last column of startRange
			set row1 to address of last row of startRange
			set rown to row count
			set myAddress to my colLabel(col1) & row1 & ":" & my colLabel(coln) & row1
			set selection range to range myAddress
			delay 0.2
			tell application "System Events" to keystroke "c" using command down
			set myAddress to my colLabel(col1) & row1 & ":" & my colLabel(coln) & rown
			set selection range to range myAddress
			--delay 0.2
			tell application "System Events" to keystroke "v" using command down
		end tell
	end tell
end fillToBottom

on colLabel(n)
	set m to (n - 1)
	set digits to {(m mod 26) + 1}
	set m to m div 26
	repeat while m > 0
		set d to (m mod 26)
		set m to m div 26
		copy d to end of digits
	end repeat
	set myString to ""
	repeat with d in digits
		set myString to (item d of "ABCDEFGHIJKLMNOPQRSTUVWXYZ") & myString
	end repeat
	return myString
end colLabel

If I remember well, we can’t rule access to Assistive devices by a script as we did before.

Now, there is no link between the authorization given thru the prefpane and the status of the checkbox in the pane Assistive Devices.

Your script may be simplified as :




tell application "Numbers"
	activate
	tell active sheet of front document
		set selectedTable to (the first table whose class of selection range is range)
		my fillToBottom(selectedTable, selection range of selectedTable)
	end tell
end tell

on fillToBottom(theTable, startRange)
	tell application "Numbers"
		activate
		tell theTable
			set theColumns to columns of startRange
			set col1 to address of first column of startRange
			set coln to address of last column of startRange
			set row1 to address of last row of startRange
			set rown to row count
			set myAddress to (name of cell row1 of column col1) & ":" & name of cell row1 of column coln
			set selection range to range myAddress
			delay 0.2
			tell application "System Events" to keystroke "c" using {command down}
			set myAddress to (name of cell row1 of column col1) & ":" & name of cell rown of column coln
			set selection range to range myAddress
			--delay 0.2
			tell application "System Events" to keystroke "v" using {command down}
		end tell
	end tell
end fillToBottom

Yvan KOENIG running El Capitan 10.11.4 in French (VALLAURIS, France) vendredi 29 avril 2016 09:53:52

Thanks to Yvan for the improvement to my script.

Thanks for the feedback.

I made more cleaning and take care of possible footer rows.

tell application "Numbers"
	activate
	tell active sheet of front document
		set selectedTable to (the first table whose class of selection range is range)
		my fillToBottom(selectedTable, selection range of selectedTable)
	end tell
end tell

on fillToBottom(theTable, startRange)
	set count_Footers to my countXers("Numbers", "Foot")
	tell application "Numbers"
		activate
		tell theTable
			tell startRange
				set topLeft to name of first cell
				set row1 to address of first row
				set coln to address of last column
			end tell
			set myAddress to topLeft & ":" & name of cell row1 of column coln
			set selection range to range myAddress
			delay 0.2
			tell application "System Events" to keystroke "c" using {command down}
			set myAddress to topLeft & ":" & name of cell -(1 + count_Footers) of column coln
			set selection range to range myAddress
			tell application "System Events" to keystroke "v" using {command down}
		end tell
	end tell
end fillToBottom

#=====
(*
set count_Row_Headers to my countXers("Numbers","R")
set count_Column_Headers to my countXers("Numbers","C") 
set count_Footers to my countXers("Numbers","F")

set count_Row_Headers to my countXers("Pages","R")
set count_Column_Headers to my countXers("Pages","C") 
set count_Footers to my countXers("Pages","F")
*)
on countXers(theApp, what)
	local mt, mi, mm, ms
	if theApp is "Numbers" then
		set mt to 6 (* Table *)
		if "Row" starts with what then
			set mi to 10
		else if "Column" starts with what then
			set mi to 12
		else if "Footer" starts with what then
			set mi to 14
		else
			if my parleAnglais() then
				error """ & what & "" isn't a valid parameter !"
			else
				error "« " & what & " » n'est pas un paramètre géré !"
			end if -- parleAnglais
		end if -- "Row".
	else if theApp is "Pages" then
		set {mt, mi} to {6, 4} (* Format, Table *)
		if "Row" starts with what then
			set mm to 10
		else if "Column" starts with what then
			set mm to 12
		else if "Footer" starts with what then
			set mm to 13
		else
			if my parleAnglais() then
				error """ & what & "" isn't a valid parameter !"
			else
				error "« " & what & " » n'est pas un paramètre géré !"
			end if -- parleAnglais
		end if -- "Row".
	else if theApp is "Keynote" then
		set {mt, mi} to {7, 4}
		set mi to 4
		if "Row" starts with what then
			set mm to 10
		else if "Column" starts with what then
			set mm to 11
		else if "Footer" starts with what then
			set mm to 12
		else
			if my parleAnglais() then
				error """ & what & "" isn't a valid parameter !"
			else
				error "« " & what & " » n'est pas un paramètre géré !"
			end if -- parleAnglais
		end if -- "Row".
	else
		if my parleAnglais() then
			error "The application "" & theApp & "" isn't driven by this script !"
		else
			error "L'application « " & theApp & " » n'est pas gérée par ce script !"
		end if -- parleAnglais
	end if -- theApp.
	activate application theApp
	tell application "System Events" to tell process theApp
		set frontmost to true
		if theApp is "Numbers" then
			tell menu bar 1 to tell menu bar item mt to tell menu 1 to tell menu item mi to tell menu 1
				repeat with ms from 1 to 6
					if value of attribute "AXMenuItemMarkChar" of menu item ms = "✓" then
						set nbXers to ms - 1
						exit repeat
					end if
				end repeat
			end tell
		else # if Pages or Keynote
			tell menu bar 1 to tell menu bar item mt to tell menu 1 to tell menu item mi to tell menu 1 to tell menu item mm to tell menu 1
				repeat with ms from 1 to 6
					if value of attribute "AXMenuItemMarkChar" of menu item ms = "✓" then
						set nbXers to ms - 1
						exit repeat
					end if
				end repeat
			end tell
		end if
	end tell -- System Events.
	return nbXers
end countXers

#=====

on parleAnglais()
	return (do shell script "defaults read 'Apple Global Domain' AppleLocale") does not start with "fr_"
end parleAnglais

#=====

Yvan KOENIG running El Capitan 10.11.4 in French (VALLAURIS, France) vendredi 29 avril 2016 20:35:50