Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

ecchi

macrumors newbie
Original poster
Aug 21, 2008
7
0
Ok, not sure if this correct area - its an AppleScript
Pretty simple. It looks at a sampleSpreadsheet (Numbers), checks the values of Cells E2 and B2. Cell E2 is a "pop-up menu" data format (2 values right now: dropDownValue1 and dropDownValue2). B2 cell is text data format. If E2 is dropDownValue1 (aka true), then open the sample Pages document, perform a mail-merge, then rename that new merged Pages document. This AppleScript does do that, but it does it using UI scripting and System Events to type out the filename instead. Very hackie. I hate it. But every time I try to do "set name of document 1 to myFileName" I get the following error:

Code:
error "Pages got an error: Can’t set name of document to \"dropDownValue1-Some Thing\"." number -10006 from name of document

I attempted to make a sanitize filename function, but I still get the same error if I call on that. I included it below, in case its still necessary.

Related matter, I do this same hack for the Mail-Merge, but only because I couldn't find any documentation on calling that with AppleScript, so I'm ok if that stays as a UI script hack (just prefer it not to have any hacks). Relative paths is so that is transportable among myself and another user, and not have to make user-specific edits to the AppleScript's paths every time I update the script.


AppleScript:
tell application "Finder"
    set sampleSpreadsheet to (POSIX path of (path to home folder)) & "Desktop/Sample.numbers" as POSIX file
    set sampleDocument to (POSIX path of (path to home folder)) & "Desktop/Sample.pages" as POSIX file
end tell

tell application "Numbers"
    open POSIX path of sampleSpreadsheet as POSIX file
    tell document 1
        tell sheet "Data"
            tell table "Generator"
                set e2Value to value of cell "E2"
                set b2Value to value of cell "B2"
                if e2Value is "dropDownValue1" then
                    tell application "Pages"
                        set myFileName to e2Value & "-" & b2Value
                        activate
                        open sampleDocument
                        my clickMenuItem("File", "Mail Merge...")
                        delay 5
                        my clickRename("File", "Rename...")
                        delay 0.5
                        tell application "System Events"
                            keystroke myFileName
                            key code 36
                        end tell
                    end tell
                end if
                if e2Value is "dropDownValue2" then
                    tell application "Safari"
                        activate
                    end tell
                end if
            end tell
        end tell
    end tell
end tell



on clickMenuItem(menuTitle, menuItem)
    delay 0.8
    tell application "System Events"
        tell process "SystemUIServer"
            tell application "Pages" to tell document 1
                -- Click the “File” menu.
                delay 0.936015
                set timeoutSeconds to 2.0
                set uiScript to "click menu bar item \"File\" of menu bar 1 of application process \"Pages\""
                my doWithTimeout(uiScript, timeoutSeconds)
                -- Mail Merge…
                delay 0.719995
                set timeoutSeconds to 2.0
                set uiScript to "click menu item 22 of menu 1 of menu bar item \"File\" of menu bar 1 of application process \"Pages\""
                my doWithTimeout(uiScript, timeoutSeconds)
                -- Click the “Merge” button.
                delay 2.287998
                set timeoutSeconds to 2.0
                set uiScript to "click UI Element \"Merge\" of sheet 1 of window 1 of application process \"Pages\""
                my doWithTimeout(uiScript, timeoutSeconds)
            end tell
        end tell
    end tell
end clickMenuItem

on clickRename(menuTitle, menuItem)
    delay 0.8
    tell application "System Events"
        tell process "SystemUIServer"
            tell application "Pages" to tell document 1
                -- Click the “File” menu.
                delay 0.936015
                set timeoutSeconds to 2.0
                set uiScript to "click menu bar item \"File\" of menu bar 1 of application process \"Pages\""
                my doWithTimeout(uiScript, timeoutSeconds)
                -- Click Rename…
                delay 0.719995
                set timeoutSeconds to 2.0
                set uiScript to "click menu item 11 of menu 1 of menu bar item \"File\" of menu bar 1 of application process \"Pages\""
                my doWithTimeout(uiScript, timeoutSeconds)
            end tell
        end tell
    end tell
end clickRename


on doWithTimeout(uiScript, timeoutSeconds)
    set endDate to (current date) + timeoutSeconds
    repeat
        try
            run script "tell application \"System Events\"
" & uiScript & "
end tell"
            exit repeat
        on error errorMessage
            if ((current date) > endDate) then
                error "Can not " & uiScript
            end if
        end try
    end repeat
end doWithTimeout

on sanitizeFileName(fileName)
    set validChars to "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-_ "
    set sanitizedFileName to ""
    
    repeat with i from 1 to length of fileName
        set thisChar to character i of fileName
        
        if thisChar is in validChars then
            set sanitizedFileName to sanitizedFileName & thisChar
        else if thisChar is "/" then
            set sanitizedFileName to sanitizedFileName & "_"
        end if
    end repeat
    
    return sanitizedFileName
end sanitizeFileName
 
The only things available are what has been provided. Check out Number’s scripting dictionary - a document’s name property only has read access.
 
If a document's name property is read-only, as @Red Menace states, then you can change this part of your algorithm.
... If E2 is dropDownValue1 (aka true), then open the sample Pages document, perform a mail-merge, then rename that new merged Pages document. ...

This is your sequence:
1. open
2. mail-merge
3. rename

Try this sequence:
1. Make a duplicate of template document, e.g. with Finder or with shell cmds.
2. Give the duplicate the desired name.
3. Mail-merge to the newly renamed duplicate document.

This is basically how stationery documents work. When a document is marked as stationery, opening it forces you to make a duplicate. You then edit the duplicate, not the original stationery.
 
Yeah...Sorry, it appears that document arguments in Pages is Read-only from AppleScript? Despite all my googling kept advising to "set name of document 1", but apparently this R/O is expected behaviour since Mojave(?)

Chown33, I can't use your suggestion because Apple's "Mail Merge" doesn't merge-into the existing document - rather it spawns new document on merge - no setting I am aware to prevent that behaviour. So your suggestion of duplicating the file with Finder using AS and renaming won't work for me.
I did debate about writing a hackie "merge" with Find&Replace using AS, but seeing as I don't see any Find or Replace functions in Pages Dictionary I'm reluctant to go further down that rabbit hole.

Thanks for the ideas, but I think I've hit the wall, without spending enormous amounts of effort or re-making this using Word (Word definitely has the functions in its AS dictionary, but trying to avoid Word if possible, mainly because most of the math functions in it's tables is more limiting, IIRC MS wants you to use Excel to embed "complicated" formulas instead of its native Tables, and that's just unnecessary for the kind of docs that I'm spitting out).

I guess I'll stick with my current solution, it's hackie, but it works exactly as I need it to, so I should just be happy.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.