Looks like no one’s replied in a while. To start the conversation again, simply ask a new question.

How to update popup (drop down) cells in Numbers using Applescript

I understand that the list popups (dropdown lists in cells) cannot be dynamic in Numbers.


I have the same dropdown list in multiple cells and tables, and this list often needs to be changed. Its not practical to amend one list, then copy/paste it into 200 plus cells that require the dropdown facility (they are not in sequential rows).


Can Applescript be used to do the copy/paste function, as i could specify the cell ranges. My simple attempt only managed to copy/paste the cell values rather than the dropdown/popup list.


Any constructive help would be appreciated.


Thanks.

Numbers-OTHER, OS X Mountain Lion (10.8)

Posted on Sep 26, 2013 11:22 AM

Reply
18 replies

Sep 27, 2013 12:36 AM in response to interceptor3

I'm not familiar enough with AppleScript applied to Numbers to offer advice on that.


By hand, it would involve clicking once on the source cell, copying (command-C or Edit>Copy),

then selecting the destination cell(s) and pasting (command-V or Edit > Paste. For discontiguous cells receiving the same pop-up menu, you would need to repeat the select—paste routine for each group. Whether you can do that with AppleScript, I don't know.


Regards,

Barry

Sep 27, 2013 6:13 AM in response to interceptor3

Hello


Here's a sample script you may try to copy range to destination(s). Please change the source and destination ranges as you see fit.


However, please keep in mind that copying and pasting the source range (with popup menus) will result in the every cell in pasted range(s) has the same selected value in popup menu as the source.


If by chance you're trying to update popup menu items list while preserving the current selected value, it would be very tricky process and require different script.


Hope this may help,

H



_main()
on _main()
    tell application "Numbers"
        tell document 1
            set src_1 to a reference to sheet 1's table 2's range "C3:D3" -- source range
            set dst_1_1 to a reference to sheet 2's table 1's range "A1:B10" -- destination range 1
            set dst_1_2 to a reference to sheet 2's table 1's range "D1:E10" -- destination range 2
            set dst_1_3 to a reference to sheet 2's table 3's range "D1:E10" -- destination range 3
            set dstlst_1 to {dst_1_1, dst_1_2, dst_1_3}
            my _copy_range(src_1, dstlst_1)
        end tell
    end tell
end _main

on _copy_range(src, dstlst)
    (*
        reference src : reference to source range object of Numbers
        list dstlst : list of references to destination range object of Numbers
        
        * due to Numbers 09's bug, range must be "a reference to" range:
            e.g., src = a reference to range "A1:B10" of table 1 of sheet 1 of document ...
    *)
    tell application "Numbers" to activate
    
    -- copy range from src
    _select_range(src)
    tell application "System Events"
        tell process "Numbers"
            keystroke "c" using {command down}
        end tell
    end tell
    
    -- paste range to dstlst
    repeat with dst in dstlst
        set dst to dst's contents
        _select_range(dst)
        tell application "System Events"
            tell process "Numbers"
                keystroke "v" using {command down}
            end tell
        end tell
    end repeat
end _copy_range

on _select_range(_range)
    (*
        reference _range : reference to range object of Numbers
        
        * due to Numbers 09's bug, _range must be "a reference to" range:
            e.g., _range = a reference to range "A1:B10" of table 1 of sheet 1 of document ...
    *)
    tell application "Numbers"
        set _table to (_range as record)'s every reference's item 1
        set _sheet to (_table as record)'s every reference's item 1
        my _select_sheet(_sheet) -- [*1]
        set _table's selection range to _range
    end tell
    (*
        [1] this is required to swtich current sheet
    *)
end _select_range

on _select_sheet(_sheet)
    (*
        reference _sheet : sheet object of Numbers
    *)
    set _name to _sheet's name
    tell application "System Events"
        tell process "Numbers"
            set frontmost to true
            tell (window 1 whose subrole = "AXStandardWindow")
                tell splitter group 1
                    tell splitter group 1
                        tell scroll area 1
                            tell outline 1
                                tell (row 1 whose group 1's static text 1's value = _name)
                                    set selected to true
                                end tell
                            end tell
                        end tell
                    end tell
                end tell
            end tell
        end tell
    end tell
end _select_sheet

Sep 28, 2013 4:26 AM in response to interceptor3

Hi Hiroto,


I have this script running, with one issue.


set tValues to my doThis(1) -- get values of the selection

if tValues is not "" then


activate

display dialog "Select the cells where you want to create the PopUp." & return & "After that, click on the 'OK' button."

my doThis(tValues) -- set the cell format of the new selection to "PopUp Menu" and set the values of the each menu item

tell application "Numbers" to display dialog "Done"

else

tell application "Numbers" to display dialog "You must select the cells in a table before running this script."

end if


on doThis(n)

tell application "Numbers"

set tTables to (tables of sheets of front document whose its selection range isnot missing value)

repeat with t in tTables-- t is a list of tables of a sheet

if contents of t is not {} then -- this list is not empty, it's the selected sheet

set activeTable to (get item 1 of t)

if n = 1 then return value of cells of selection range of activeTable-- return values of the selection

set format of (cells of selection range of activeTable) to pop up menu-- set the format to pop up menu

return my setValuePopUp(n) -- set value of each menu item

end if

end repeat

end tell

return ""

end doThis


on setValuePopUp(L)

tell application "System Events"

tell process "Numbers"

set frontmost to true

delay 0.3

set inspectorWindow to missing value

set tWindows to windows whose subrole is "AXFloatingWindow"

repeat with i in tWindows

if exists radio group 1 of i then

set inspectorWindow to i

exit repeat

end if

end repeat

if inspectorWindow is missing value then


keystroke "i" using {option down, command down} -- Show Inspector

else


performaction "AXRaise" of inspectorWindow-- raise the Inspector window to the front

end if

delay 0.3

tell window 1


clickradio button 4 of radio group 1 -- the "cell format" tab

delay 0.3

tell group 2 of group 1

set tTable to table 1 of scroll area 1

set tc to count rows of tTable

set lenL to (count L)


if tc < lenL then -- ** add menu items **

repeat until (count rows of tTable) = lenL


clickbutton 1 -- button [+]

end repeat


keystrokereturn-- validate the default name of the last menu item

else if tc > lenL then -- ** remove menu items **

repeat while exists row (lenL + 1) of tTable

select row (lenL + 1) of tTable


clickbutton 2 -- button [-]

end repeat

end if


tell tTable to repeat with i from 1 to lenL-- ** change value of each menu item **

set value of text field 1 of row i to item i of L

end repeat

end tell

end tell

end tell

end tell

end setValuePopUp


==============================


When the popup is created, if there is one header row, it adds "1" to the list of popup items, if there are two header rows, it adds "1", "2" to the list of popup items. What should i amend to remove this (i have two header rows in my sheet).

I would ideally like to add a "-" to the list (to represent nothing selected in the cell) as default i.e. top of the list (i could add the symbol to my source data but that would look untidy). At the moment, after running the script all cell values change to 1.


Oh, what would the best way to modify the script so it selects a specific cell range? At the moment i have to first select a column, then run the script, then select the source cells, then click ok on the dialog box before it does the magic.

Someone else will be running the script, and if its easy to change, i would prefer to have an absolute source cell range values so the user can just rund the script without any selection required.

If you can advise on this, that would be most helpful.

Sep 28, 2013 11:08 AM in response to interceptor3

Hello


Well, the script you're using is not mine. It was written by Jacques Rioux in this thread:


(programmatically) populate pop-up list with range of values from another table

https://discussions.apple.com/thread/4273829?start=0&tstart=0


Here I chose to write a new script because it is easier for me than to edit other's code. 😉


You can specify the source range which defines the popup item list and destination range where resulting popup menus are put in script. The set_popup_items_from_range(destination_range, source_range) handler will do the job. (Please note the order of the parameters.) Blank cells in source range are ignored and hyphen is added as the first item of list.


Hope this may help,

Hiroto



(*
    set popup menu items in target range to values of source range
    v0.1
        - blank cells in source range are ignored
        - hyphen is added as the first popup item which is to be selected
*)
_main()
on _main()
    tell application "Numbers"
        activate
        tell document 1
            set src to a reference to sheet 1's table 1's column "G" -- source range (defining popup item list)
            --set src to a reference to sheet 1's table 1's range "G1:G10" -- source range (defining popup item list)
            set dst to a reference to sheet 1's table 1's range "C3:C40" -- destination range (for resulting popup menu)
            my set_popup_items_from_range(dst, src)
        end tell
    end tell
end _main

on set_popup_items_from_range(dst, src)
    (*
        reference dst : reference to destination range object of Numbers
        reference src : reference to source range object of Numbers
        
        * set popup menu items in dst using the values obtained from src
    *)
    script o
        property aa : {}
        property bb : {}
        
        on _undo()
            tell application "Numbers" to activate
            tell application "System Events"
                tell process "Numbers"
                    keystroke "z" using {command down} -- undo
                end tell
            end tell
        end _undo
        on _delete()
            (*
                virtual key code:
                    kVK_Delete    = 0x33    (51)
            *)
            tell application "Numbers" to activate
            tell application "System Events"
                tell process "Numbers"
                    key code 51 -- delete
                end tell
            end tell
        end _delete
        
        -- get list of values (=aa) from src
        (*
            - empty cells are ignored
            - (optional) hyphen is added as first item
        *)
        tell application "Numbers"
            tell src
                set aa to every cell's value as list
                set format to text
                set bb to every cell's value as list -- [*1]
                my _undo() -- undo format change
            end tell
        end tell
        repeat with i from 1 to count my aa
            if my bb's item i = 0.0 then -- [*1]
                set my aa's item i to missing value -- ignore empty cells
            else
                set my aa's item i to my aa's item i as string
            end if
        end repeat
        set aa to my aa's strings -- filter out missing value
        set aa's beginning to "-" -- (optional) add hyphen at the beginning of aa
        
        -- set popup menu items in dst using aa
        _select_range(dst)
        _delete()
        tell application "Numbers"
            tell dst
                set format to pop up menu
            end tell
        end tell
        set_popup_items(aa)
        (*
            [1] Empty cell is represented as 0.0 while number 0.0 is represented as "0.0" when format is text.
                This behaviour lets us distinguish empty cell from cell containing 0.0.
        *)
    end script
    tell o to run
end set_popup_items_from_range

on set_popup_items(dd)
    (*
        list dd : list of pop up item's string values
    *)
    tell application "System Events"
        tell process "Numbers"
            -- bring Numbers to front
            set frontmost to true
            -- open new inspector window
            tell menu bar 1's menu bar item 9 -- view
                if menu 1's menu item 11's enabled then
                    tell menu 1's menu item 11 -- new inspector
                        click
                    end tell
                else
                    tell menu 1's menu item 10 --  inspector
                        click
                    end tell
                end if
            end tell
            -- set pop up menu items
            set c to count dd
            tell (window 1 whose subrole = "AXFloatingWindow") -- front inspector window
                tell radio group 1
                    tell radio button 4 -- cell
                        click
                    end tell
                end tell
                tell group 1
                    tell group 2
                        tell scroll area 1
                            tell table 1 -- pop up menu items table
                                set k to count rows
                                if k > 0 then select row 1
                            end tell
                        end tell
                        repeat c - k times
                            click button 1 -- +
                        end repeat
                        repeat k - c times
                            click button 2 -- -
                        end repeat
                        tell scroll area 1
                            tell table 1 -- pop up menu items table
                                repeat with i from 1 to c
                                    tell row i's text field 1
                                        set focused to true
                                        set value to dd's item i
                                    end tell
                                end repeat
                            end tell
                        end tell
                    end tell
                end tell
                tell (button 1 whose subrole = "AXCloseButton") -- close
                    click
                end tell
            end tell
        end tell
    end tell
end set_popup_items

on _select_range(_range)
    (*
        reference _range : reference to range object of Numbers
        
        * due to Numbers 09's bug, _range must be "a reference to" range:
            e.g., _range = a reference to range "A1:B10" of table 1 of sheet 1 of document ...
    *)
    tell application "Numbers"
        set _table to (_range as record)'s every reference's item 1
        set _sheet to (_table as record)'s every reference's item 1
        my _select_sheet(_sheet) -- [*1]
        set _table's selection range to _range
    end tell
    (*
        [1] this is required to swtich current sheet
    *)
end _select_range

on _select_sheet(_sheet)
    (*
        reference _sheet : sheet object of Numbers
    *)
    set _name to _sheet's name
    tell application "System Events"
        tell process "Numbers"
            set frontmost to true
            tell (window 1 whose subrole = "AXStandardWindow")
                tell splitter group 1
                    tell splitter group 1
                        tell scroll area 1
                            tell outline 1
                                tell (row 1 whose group 1's static text 1's value = _name)
                                    set selected to true
                                end tell
                            end tell
                        end tell
                    end tell
                end tell
            end tell
        end tell
    end tell
end _select_sheet

Sep 29, 2013 4:09 AM in response to interceptor3

Tested the script, fantastic. It copies the source data list, creates the popup list, then pastes the popup facility into the destination cells, inc a leading hyphen in the list.


One more question, to paste the destination into other tables and cell ranges, what should i add?


At the moment that line is


set dst to a reference to sheet 1's table 1's range "C3:C40" -- destination range (for resulting popup menu)


If i want to add a sheet 1's table 2's range "C5:C10" and so on, how can that be formatted (have 12 tables to add the new popups to)


I'm sure a lot of other people will find your script and expertise very useful.


This automation will really help my friend, and save so much time.


Look forward to hearing from you, and hope this is not too much work. All is really appreciated, i wish i knew more about applescript, i'm only just starting to look at it.


Colin

Sep 29, 2013 5:31 AM in response to interceptor3

Hello Colin,


No problem. Here's a revised version which accepts list of destination ranges as the first parameter.


(*
    set popup menu items in target range(s) to values of source range
    v0.11
        - blank cells in source range are ignored
        - hyphen is added as the first popup item which is selected
*)
_main()
on _main()
    tell application "Numbers"
        activate
        tell document 1
            set src_1 to a reference to sheet 1's table 1's column "G" -- source range (defining popup item list)
            --set src_1 to a reference to sheet 1's table 1's range "G1:G10" -- source range (defining popup item list)
            set dst_1_1 to a reference to sheet 1's table 2's range "C5:C10" -- destination range 1 (for resulting popup menu)
            set dst_1_2 to a reference to sheet 1's table 3's range "C5:C10" -- destination range 2 (for resulting popup menu)
            set dst_1_3 to a reference to sheet 1's table 4's range "C5:C10" -- destination range 3 (for resulting popup menu)
            set dstlst_1 to {dst_1_1, dst_1_2, dst_1_3}
            my set_popup_items_from_range(dstlst_1, src_1)
        end tell
    end tell
end _main

on set_popup_items_from_range(dstlst, src)
    (*
        list dstlst : list of references to destination range object of Numbers
        reference src : reference to source range object of Numbers
        
        * set popup menu items in every destination range in dstlst using the values obtained from src

        * due to Numbers 09's bug, range must be "a reference to" range:
            e.g., src = a reference to range "A1:B10" of table 1 of sheet 1 of document ...
    *)
    script o
        property aa : {}
        property bb : {}
        
        on _undo()
            tell application "Numbers" to activate
            tell application "System Events"
                tell process "Numbers"
                    keystroke "z" using {command down} -- undo
                end tell
            end tell
        end _undo
        on _delete()
            (*
                virtual key code:
                    kVK_Delete    = 0x33    (51)
            *)
            tell application "Numbers" to activate
            tell application "System Events"
                tell process "Numbers"
                    key code 51 -- delete
                end tell
            end tell
        end _delete
        
        -- get list of values (=aa) from src
        (*
            - empty cells are ignored
            - (optional) hyphen is added as first item
        *)
        tell application "Numbers"
            tell src
                set aa to every cell's value as list
                set format to text
                set bb to every cell's value as list -- [*1]
                my _undo() -- undo format change
            end tell
        end tell
        repeat with i from 1 to count my aa
            if my bb's item i = 0.0 then -- [*1]
                set my aa's item i to missing value -- ignore empty cells
            else
                set my aa's item i to my aa's item i as string
            end if
        end repeat
        set aa to my aa's strings -- filter out missing value
        set aa's beginning to "-" -- (optional) add hyphen at the beginning of aa
        
        -- set popup menu items in dst using aa
        repeat with dst in dstlst
            set dst to dst's contents
            _select_range(dst)
            _delete() -- clear the destination range
            tell application "Numbers"
                tell dst
                    set format to pop up menu
                end tell
            end tell
            set_popup_items(aa)
        end repeat
        (*
            [1] Empty cell is represented as 0.0 while number 0.0 is represented as "0.0" when format is text.
                This behaviour lets us distinguish empty cell from cell containing 0.0.
        *)
    end script
    tell o to run
end set_popup_items_from_range

on set_popup_items(dd)
    (*
        list dd : list of pop up item's string values
    *)
    tell application "System Events"
        tell process "Numbers"
            -- bring Numbers to front
            set frontmost to true
            -- open new inspector window
            tell menu bar 1's menu bar item 9 -- view
                if menu 1's menu item 11's enabled then
                    tell menu 1's menu item 11 -- new inspector
                        click
                    end tell
                else
                    tell menu 1's menu item 10 --  inspector
                        click
                    end tell
                end if
            end tell
            -- set pop up menu items
            set c to count dd
            tell (window 1 whose subrole = "AXFloatingWindow") -- front inspector window
                tell radio group 1
                    tell radio button 4 -- cell
                        click
                    end tell
                end tell
                tell group 1
                    tell group 2
                        tell scroll area 1
                            tell table 1 -- pop up menu items table
                                set k to count rows
                                if k > 0 then select row 1
                            end tell
                        end tell
                        repeat c - k times
                            click button 1 -- +
                        end repeat
                        repeat k - c times
                            click button 2 -- -
                        end repeat
                        tell scroll area 1
                            tell table 1 -- pop up menu items table
                                repeat with i from 1 to c
                                    tell row i's text field 1
                                        set focused to true
                                        set value to dd's item i
                                    end tell
                                end repeat
                            end tell
                        end tell
                    end tell
                end tell
                tell (button 1 whose subrole = "AXCloseButton") -- close
                    click
                end tell
            end tell
        end tell
    end tell
end set_popup_items

on _select_range(_range)
    (*
        reference _range : reference to range object of Numbers
        
        * due to Numbers 09's bug, _range must be "a reference to" range:
            e.g., _range = a reference to range "A1:B10" of table 1 of sheet 1 of document ...
    *)
    tell application "Numbers"
        set _table to (_range as record)'s every reference's item 1
        set _sheet to (_table as record)'s every reference's item 1
        my _select_sheet(_sheet) -- [*1]
        set _table's selection range to _range
    end tell
    (*
        [1] this is required to swtich current sheet
    *)
end _select_range

on _select_sheet(_sheet)
    (*
        reference _sheet : sheet object of Numbers
    *)
    set _name to _sheet's name
    tell application "System Events"
        tell process "Numbers"
            set frontmost to true
            tell (window 1 whose subrole = "AXStandardWindow")
                tell splitter group 1
                    tell splitter group 1
                        tell scroll area 1
                            tell outline 1
                                tell (row 1 whose group 1's static text 1's value = _name)
                                    set selected to true
                                end tell
                            end tell
                        end tell
                    end tell
                end tell
            end tell
        end tell
    end tell
end _select_sheet



By the way, you can also use sheet/table name instead of index when referencing range such as -


tell document 1
    set _range to a reference to sheet "Sheet A"'s table "Table B"'s range "C5:C10"
end tell


Or if you prefer -


tell document 1
    set _range to a reference to range "C5:C10" of table "Table B" of sheet "Sheet A"
end tell


etc.


All the best,

Hiroto

Sep 29, 2013 5:45 AM in response to Hiroto

Hi Hiroto, just got an error.


I have created 3 more test tables, so 4 in total in sheet 1.


Amended the script...


set src_1 to a reference to sheet 1's table 1's column "b" -- source range (defining popup item list)

set src_1 to a reference to sheet 1's table 1's range "b2:b10" -- source range (defining popup item list)

set dst_1_1 to a reference to sheet 1's table 2's range "C2:C10" -- destination range 1 (for resulting popup menu)

set dst_1_2 to a reference to sheet 1's table 3's range "d2:d10" -- destination range 2 (for resulting popup menu)

set dst_1_3 to a reference to sheet 1's table 4's range "e2:e10" -- destination range 3 (for resulting popup menu)


And received this error.


error "System Events got an error: Can’t get scroll area 1 of group 2 of group 1 of window 1 of process \"Numbers\" whose subrole = \"AXFloatingWindow\". Invalid index." number -1719


Any thoughts?


The content of b2-b10 in table 1 is just a selection of test characters at the moment.


The script stops/highlights at COUNT ROWS in this part...


tell group 1

tell group 2

tell scroll area 1

tell table 1 -- pop up menu items table

set k to count rows

if k > 0 then select row 1

end tell

end tell

repeat c - k times

click button 1 -- +

end repeat

repeat k - c times

click button 2 -- -

end repeat



Any ideas?


Colin

How to update popup (drop down) cells in Numbers using Applescript

Welcome to Apple Support Community
A forum where Apple customers help each other with their products. Get started with your Apple ID.