Saving a numbers document automatically

Setup: A Keyboard Maestro macro (hotkey-triggered) finalizes a patient invoice that's open in Numbers. It needs to: (1) save/duplicate the currently-open Numbers document under a new timestamped filename into a folder, and (2) file a copy of that resulting file into a specific group in DEVONthink.

Current implementation: One "Execute AppleScript" action that does all of it — gets the front document's path, builds a new filename with a date timestamp, tells Numbers to "save ... in file" the new path, then tells DEVONthink (via tell application id "DNtp") to import that file into a group by UUID.

2 bill patient.kmmacros (3.5 KB)

The question: Is it better to break this into native KM actions (e.g., "Duplicate File," "Move File," KM's built-in date tokens for the filename) instead of one big script, since the forum generally advises against doing everything in script? Specifically:

  • Is there a native KM way to do a Numbers "Save As" to a new name/location while the doc is open, or does that step require AppleScript (or System Events/Numbers' own dictionary) because Finder-level duplicate/move only works on files already saved to disk, not a live open document?

  • Is there a native KM (or DEVONthink) action for importing/filing a file into a DEVONthink group, or is AppleScript unavoidable for that step since DEVONthink's automation is exposed only through its scripting dictionary?

That's the crux: which pieces can genuinely move to native actions, and which ones (saving an open document, talking to DEVONthink) realistically still need a script regardless of best practice.

Here's my take on it:

You have a solution that you spent time creating, and which seems to work well for you. Unless there's something about it that doesn't actually work well, I wouldn't spend any time on recreating it. At best, you'll wind up with a macro that does exactly what it does now, but will have cost you additional time to create, just to be able to say you're using native Keyboard Maestro actions.

I know I could rewrite many of my macros to be more efficient. But they work as is, and the extra 10 milliseconds I save each run would have a very long payback for the time it would take to gain that speed :).

-rob.

2 Likes

Not really -- more that you shouldn't use an AppleScript when you can do the same with a few KM Actions. That's because it takes time and resources to instantiate the AS environment -- why replace a routine of a dozen KM Actions that takes ~12ms to execute with an AS that takes ~40ms just to ready, never mind run.

But AppleScripts run "as fast as they can", compared to KM's "one Action per millisecond", so the more you do in your AS the less relevant the instantiation time. And if you are already using AS -- your DEVONthink import -- it makes sense to everything in one script with a single instantiation.

Robustness and speed are other reasons for using AS to do your "Save As..." step. You can do it with KM Actions -- it's been covered here many times, and here's a recent thread about it -- but the basic pattern is

  1. "Select a Menu Item" to "Save As..."
  2. Wait for the dialog to be ready for input
  3. "Insert by typing/pasting" the new file name
  4. "Simulate a keystroke" ⇧⌘G to open the "Go to location" dialog
  5. Wait for the dialog to be ready for input
  6. "Insert by pasting" the path you want to save at
  7. Click the "OK" button
  8. Click the "Save" button

The good thing about learning this pattern is that that it works (with maybe minor modifications) for any app that uses the standard OS "Save" dialog -- AppleScript solutions are generally app-specific, assuming the app is scriptable in the first place.

Similar would be true for importing into DEVONthink -- you automate what you'd do, manually, in the UI.

But given that you've got a) two AppleScriptable applications, and b) an AppleScript that works -- I'd leave everything as it is!

If I was to change things -- I'd change the approach taken. Why open the file in Numbers and immediately "Save As..."? I'd duplicate the template file, named appropriately, then open that duplicate. I haven't got DEVON to test against, but something like:

Or use File > Save as template… (more, if needed: Manage Numbers templates on Mac) and then select that template whenever needed.

I'd be a fan of this if you could include something like #today# in the template file name that evaluated on first open, and include a default save path -- AFAIK that's not possible so you'd still have to automate the "Save/Save As..." dialog or use AS.

The joy of the duplication method is that you can do all that nasty file name/path stuff with easy KM Actions.

Yes, quite so, but using a “proper” template file (rather than a file that is being used as a template) means that the original wouldn’t ever be accidentally overwritten*, and that it could be conveniently accessed from the Template Chooser**.

* But neither would a file that has been locked.
** There are alternative ways to organise and summon documents, of course!

You could combine both -- save as a Template for "manual" use, duplicate that template for "automated".

Numbers's user templates are stored in ~/Library/Containers/com.apple.iWork.Numbers/Data/Library/Application Support/User Templates, named with an UUID and a nmbtemplate extension -- AFAIK you can duplicate and rename to Invoice_2026-06-17.numbers and you don't miss anything.

If you've got a lot of templates, working out which is which might be a problem.A good start would be to run

set theList to ""
tell application "Numbers"
	repeat with eachItem in (get every template whose id contains "CloudKit")
		set theList to name of eachItem & " -- " & id of eachItem & linefeed
	end repeat
end tell
return theList

...to get a name -- UUID list. You could take it further and create a KM "Prompt with List" template picker!

Getting your way of thinking is important to me. A general pattern will help me in the future. I will try it. Actually, the script I have does not work. I want to avoid scripts but AI only knows scripts if you do not have any better ideas.

Thank you,
Ellen Madono

It is only my way of thinking -- that doesn't mean it's right for you or what you want to do :wink:

Apologies -- I thought this was a working AS you were considering converting. This should fix your file-referencing problems in Numbers. I don't have DEVONthink so I can't test that bit, but see how you get on.

tell application "Numbers Creator Studio"
	set theDoc to front document
	set oldPath to POSIX path of (get file of theDoc)
	set theFolder to do shell script "dirname " & quoted form of oldPath
	set newPath to theFolder & "/Invoice_" & (do shell script "date +%Y-%m-%d_%H%M") & ".numbers"
	set newPath to (newPath as POSIX file)
	save theDoc in newPath
end tell

tell application id "DNtp"
	set theGroup to get record with uuid "BF185EF6-2C1D-4284-870E-4911C147EC0D"
	import newPath to theGroup
end tell