Applescript to paste into numbers

I want to be able to copy contents of clipboard into cell A1 of a certain table in numbers file. What applescript could I use to do this?

MacBook Pro

Posted on May 18, 2010 3:53 PM

Reply
16 replies

May 18, 2010 4:21 PM in response to Badunit

Gave this a try, but all it did was make numbers hang and had to force quit.

Maybe if I explain the whole picture. I have written a script to open an excel file, copy contents, with view to paste into Sheet 1, table data of file Live Capture.numbers

This need to be a paste, as I want to redo this procedure each minute, as another piece of software updates the Excel file.
Hope you can suggest something for this, I have got as far as opening, copying excel, opening numbers file, just need to be able to paste in select cell of table

May 19, 2010 1:37 AM in response to Barry

I was unable to get this error message.
It may due to the use of a clipboard enhancer.

The given scheme apply when we need to fill a single cell.
If the clipboard may contain the contents of several cells, it returns odd result : everything in a single cell.

Here is the scheme which I use.
It rely upon GUI scripting.

The focus must be on the targer table or at leat on the target sheet.

In this example, I put the focus on the table itself.

--

on run
my activateGUIscripting()
(*
do what you need
*)
set dName to 1 (* may be set by the beginning of the script *)
set sName to 1 (* may be set by the beginning of the script *)
set tName to 1 (* may be set by the beginning of the script *)
set rowNum to 3 (* may be set by the beginning of the script *)
set colNum to 2 (* may be set by the beginning of the script *)
(*
Put focus on the target table
*)
my selectTable(dName, sName, tName)
tell application "Numbers" to tell document dName to tell sheet sName to tell table tName
set selection range to range (name of cell rowNum of column colNum)
end tell
-- my raccourci("Numbers", "v", "c") (* Paste *)
my raccourci("Numbers", "v", "cas") (* Paste and Match Style *)
-- my selectMenu("Numbers", 4, 6) (* Paste *)
-- my selectMenu("Numbers", 4, 7) (* Paste and Match Style *)
-- my selectMenu("Numbers", 4, 8) (* Paste Values *)
(*
Do what you need
*)
end run
--=====
on parleAnglais()
local z
try
tell application "Numbers" to set z to localized string "Cancel"
on error
set z to "Cancel"
end try
return (z is not "Annuler")
end parleAnglais
--=====
on activateGUIscripting()
tell application "System Events"
if not (UI elements enabled) then set (UI elements enabled) to true (* to be sure than GUI scripting will be active *)
end tell
end activateGUIscripting
--=====
on selectTable(theDoc, theSheet, theTable)
local maybe, targetSheetRow, rowIndex, r
try
tell application "Numbers"
activate
set theDoc to name of document theDoc (* useful if the passed value is a number. Checks also that we passed the name of an open doc *)
end tell -- Numbers
on error
if my parleAnglais() then
error "The spreadsheet “" & theDoc & "” is not open !"
else
error "Le tableur « " & theDoc & " » n’est pas ouvert ! "
end if -- my parleAnglais
end try

try
tell application "Numbers" to tell document theDoc
set theSheet to name of sheet theSheet (* useful if the passed value is a number and check the availability of theSheet if it's a string *)
end tell -- Numbers
on error
if my parleAnglais() then
error "The sheet “" & theSheet & "” is unavailable in the spreadsheet “" & theDoc & "” !"
else
error "La feuille « " & theSheet & " » n’existe pas dans le tableur « " & theDoc & " » ! "
end if -- my parleAnglais
end try

try
tell application "Numbers" to tell document theDoc to tell sheet theSheet
set theTable to name of table theTable (* useful if the passed value is a number and check the availability of theSheet if it's a string *)
end tell -- Numbers
on error
if my parleAnglais() then
error "The table “" & theTable & "” is unavailable in the sheet “" & theSheet & "” of the spreadsheet “" & d & "” !"
else
error "La table « " & theTable & " » n’existe pas dans la feuille « " & theSheet & " » du tableur « " & d & " » ! "
end if -- my parleAnglais
end try

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
tell targetSheetRow to set {value of attribute "AXSelected", value of attribute "AXDisclosing"} to {true, true}

-- Get the sheet row's 0-based index + 2 for the following row's 1-based index.
set r to (value of attribute "AXIndex" of targetSheetRow) + 2

repeat until (value of first static text of row r is theTable)
set r to r + 1
end repeat
set value of attribute "AXSelected" of row r to true
end tell -- outline 1 …
end tell -- System Events

end selectTable
--=====
(*
my selectMenu("Pages",5, 12)
==== Uses GUIscripting ====
*)
on selectMenu(theApp, mt, mi)
tell application theApp
activate
tell application "System Events" to tell process theApp to tell menu bar 1 to tell menu bar item mt to tell menu 1 to click menu item mi
end tell -- application theApp
end selectMenu
--=====
(*
==== Uses GUIscripting ====
*)
(*
This handler may be used to 'type' text, invisible characters if the third parameter is an empty string.
It may be used to 'type' keyboard raccourcis if the third parameter describe the required modifier keys.
I changed its name « shortcut » to « raccourci » to get rid of a name conflict in Smile.
*)
on raccourci(a, t, d)
local k
tell application a to activate
tell application "System Events" to tell application process a
set frontmost to true
try
t * 1
if d is "" then
key code t
else if d is "c" then
key code t using {command down}
else if d is "a" then
key code t using {option down}
else if d is "k" then
key code t using {control down}
else if d is "s" then
key code t using {shift down}
else if d is in {"ac", "ca"} then
key code t using {command down, option down}
else if d is in {"as", "sa"} then
key code t using {shift down, option down}
else if d is in {"sc", "cs"} then
key code t using {command down, shift down}
else if d is in {"kc", "ck"} then
key code t using {command down, control down}
else if d is in {"ks", "sk"} then
key code t using {shift down, control down}
else if (d contains "c") and (d contains "s") and d contains "k" then
key code t using {command down, shift down, control down}
else if (d contains "c") and (d contains "s") and d contains "a" then
key code t using {command down, shift down, option down}
end if
on error
repeat with k in t
if d is "" then
keystroke (k as text)
else if d is "c" then
keystroke (k as text) using {command down}
else if d is "a" then
keystroke k using {option down}
else if d is "k" then
keystroke (k as text) using {control down}
else if d is "s" then
keystroke k using {shift down}
else if d is in {"ac", "ca"} then
keystroke (k as text) using {command down, option down}
else if d is in {"as", "sa"} then
keystroke (k as text) using {shift down, option down}
else if d is in {"sc", "cs"} then
keystroke (k as text) using {command down, shift down}
else if d is in {"kc", "ck"} then
keystroke (k as text) using {command down, control down}
else if d is in {"ks", "sk"} then
keystroke (k as text) using {shift down, control down}
else if (d contains "c") and (d contains "s") and d contains "k" then
keystroke (k as text) using {command down, shift down, control down}
else if (d contains "c") and (d contains "s") and d contains "a" then
keystroke (k as text) using {command down, shift down, option down}
end if
end repeat
end try
end tell
end raccourci
--=====
--


You may choose between five instruction given what you really want to achieve.

- two ways to apply a simple Paste
- two ways to apply Paste and Match Style
- one way to apply Paste Values
Of course, if you linked a shortcut to Paste Values, you may use it but the script will fail if you try to use it on an other machine.

From my point of view, using the handle raccourci is better for Paste or Paste And Match Style because the shortcuts are standard ones and will not change (if you don't change them by yourself ).
Triggering the menu item is the only soluce when you want to paste values.

When the datas are grabbed from Excel, there is no need to use Paste Values as the formulas aren't passed.

If the datas are grabbed in Excel by the script, using the clipboard isn't necessarily the best soluce.

This skeleton may be better :

set theVal to value of sourceCellInExcelTable

set value of cell targetCellInNumbersTable to theVal

Have fun.

Yvan KOENIG (VALLAURIS, France) mercredi 19 mai 2010 10:36:55

May 19, 2010 5:10 AM in response to KOENIG Yvan

Wow this goes way over my head!!! LOL. I have only dabbled in applescripts for a few things.

I can't seem to get any of the proposed solutions to work. This is what I have got so far ...

set importFile to "Users:lholmes:Desktop:test.xls"
set liveFile to "Users:lholmes:Desktop:Live.numbers"

tell application "Microsoft Excel"
open importFile
copy range (range "a1:M500" of sheet "Sheet1.xls" of workbook importFile)
end tell

tell application "Numbers"
activate
open liveFile
tell liveFile to tell sheet 1 to tell table 1
set value of cell "a1" to (the clipboard as text)
end tell

end tell

Is this along the right lines. I would like to understand exactly how this works, if I need to fix later on.

Not sure if this makes any difference, my reading around seems to imply it may, I am using 10.6.3 Numbers 09 and can either use Excel 04 or 08.
I just want to be able to copy the range from the excel and paste into table in numbers. The copy part of the script seems to work, as when I select appropriate area in numbers manually it will paste exactly how I want it.
Not sure where I am going wrong, but its really frustrating me now.
Any help would be great.
Thanks

May 19, 2010 5:43 AM in response to Tech Dem

Part of the problem with using the minimal script I provided is that you are copying a range of your Excel spreadsheet to the clipboard but the script then tries to put it all into one cell. That was a miscommunication between us on the meaning of "copy the contents of the clipboard into cell A1".

Yvan's script does an actual "command V" paste like what you would do manually. Yvan's scripts are more involved than most because he has generic handlers/routines that he has designed for multiple purposes and he typically has error handlers.

May 19, 2010 8:05 AM in response to Tech Dem

Here is a running version of what you wanted.

--

on run
(*
Activate GUI scripting which is required to trigger the Paste menu
*)
my activateGUIscripting()
(*
Ask "Standard Additions" to give the true path to the Desktop.
*)
set p2d to path to desktop as text
(*
Build the source and target pathnames
*)
set importFile to p2d & "Users:lholmes:Desktop:test.xls"
set liveName to "Live.numbers"
set liveFile to p2d & liveName
(*
Here is an example of complete pathname.
Yours where wrong.
You used UNIX path replacing the slashs by colons.
The volume name was missing.
set liveFile to "Macintosh HD:Users:yvan_koenig:Desktop:Live.numbers" *)
(*
Check that the files which we plan to use are available.
*)
tell application "System Events"
set maybe1 to exists disk item importFile
set maybe2 to exists disk item liveFile
end tell -- Numbers
set errMsg to ""
if maybe1 is false then set errMsg to errMsg & "The file “" & importFile & "” is unavailable !"
if maybe2 is false then set errMsg to errMsg & "The file “" & liveFile & "” is unavailable !"
if errMsg is not "" then error errMsg

(*
I disable the Excel code because M…Soft products are not allowed to enter my machines
*)
(*
tell application "Microsoft Excel"
open importFile
copy range (range "a1:M500" of sheet "Sheet1.xls" of workbook importFile)
end tell
*)

tell application "Numbers"
activate
open liveFile
(*
Wait for a really open document
*)
repeat until exists window liveName
delay 0.2
end repeat
(*
Define the first cell of the range in which we will paste.
I choose B2 because the default tables have an header row and an header column.
It's easier to remove them than to change them in standard row/column.
*)
tell document liveName to tell sheet 1 to tell table 1 to set selection range to range "B2"
end tell -- Numbers
(*
This time, I insert only the scheme triggering a menu item.
If like me you prefer triggering a shortcut,
grab the instruction and the handler from my late script.
*)
--my selectMenu("Numbers", 4, 6) -- Paste
my selectMenu("Numbers", 4, 7) -- Paste Matching Style
--my selectMenu("Numbers", 4, 8) -- Paste Values
end run
--=====
on activateGUIscripting()
tell application "System Events"
if not (UI elements enabled) then set (UI elements enabled) to true (* to be sure than GUI scripting will be active *)
end tell
end activateGUIscripting
--=====
(*
Handler triggering the menu item mi of the menu mt of the application theApp.
*)
on selectMenu(theApp, mt, mi)
tell application theApp
activate
tell application "System Events" to tell process theApp to tell menu bar 1 to tell menu bar item mt to tell menu 1 to click menu item mi
end tell -- application theApp
end selectMenu
--=====
--


I'm always wondering when I read :
Is this along the right lines. I would like to understand exactly how this works, if I need to fix later on.


Are you understanding what is doing Numbers when you use it ?

As far as I know, I never destroyed an user's system 😉

Yvan KOENIG (VALLAURIS, France) mercredi 19 mai 2010 17:01:15

May 19, 2010 8:38 AM in response to KOENIG Yvan

Thanks for the assistance Yvan.
OK I think I understand how this script works now. Except it is stalling here
on run
(*
Activate GUI scripting which is required to trigger the Paste menu
*)
my activateGUIscripting()
(*
Ask "Standard Additions" to give the true path to the Desktop.
*)
set p2d to path to desktop as text
(*
Build the source and target pathnames
*)
set importFile to p2d & "Capture Edit List.xls"
set liveName to "Live Capture.numbers"
set liveFile to p2d & liveName
(*
Here is an example of complete pathname.
Yours where wrong.
You used UNIX path replacing the slashs by colons.
The volume name was missing.
set liveFile to "Macintosh HD:Users:yvan_koenig:Desktop:Live.numbers" *)
(*
Check that the files which we plan to use are available.
*)
tell application "System Events"
set maybe1 to exists disk item importFile
set maybe2 to exists disk item liveFile
end tell -- Numbers
set errMsg to ""
if maybe1 is false then set errMsg to errMsg & "The file “" & importFile & "” is unavailable !"
if maybe2 is false then set errMsg to errMsg & "The file “" & liveFile & "” is unavailable !"
if errMsg is not "" then error errMsg

(* need to see if can write a dialog box to highlight no file, change route of Capture Edit List in SportsCode Preferences Edit List. Check that it is enabled and route to Desktop is selected*)

tell application "Microsoft Excel"
open importFile
copy range (range "a1:M500" of sheet "Capture Edit List.xls" of workbook importFile)
end tell


tell application "Numbers"
activate
open liveFile
(*
Wait for a really open document
*)
repeat until exists window liveName
delay 0.2
end repeat

gets this far then continually loops from with false in identifying the file
Numbers has already opened up and is ready to be pasted. But it wont get past this point.
Any idea, all I did was paste into script editor and change the path to the files.
Thanks very much for you assistance with this, very much appreciated.

May 19, 2010 9:01 AM in response to Tech Dem

I tried removing the check for existing numbers file and get the following error message

error "Numbers got an error: Can’t set range \"B1\" of table 1 of sheet 1 of document \"Live Capture.numbers\" to range \"B1\" of table 1 of sheet 1 of document \"Live Capture.numbers\"." number -10006 from range "B1" of table 1 of sheet 1 of document "Live Capture.numbers"

Not sure why this happened as Table 1 does exist in Sheet 1 and has lots of empty cells, its totally empty through to D9...
Now I'm stumped again...

May 19, 2010 10:00 AM in response to Tech Dem

I was able to reproduce the described behaviour.
The document contained one sheet and the first table in the sheet had a single column so, for sure, it was unable to paste in cell B2.

As you wrote about cell D6, I assume that there is at least one table with several columns.
May you check if there is an other table embedding a single columns ?

Yvan KOENIG (VALLAURIS, France) mercredi 19 mai 2010 18:59:54

May 19, 2010 11:42 AM in response to KOENIG Yvan

Looking at the screenshots gives the responce which was in front of you.

(1) I must say that I don't like liers !

In the thread you wrote :

Not sure why this happened as Table 1 does exist in Sheet 1 and *_has lots of empty cells, its totally empty through to D9..._*


But your table contains *_a single cell !_*

(2) if you open your eyes as I did, you may see that your document is not named
"Live Capture.numbers"
but
"Live Capture" .

If you have time to waste, I haven't.

Yvan KOENIG (VALLAURIS, France) mercredi 19 mai 2010 20:39:02

This thread has been closed by the system or the community team. You may vote for any posts you find helpful, or search the Community for additional answers.

Applescript to paste into numbers

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