使用applescript在特定工作表上的iWork编号中创建新表

时间:2022-03-07 02:42:39

I am having trouble creating a new table on a specific sheet using Applescript unless the sheet I want insert the new table in is either new or current selected. The general form of the code I am using is:

我无法使用Applescript在特定工作表上创建新表,除非我想要插入新表的表是新的或当前选中的。我使用的代码的一般形式是:

    tell application "Numbers"
    tell document 1
    tell sheet "This is the sheet I want to use"
    make new table with properties {name:"A new table"}
    end tell 
    end tell 
    end tell

Has anyone had any more success at achieving this? This looks to me like a bit of a problem for some advanced spreadsheet scripts in Numbers.

有没有人在实现这一目标方面取得更大成功?对于我来说,这对于Numbers中的一些高级电子表格脚本来说有些问题。

2 个解决方案

#1


OK. My first answer was accepted and could not be deleted, but was inadequate, so I have decided to edit it and add some code which really does solve the problem!

好。我的第一个答案被接受了,无法删除,但是不够,所以我决定编辑它并添加一些真正解决问题的代码!

This code comes via Yvan Koenig, who credits Nigel Garvey. Both are active on the applescript-users list, which is excellent, by the way, not least because of the activity of these two gentlemen, and so many other great AppleScripters.

此代码来自Yvan Koenig,后者称Nigel Garvey。两者都在applescript-users列表中是活跃的,顺便说一下,这非常好,尤其是因为这两位绅士的活动以及许多其他优秀的AppleScripters。

It relies on GUI scripting (which is always a horrible thing to have to fall back on, but it's what we've got).

它依赖于GUI脚本(这一直是一件可怕的事情,但它是我们所拥有的)。

The call to my activateGUIscripting() may cause a prompt for an admin password to appear. If you absolutely know that you have GUI scripting enabled (System Prefs->Universal Access->Enable Access for Assistive Devices) - then you can omit this line.

对activateGUIscripting()的调用可能会导致出现管理员密码的提示。如果您完全知道已启用GUI脚本(系统Prefs->通用访问 - >启用辅助设备访问) - 那么您可以省略此行。

The next two lines are just example calls, so you need a sheet called "Sheet 1" for these example calls to work.

接下来的两行只是示例调用,因此您需要一个名为“Sheet 1”的工作表才能使这些示例调用生效。

This will allow you to create a table in any sheet in any document, regardless of what is selected or frontmost.

这将允许您在任何文档的任何工作表中创建表,无论选择什么或最前面。

--EXAMPLE CALLS
my activateGUIscripting()
my selectsheet(1, "Sheet 1")
my createNewTable(1, "Sheet 1", "myNewTable", 69, 13)

--NUMBERS UTILS
on createNewTable(dName, sName, newTable, nb_rows, nb_columns)
    tell application "Numbers" to tell document dName to tell sheet sName
        make new table with properties {name:newTable, row count:nb_rows, column count:nb_columns}
    end tell
end createNewTable

--=====
on activateGUIscripting()
    (* to be sure than GUI scripting will be active *)
    tell application "System Events"
        if not (UI elements enabled) then set (UI elements enabled) to true
    end tell
end activateGUIscripting
--=====
(*
==== Uses GUIscripting ====
 *)
on selectsheet(theDoc, theSheet)
    script myScript
        property listeObjets : {}
        local maybe, targetSheetRow
        --+++++
        -- set log_report to "point 2 : " & (current date) & return
        --+++++
        tell application "Numbers"
            activate
            set theDoc to name of document theDoc (* useful if the passed value is a number *)
            tell document theDoc to set my listeObjets to name of sheets
        end tell -- "Numbers"…

        set maybe to theSheet is in my listeObjets
        set my listeObjets to {} -- So it will not be saved in the script *)
        if not maybe then
            error "The sheet “" & theSheet & "” is unavailable in the spreadsheet “" & theDoc & "” !"
        end if -- not maybe

        set maybe to 5 > (system attribute "sys2")
        tell application "System Events" to tell application process "Numbers"
            tell outline 1 of scroll area 1 of splitter group 1 of splitter group 1 of window theDoc
                if maybe then (* macOS X 10.4.x
'(value of attributes contains 0)': '(value of attribute "AXDisclosureLevel" is 0)' sometimes works in Tiger, sometimes not.
The only possible instances of 0 amongst the attributes are the disclosure level of a sheet row and the index of the first row, which represents a sheet anyway.
Another possibility is '(value of attribute -1 is 0)', which makes me uneasy. *)
                    set targetSheetRow to first row where ((value of attributes contains 0) and (value of first static text is theSheet))
                else (* macOS X 10.5.x or higher *)
                    set targetSheetRow to first row where ((value of attribute "AXDisclosureLevel" is 0) and ((groups is {}) and (value of first static text is theSheet)) or (value of first group's first static text is theSheet))
                end if -- maybe…
                (*
Handler modified to accomodate sheets requiring a lot of time to get the focus
*)
                tell targetSheetRow to set value of attribute "AXSelected" to true
                set cnt to 0
                repeat (*
Must way that Numbers becomes ready to receive the value *)
                    try
                        tell targetSheetRow to set value of attribute "AXDisclosing" to true
                        exit repeat
                    on error
                        set cnt to cnt + 1
                        delay 0.5 -- half a second
                    end try
                end repeat
            end tell -- outline…
        end tell -- "System Events"…
        --+++++
        -- set log_report to log_report & "point 3, cnt = " & cnt & return & (current date) & return
        --+++++
        tell application "Numbers" to tell document theDoc to tell sheet theSheet to tell table 1
            with timeout of 20 * 60 seconds (*
WITH this setting, the script will be able to wait 20 minutes for the asked value.
I hope that the document will not be so huge that this delay prove to be too short. *)
                value of cell "A1"
            end timeout
        end tell -- "Numbers"…
        --+++++
        -- set log_report to log_report & "point 4 : " & (current date) & return
        --+++++
        tell application "System Events" to tell application process "Numbers" (*
Do the trick one more time to be sure that the sheet is open *)
            tell targetSheetRow to set value of attribute "AXDisclosing" to true
        end tell -- "System Events"…
        --+++++
        -- return log_report & "point 5 : " & (current date) & return
        --+++++
        (*
End of the modified piece of code
*)
    end script
    run myScript
end selectsheet

#1


OK. My first answer was accepted and could not be deleted, but was inadequate, so I have decided to edit it and add some code which really does solve the problem!

好。我的第一个答案被接受了,无法删除,但是不够,所以我决定编辑它并添加一些真正解决问题的代码!

This code comes via Yvan Koenig, who credits Nigel Garvey. Both are active on the applescript-users list, which is excellent, by the way, not least because of the activity of these two gentlemen, and so many other great AppleScripters.

此代码来自Yvan Koenig,后者称Nigel Garvey。两者都在applescript-users列表中是活跃的,顺便说一下,这非常好,尤其是因为这两位绅士的活动以及许多其他优秀的AppleScripters。

It relies on GUI scripting (which is always a horrible thing to have to fall back on, but it's what we've got).

它依赖于GUI脚本(这一直是一件可怕的事情,但它是我们所拥有的)。

The call to my activateGUIscripting() may cause a prompt for an admin password to appear. If you absolutely know that you have GUI scripting enabled (System Prefs->Universal Access->Enable Access for Assistive Devices) - then you can omit this line.

对activateGUIscripting()的调用可能会导致出现管理员密码的提示。如果您完全知道已启用GUI脚本(系统Prefs->通用访问 - >启用辅助设备访问) - 那么您可以省略此行。

The next two lines are just example calls, so you need a sheet called "Sheet 1" for these example calls to work.

接下来的两行只是示例调用,因此您需要一个名为“Sheet 1”的工作表才能使这些示例调用生效。

This will allow you to create a table in any sheet in any document, regardless of what is selected or frontmost.

这将允许您在任何文档的任何工作表中创建表,无论选择什么或最前面。

--EXAMPLE CALLS
my activateGUIscripting()
my selectsheet(1, "Sheet 1")
my createNewTable(1, "Sheet 1", "myNewTable", 69, 13)

--NUMBERS UTILS
on createNewTable(dName, sName, newTable, nb_rows, nb_columns)
    tell application "Numbers" to tell document dName to tell sheet sName
        make new table with properties {name:newTable, row count:nb_rows, column count:nb_columns}
    end tell
end createNewTable

--=====
on activateGUIscripting()
    (* to be sure than GUI scripting will be active *)
    tell application "System Events"
        if not (UI elements enabled) then set (UI elements enabled) to true
    end tell
end activateGUIscripting
--=====
(*
==== Uses GUIscripting ====
 *)
on selectsheet(theDoc, theSheet)
    script myScript
        property listeObjets : {}
        local maybe, targetSheetRow
        --+++++
        -- set log_report to "point 2 : " & (current date) & return
        --+++++
        tell application "Numbers"
            activate
            set theDoc to name of document theDoc (* useful if the passed value is a number *)
            tell document theDoc to set my listeObjets to name of sheets
        end tell -- "Numbers"…

        set maybe to theSheet is in my listeObjets
        set my listeObjets to {} -- So it will not be saved in the script *)
        if not maybe then
            error "The sheet “" & theSheet & "” is unavailable in the spreadsheet “" & theDoc & "” !"
        end if -- not maybe

        set maybe to 5 > (system attribute "sys2")
        tell application "System Events" to tell application process "Numbers"
            tell outline 1 of scroll area 1 of splitter group 1 of splitter group 1 of window theDoc
                if maybe then (* macOS X 10.4.x
'(value of attributes contains 0)': '(value of attribute "AXDisclosureLevel" is 0)' sometimes works in Tiger, sometimes not.
The only possible instances of 0 amongst the attributes are the disclosure level of a sheet row and the index of the first row, which represents a sheet anyway.
Another possibility is '(value of attribute -1 is 0)', which makes me uneasy. *)
                    set targetSheetRow to first row where ((value of attributes contains 0) and (value of first static text is theSheet))
                else (* macOS X 10.5.x or higher *)
                    set targetSheetRow to first row where ((value of attribute "AXDisclosureLevel" is 0) and ((groups is {}) and (value of first static text is theSheet)) or (value of first group's first static text is theSheet))
                end if -- maybe…
                (*
Handler modified to accomodate sheets requiring a lot of time to get the focus
*)
                tell targetSheetRow to set value of attribute "AXSelected" to true
                set cnt to 0
                repeat (*
Must way that Numbers becomes ready to receive the value *)
                    try
                        tell targetSheetRow to set value of attribute "AXDisclosing" to true
                        exit repeat
                    on error
                        set cnt to cnt + 1
                        delay 0.5 -- half a second
                    end try
                end repeat
            end tell -- outline…
        end tell -- "System Events"…
        --+++++
        -- set log_report to log_report & "point 3, cnt = " & cnt & return & (current date) & return
        --+++++
        tell application "Numbers" to tell document theDoc to tell sheet theSheet to tell table 1
            with timeout of 20 * 60 seconds (*
WITH this setting, the script will be able to wait 20 minutes for the asked value.
I hope that the document will not be so huge that this delay prove to be too short. *)
                value of cell "A1"
            end timeout
        end tell -- "Numbers"…
        --+++++
        -- set log_report to log_report & "point 4 : " & (current date) & return
        --+++++
        tell application "System Events" to tell application process "Numbers" (*
Do the trick one more time to be sure that the sheet is open *)
            tell targetSheetRow to set value of attribute "AXDisclosing" to true
        end tell -- "System Events"…
        --+++++
        -- return log_report & "point 5 : " & (current date) & return
        --+++++
        (*
End of the modified piece of code
*)
    end script
    run myScript
end selectsheet

#2