2017-04-06 69 views
0

使用我的數字表腳本,我正在經歷一個極端情況(每個單元格3-4秒)掛在重複循環中,我認爲這可能是由於我使用了copy命令造成的,因爲據我所知,copy創建了一個新的值的引用,而不是像set命令那樣替換值。我不確定它是否使用了copy命令,我的Mac,或者循環在命令序列中的位置不當。我試過切換一些命令的順序,但是沒有幫助。類似copy循環的其他用途行爲不如此緩慢。我的問題是一個複合問題。我是否要求循環處理很多,是否放錯地方,我是否應該使用除copy之外的東西,還是僅僅是我的Mac? (內存似乎不足以導致掛起,在掛起期間仍然剩下1.5gb,除了Numbers和腳本運行外,沒有其他任何東西)總結起來,我該如何解決掛起問題?在重複循環中極端掛起

掛起開始在環路的部分低於

-- This is where the extreme hang begins 

repeat with x from 1 to (count rows) - 2 
    repeat with y from 1 to count monthNames 
     copy incrementDates(y) of me to {theDayIndex, theMonthIndex, theYear, theDateString, monthLengthInDays} 
     set monthStart to theDateString 
     set monthEnd to theMonthIndex & "/" & monthLengthInDays & "/" & theYear as text 
     set theFormula to "=SUMIFS(Amount,Category,A,Date, \">=" & monthStart & "\",Date, \"<=" & monthEnd & "\")" 
     set value of cell (y + 1) of row (x + 1) to theFormula 
    end repeat 
end repeat 

-- Extreme hang ends and script continues normally 

參考完整的劇本就在這裏,萬一它我的其他copy使用的配合問題。

set moneyInHeaders to {"Last Name", "First Name", "Receipt Number", "Payment", "Date", "Office", "City", "Referral Name"} 
set locationList to {"Location 1", "Location 2"} 
set the monthNames to {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"} 
set moneyOutHeaders to {"Expense", "Amount", "Date", "Category", "Item"} 
set categoryItems to {"Marketing", "Software", "Tools", "Utilities", "Other"} 
set thisYearName to (year of (current date)) as string 
set moneyInColor to {31354, 51657, 22615} 
set moneyOutColor to {59623, 20816, 14391} 

tell application "Numbers" 
if not (exists document 1) then make new document 
tell document 1 
    delete every sheet 
    set the name of sheet 1 to "Money In" 
    tell sheet 1 
     delete every table 
     set moneyInTable to make new table with properties {name:"Money In", position:{-7, 29}, width:788, column count:count moneyInHeaders, row count:14, footer row count:1, header column count:2} 
     tell moneyInTable 
      set locationCount to count locationList -- get count of locations 
      set properties of row 1 to {background color:{moneyInColor}} 
      my populateCells(moneyInTable, row 1, moneyInHeaders, false) -- fill header row values 
      set value of last cell of column named "Payment" to ("=SUM(C)") 
      my populateCells(moneyInTable, column named "Office", locationList, true) -- fill pop up menu values 
      my formatCells(moneyInTable, column named "Payment", currency) 
      my formatCells(moneyInTable, column named "Date", date and time) 
      my formatCells(moneyInTable, column named "Office", pop up menu) 
      delete (rows 2 through (locationCount + 1)) -- remove rows that contain values so the pop up column is empty 
      repeat locationCount times -- add the rows back to keep table size 
       add row below row 2 
      end repeat 
     end tell -- end telling moneyInTable 

     -- Set locked false for now 
     set totalsTable to make new table with properties {name:"Money In Totals", locked:false, position:{785, 29}, column count:2, row count:(count monthNames) + 2, header column count:1, header row count:1, footer row count:1} 
     tell totalsTable 
      set properties of row 1 to {background color:{moneyInColor}} 
      my populateCells(totalsTable, column "A", monthNames, true) 
      set value of last cell of column "A" to "Grand Total" 
      set value of cell "B1" to "Totals" 
      set value of last cell to ("=SUM(B)") 
      tell column "B" 
       repeat with x from 1 to count monthNames -- loop and increment dates for the SUMIFS formula 
        copy incrementDates(x) of me to {theDayIndex, theMonthIndex, theYear, theDateString, monthLengthInDays} 
        set monthStart to theDateString 
        set monthEnd to theMonthIndex & "/" & monthLengthInDays & "/" & theYear as text 
        set the value of cell (x + 1) to ("=SUMIFS(Payment,Date, \">=" & monthStart & "\", Date, \"<=" & monthEnd & "\")") 
       end repeat 
      end tell -- end telling column B 
     end tell -- end telling totalsTable 
    end tell -- end telling active sheet 

    make new sheet with properties {name:"Money Out"} 
    tell sheet 2 
     delete every table 
     set moneyOutTable to make new table with properties {name:"Money Out", position:{-7, 29}, width:710, column count:count moneyOutHeaders, row count:14, footer row count:1} 
     tell moneyOutTable 
      set catCount to count categoryItems -- get count of categoryItems 
      set properties of column "A" to {width:180} 
      set properties of row 1 to {background color:{moneyOutColor}} 
      set value of last cell of column "B" to ("=SUM(B)") 
      my populateCells(moneyOutTable, row 1, moneyOutHeaders, false) -- fill header row values 
      my populateCells(moneyOutTable, column named "Category", categoryItems, true) -- fill pop up values 
      my formatCells(moneyOutTable, column "A", text) 
      my formatCells(moneyOutTable, column named "Amount", currency) 
      my formatCells(moneyOutTable, column named "Date", date and time) 
      my formatCells(moneyOutTable, column named "Category", pop up menu) 
      my formatCells(moneyOutTable, column named "Item", text) 
      delete (rows 2 through (catCount + 1)) -- remove rows that contain values so the pop up menu is empty 
      repeat catCount times -- add the rows back to keep table size 
       add row below row 2 
      end repeat 
     end tell -- end telling moneyOutTable 

     set totalsTable to make new table with properties {name:"Money Out Totals", locked:false, position:{744, 29}, column count:2, row count:(count monthNames) + 2, header column count:1, header row count:1, footer row count:1} 
     tell totalsTable 
      set properties of row 1 to {background color:{moneyOutColor}} 
      my populateCells(totalsTable, column "A", monthNames, true) 
      set value of last cell of column "A" to "Grand Total" 
      set value of cell "B1" to "Totals" 
      set value of last cell to ("=SUM(B)") 
      tell column "B" 
       repeat with x from 1 to count monthNames -- oop and increment dates for the SUMIFS formula 
        copy incrementDates(x) of me to {theDayIndex, theMonthIndex, theYear, theDateString, monthLengthInDays} 
        set monthStart to theDateString 
        set monthEnd to theMonthIndex & "/" & monthLengthInDays & "/" & theYear as text 
        set theFormula to ("=SUMIFS(Amount,Date, \">=" & monthStart & "\", Date, \"<=" & monthEnd & "\")") 
        set the value of cell (x + 1) to theFormula 
       end repeat 
      end tell -- end telling column B 
     end tell -- end telling totalsTable 

     set summaryTable to make new table with properties {name:"Category Totals", position:{943, 29}, column count:2, row count:(catCount) + 1} 
     tell summaryTable 
      set properties of row 1 to {background color:{moneyOutColor}} 
      set value of cell "B1" to "Totals" 
      my populateCells(summaryTable, column "A", categoryItems, true) 
      my formatCells(summaryTable, column "B", currency) 
      tell column 2 
       repeat with x from 2 to the count of cells 
        set theFormula to ("=SUMIFS(Amount,Category,A)") 
        set the value of cell x to theFormula 
       end repeat 
      end tell -- end telling column 2 
     end tell -- end telling summaryTable 

     -- Extreme hang starts on this table, specifically below where noted 

     set breakDownTable to make new table with properties {name:"Expenses By Month", column count:(count monthNames) + 1, row count:(count categoryItems) + 2, header column count:1, footer row count:1, header row count:1} 
     tell breakDownTable 
      set properties of row 1 to {background color:{moneyOutColor}} 
      my populateCells(breakDownTable, row 1, monthNames, true) 
      my populateCells(breakDownTable, column "A", categoryItems, true) 
      my formulateRow(breakDownTable, last row, "SUM") 
      set selection range to range "B2:M8" 
      set properties of selection range to {format:currency} 
      set value of last cell of column "A" to "Total" 

--***** This is where the extreme hang begins 

      repeat with x from 1 to (count rows) - 2 
       repeat with y from 1 to count monthNames 
        copy incrementDates(y) of me to {theDayIndex, theMonthIndex, theYear, theDateString, monthLengthInDays} 
        set monthStart to theDateString 
        set monthEnd to theMonthIndex & "/" & monthLengthInDays & "/" & theYear as text 
        set theFormula to "=SUMIFS(Amount,Category,A,Date, \">=" & monthStart & "\",Date, \"<=" & monthEnd & "\")" 
        set value of cell (y + 1) of row (x + 1) to theFormula 
       end repeat 
      end repeat 

--***** Extreme hang ends and script continues normally 

      add column after last column -- add a totals column after everything else is done 
      set totalsColumn to the last column 
      tell totalsColumn 
       set value of cell 1 to "Total" 
       my formulateColumn(breakDownTable, totalsColumn, "SUM") 
      end tell -- end telling totalsColumn 
     end tell -- end telling breakDownTable 
    end tell -- end telling sheet 2 

    make new sheet with properties {name:"Overview"} 
    tell sheet 3 
     delete every table 
     set cashFlowTable to make new table with properties {name:"Cashflow", column count:2, row count:(count monthNames) + 2, footer row count:1} 
     tell cashFlowTable 
      my populateCells(cashFlowTable, column "A", monthNames, true) 
      set value of last cell of column "A" to "Grand Total" 
      my formatCells(cashFlowTable, column "B", currency) 
      set value of cell "B1" to "Cashflow Totals" 
      set value of last cell to ("=SUM(B)") 
      tell column 2 
       repeat with x from 1 to count monthNames 
        set value of cell (x + 1) to ("=Money In::Money In Totals::Totals " & item x of monthNames & "−Money Out::Money Out Totals::Totals " & item x of monthNames) 
       end repeat 
      end tell -- end telling column 2 
     end tell -- end telling cashflow table 
    end tell -- end telling sheet 3 
    set active sheet to first sheet 
end tell -- end telling document 
end tell -- end telling Numbers 

using terms from application "Numbers" 

to populateCells(theTable, theDirection, theListToUse, usingHeaders) 
    tell theTable 
     set x to 1 
     if usingHeaders is true then 
      repeat with x from 1 to count theListToUse 
       set value of cell (x + 1) of theDirection to (item x of theListToUse) 
      end repeat 
     else 
      repeat with x from 1 to count theListToUse 
       set value of cell x of theDirection to (item x of theListToUse) 
      end repeat 
     end if 
    end tell 
end populateCells 

to formatCells(theTable, theDirection, theFormat) 
    tell theTable 
     set theRange to ¬ 
      ((name of cell 2 of theDirection) & ":" & ¬ 
       (name of last cell of theDirection)) 
     set selection range to range theRange 
     set properties of selection range to {format:theFormat} 
    end tell 
end formatCells 

to colorCells(theTable, theDirection, theColor) 
    tell theTable 
     set theRange to ¬ 
      ((name of cell 2 of theDirection) & ":" & ¬ 
       (name of last cell of theDirection)) 
     set selection range to range theRange 
     set properties of selection range to {background color:theColor} 
    end tell 
end colorCells 

to formulateColumn(theTable, theColumn, theType) 
    tell theTable 
     tell theColumn 
      repeat with i from 2 to the count of cells 
       set thisRow to the row of cell i 
       set rangeStart to the name of cell 2 of thisRow 
       set rangeEnd to the name of cell -2 of thisRow 
       set theFormula to ("=" & theType & "(" & rangeStart & ":" & rangeEnd & ")") as string 
       set value of cell i to theFormula 
      end repeat 
     end tell 
    end tell 
end formulateColumn 

to formulateRow(theTable, theRow, theType) 
    tell theTable 
     tell theRow 
      repeat with i from 2 to the count of cells 
       set thisColumn to the column of cell i 
       set rangeStart to the name of thisColumn 
       set rangeEnd to the name of thisColumn 
       set theFormula to ("=" & theType & "(" & rangeStart & ":" & rangeEnd & ")") as string 
       set value of cell i to theFormula 
      end repeat 
     end tell 
    end tell 
end formulateRow 

end using terms from 

to incrementDates(tempMonth) 
    copy (current date) to tempDate 
    set day of tempDate to 1 
    set month of tempDate to tempMonth 
    set theDayName to weekday of tempDate 
    set theDayIndex to day of tempDate 
    set theMonth to month of tempDate 
    set theMonthIndex to theMonth as integer 
    set theMonthName to theMonth as string 
    set theYear to year of tempDate 
    set theDateString to short date string of tempDate 
    repeat with i from 1 to 32 
     set tempDate to tempDate + (1 * days) 
     if month of tempDate is not theMonth then 
      set monthLengthInDays to i 
      exit repeat 
     end if 
    end repeat 
    return {theDayIndex, theMonthIndex, theYear, theDateString, monthLengthInDays} 
end incrementDates 
+0

儘量避免複製(當前日期)。改爲使用:將tempDate設置爲當前日期 –

+0

@Pat_Morita這有點含糊。沒有推理?我將如何引用從incrementDates處理程序返回的值?如果你打算花時間發表評論,至少要讓它有意義或有幫助。你的評論等同於回答「爲什麼我的手臂會受傷?」用「用你的另一隻手臂」。 – Jesse

回答

0

尋找你的劇本後,我已經跑了,並沒有經歷過你所描述使葉片問題的系統或多個測試運行,而寫劇本的滯後。

接下來,如上述註釋中所述,您可以在incrementDates處理程序中使用set命令而不是copy。你不需要的每個處理程序被調用時(current date)副本(每次通話12次),這樣可以改成

to incrementDates(tempMonth) 
    set tempDate to (current date) 
    set day of tempDate to 1 
    set month of tempDate to tempMonth 
    set theDayName to weekday of tempDate 
    set theDayIndex to day of tempDate 
    set theMonth to month of tempDate 
    set theMonthIndex to theMonth as integer 
    set theMonthName to theMonth as string 
    set theYear to year of tempDate 
    set theDateString to short date string of tempDate 
     repeat with i from 1 to 32 
     set tempDate to tempDate + (1 * days) 
     if month of tempDate is not theMonth then 
      set monthLengthInDays to i 
      exit repeat 
     end if 
    end repeat 
    return {theDayIndex, theMonthIndex, theYear, theDateString, monthLengthInDays} 
end incrementDates 

從那裏,你仍然會檢索和你現在做的值。

接下來,您還創建了一個處理程序,在這裏處理程序不是特別需要的。

to formatCells(theTable, theDirection, theFormat) 
    tell theTable 
     set theRange to ¬ 
     ((name of cell 2 of theDirection) & ":" & ¬ 
      (name of last cell of theDirection)) 
    set selection range to range theRange 
    set properties of selection range to {format:theFormat} 
end tell 
end formatCells 

上面是一樣的使用

set properties of column named "Payment" to {format:currency} 

的區別是微不足道的,但我一般指南是不推倒重來。你還沒有使用,其中一個處理程序可以創建totalsTable

to makeMonthlyTotalsTable(theTable, theColor) 
    tell theTable 
     set properties of row 1 to {background color:{theColor}} 
     my populateCells(totalsTable, column "A", monthNames, true) 
     set value of last cell of column "A" to "Grand Total" 
     set value of cell "B1" to "Totals" 
     set value of last cell to ("=SUM(B)") 
     tell column "B" 
      repeat with x from 1 to count monthNames -- loop and increment dates for the SUMIFS formula 
       copy incrementDates(x) of me to {theDayIndex, theMonthIndex, theYear, theDateString, monthLengthInDays} 
       set monthStart to theDateString 
       set monthEnd to theMonthIndex & "/" & monthLengthInDays & "/" & theYear as text 
       set the value of cell (x + 1) to ("=SUMIFS(Payment,Date, \">=" & monthStart & "\", Date, \"<=" & monthEnd & "\")") 
      end repeat 
     end tell -- end telling column B 
    end tell -- end telling totalsTable 
end makeMonthlyTotalsTable 

再微不足道的差異,也許看法,但更乾淨的代碼時,如果你打算重新創建一個表中其他工作表中使用的處理程序。

注意:我沒有測試這個處理程序,我只是從腳本中複製並粘貼了它,並更改了要傳遞的變量名稱,但只要您設置並聲明顏色名稱變量並切換monthNames屬性。

property monthNames : {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}