Search code examples
applescriptapplescript-numbers

Setting a variable in AppleScript based on a list in a Numbers sheet


AppleScript beginner here. Searching high and low hasn't led me to the answer yet.

I'm using AppleScript to help run youth wrestling tournaments. Each division (based on age) is broken down into weight classes. For example: Novice 80 or Cadet 105.

Once a certain group of kids is put into a certain division/weight class, those kids get added to a new sheet that contains their bracket (think March Madness bracket but a small number of kids wrestling instead of playing basketball).

I've figured out how to get a group into a new sheet where they populate the bracket, but when this new sheet is created, I don't know how to make AppleScript change the name of the sheet to the correct division/weight class. I'm sure it has something to do with creating variables based on a list of the divisions/weight classes (that I have), but I can't figure out how to do it. Here's the relevant portion of the code:

tell document 1
        set active sheet to the last sheet
        set thisSheet to make new sheet
        set the name of thisSheet to "[Division variable – Weight class variable]"
        tell thisSheet
            delete every table
        end tell

Any ideas on how to make AppleScript name the sheet like I want?


Solution

  • To give you a small example that you're able to visualize what you're going after, heres a small snippet. I think its self explanatory, iterate through a list of titles, then apply the names to the sheets.

    set divisionNames to {"Novice", "Cadet"} -- How You Grab These Values Matters
    set weightClasses to {"80", "105"} -- These Values Too
    
    tell application "Numbers"
        activate
    set thisDocument to make new document
    tell thisDocument
        repeat with i from 1 to count of divisionNames
            make new sheet with properties {name:item i of divisionNames & space & item i of weightClasses}
        end repeat
    end tell
    end tell
    

    Alternately, if you're pulling the values from a list as a whole then you could

    set sheetTitles to {"Novice 80", "Cadet 105"}
    
    tell application "Numbers"
    activate
    set thisDocument to make new document
    tell thisDocument
        repeat with division in sheetTitles
            make new sheet with properties {name:division}
        end repeat
    end tell
    end tell
    

    EDIT: In the spirit of helping a low to no budget school/organization.. here's another example answering the second question issued in comments. Again without knowing the structure of your data its hard to give you an exact answer on your specific case. Additionally, here's a link to a site they may help further the advancement on your project. https://iworkautomation.com/numbers/index.html

    (*
    set sampleKids to {"John Doe", "Jane Doe", "Johnny Foe", "Janie Foe", "Tommy Joe", "Tammy Joe"}
    set sampleDivisions to {"Novice-80", "Novice-85", "Cadet-105", "Cadet-110", "Novice-80", "Cadet-105"}
    
    tell application "Numbers"
    activate
    set thisDoc to make new document with properties {name:"Wrestling Sample"}
    tell thisDoc
        set the name of sheet 1 to "Sign In Sheet"
        tell active sheet
            delete every table
            set newTable to make new table with properties {row count:(count of sampleKids) + 1, column count:2, name:"Sign In Sheet"}
            tell newTable
                set value of cell 1 of column "A" to "Name"
                set value of cell 1 of column "B" to "Division"
                set x to 2
                repeat with eachName in sampleKids
                    set value of cell x of column "A" to eachName
                    set x to (x + 1)
                end repeat
                set x to 2
                repeat with eachDivision in sampleDivisions
                    set value of cell x of column "B" to eachDivision
                    set x to (x + 1)
                end repeat
            end tell
        end tell
    end tell
    end tell
    *)
    
    --********** IGNORE ABOVE THIS LINE IT'S ONLY BUILDING A SAMPLE TABLE **********--
    --********** SAVE ABOVE TO ANOTHER SCRIPT FOR TESTING WITH NEW TABLE **********--
    
    (*
    ERROR HANDLING ISN'T PRESENT - AN EMPTY CELL IN FIRST COLUMN OR CHOSEN COLUMN WILL THROW AN 
    ERROR SINCE THEY ARE THE IMPORTANT PIECES OF DATA FOR GRABBING LISTS - SAVE SCRIPT
    TO NUMBERS SCRIPT FOLDER OF YOUR CHOICE - ENTER ALL INFO ON FIRST TABLE OF FIRST SHEET OF 
    DOCUMENT THEN RUN SCRIPT - SCRIPT ACCEPTS ANY AMOUNT OF ROWS OR COLUMNS
    *)
    
    tell application "Numbers"
    activate
    -- Display A Simple Reminder That You're About To Lose Some Existing Data
    display dialog "This Script Will Delete All Sheets Except The First Sheet Of This Document Before It Proceeds To Make New Sheets & Tables Based On The First Table Of The First Sheet." buttons {"Cancel", "Start"} default button 2 with icon 1
    tell document 1
        -- Get A List of the Sheet Names
        set sheetNames to name of sheets
        -- Start With A Fresh Slate, No Old Sheets
        delete (every sheet whose name is not item 1 of sheetNames)
        tell sheet 1
            -- Grab and Set Future Header Values
            set columnHeaders to value of cell of row 1 in table 1
            -- Display A List Of Possible Choices To Create New Sheets With From The List We Make Above
            set chosenColumn to choose from list columnHeaders with prompt "Which Column Do You Want To Use For New Sheets?" default items item 1 of columnHeaders
            set chosenColumn to chosenColumn as text
            tell table 1
                -- Remove All Empty Rows to Help Prevent Error In Script
                set {row_count, col_count} to {count rows, count columns}
                set blank_row to {}
                repeat with x from 1 to col_count
                    set blank_row to blank_row & missing value
                end repeat
                set x to 1
                -- Delete Empty Rows In Reverse, It's Logical
                repeat with y from row_count to 1 by -1
                    set row_values to value of cells of row y
                    if row_values = blank_row then delete row y
                end repeat
    
                -- Grab A List of All Divisions for Future Use Depending on Choice From Prompt, excluding the First Row Which Is A Header. If You Selected The First Column, We Have to Handle That Differently
                if chosenColumn is item 1 of columnHeaders then
                    set theDivisions to the value of every cell of column "A" whose value is not chosenColumn
                else
                    set theDivisions to the value of every cell of column named chosenColumn whose value is not chosenColumn
                end if
    
            end tell
        end tell
        -- Start the New "Sheet Making" Loop
        repeat with division in theDivisions
            -- Make An Empty Blank List At the Start of Every Loop
            set matchingDivisions to {}
            tell table 1 of sheet 1
    
                -- Get All Rows Matching the Current Division of the Loop We Are On, to Make New Tables With Later
                repeat with x from 1 to count of cells
                    if the value of cell x is division then
                        -- Put All Data About the Rows We Gathered Above Into the Empty List We Made 
                        set the end of matchingDivisions to value of cells of row of cell x
                    end if
                end repeat
                -- Reset x, Because I'm Not Creative and Want to Use It Later
                set x to 1
            end tell
            -- If The Sheet Of the Division We Are On, of the Loop, Doesn't Exist, Make It
            if not (exists sheet division) then
                make new sheet with properties {name:division}
                tell sheet division
                    -- Start With A Fresh Slate On This New Sheet
                    delete every table
                    -- Make the Table With All Relevant Parameters 
                    set currentDivisionTable to make new table with properties ¬
                        {row count:((count of matchingDivisions) + 1), column count:count of item 1 of matchingDivisions, name:division}
                    tell currentDivisionTable
                        set x to 1
                        -- Set The Header Values from A List We Created Earlier
                        repeat with theHeader in columnHeaders
                            set the value of cell x to theHeader
                            set x to (x + 1)
                        end repeat
                        -- Reset x Again, I'm Lazy
                        set x to 1
                        -- Set Starting Point to Start Filling The Table, Compensate For Our Headers
                        set rowIndex to 1
                        set columnIndex to 0
                        -- Start Filling The Table With Data, Which Comes From The List Earlier
                        repeat with x from 1 to count of the matchingDivisions
                            set rowData to item x of the matchingDivisions
                            tell row (rowIndex + x)
                                repeat with i from 1 to the count of rowData
                                    tell cell (columnIndex + i)
                                        set value to item i of rowData
                                    end tell
                                end repeat
                            end tell
                        end repeat
                    end tell
                end tell
            end if
        end repeat
        -- Return To the First Sheet
        set the active sheet to the first sheet
        -- Display Notification That The Tables Are Done Being Made -- OPTIONAL
        display notification "Processing is complete." with title "Numbers Table Converter" subtitle "All Tables Have Been Made." sound name "Hero"
    end tell
    end tell