2013-01-12 118 views
0
function onEdit() { 
var openRequests = SpreadsheetApp.getActive().getSheetByName('Open Requests'); 
var lastRowOpen = openRequests.getLastRow(); 

var closedRequests = SpreadsheetApp.getActive().getSheetByName('Closed Requests'); 
var lastRowClose = closedRequests.getLastRow(); 

var closed = openRequests.getRange(2,8,lastRowOpen,1).getValues(); 

for (var i = 0; i < lastRowOpen; i++) 
{ 
    if (closed[i][0].toString() == 'Yes') 
    { 
     var line = i+2; 
     if (closedRequests.getLastRow() == 1) 
     { 
      openRequests.getRange(line,1,1,9).copyTo(closedRequests.getRange(2,1,1,9)); 
      closedRequests.getRange(2,9,1,1).setValue(new Date()); 
      openRequests.deleteRow(line); 
     } 
     else 
     { 
      openRequests.getRange(line,1,1,9).copyTo(closedRequests.getRange(lastRowClose+1,1,1,9)); 
      closedRequests.getRange(lastRowClose+1,9,1,1).setValue(new Date()); 
      openRequests.deleteRow(line); 
     } 
    } 
} 

}在電子表格

谷歌Apps腳本雙刪除行我已經設置了一個觸發運行onEdit。它所做的是檢查名爲Closed的列以查看它是否表示YesClosed列有一個數據驗證下拉菜單,其中包含值Yes

所以,當我點擊下拉菜單,選擇Yes,應該整行復制到名爲Closed Requests然後刪除叫Open Requests電子表格中的行另一片。

我遇到的問題是,大約有50%的時間,它刪除了我選擇的行Yes,但它也刪除了它下面的行(大約50%的時間發生這種情況,只有一些時間第二個刪除的行顯示在Closed Requests中,除非我撤消,否則整行的其他時間會永遠消失)。

從我所知道的情況來看,deleteRow()函數刪除整行並將其下的所有行向上移一行以填充空白。所以下面那行意味着被刪除的行會被移動到同一行並被刪除。我不知道爲什麼函數被調用兩次。

我試着添加一些延遲,但它似乎並沒有工作。

回答

5
function onEdit(e) { 
    var eRange = e.source.getActiveRange(); 
    var openRequests = SpreadsheetApp.getActive().getSheetByName('Open Requests'); 
    var closedRequests = SpreadsheetApp.getActive().getSheetByName('Closed Requests'); 
    var nextRowClose = (closedRequests.getLastRow()?closedRequests.getLastRow()+1:2); 

    if(eRange.getSheet().getName()=="Open Requests" && eRange.getColumn()==8 && eRange.getValue()=="Yes") { 
    openRequests.getRange(eRange.getRow(), 1, 1, 9) 
     .copyTo(closedRequests.getRange(nextRowClose, 1)); 
    closedRequests.getRange(nextRowClose, 9).setValue(new Date()); 
    openRequests.deleteRow(eRange.getRow()); 
    } 
} 
+0

這似乎工作到目前爲止。你能告訴我我在做什麼導致了雙重刪除? – Jack

+0

嗨,傑克,我不知道你的劇本爲什麼會出現。在循環中修改文檔時,我曾經見過類似的東西。我提出的解決方案直接通過源代碼進行,無需循環前面的回覆,因爲從下拉列表中選擇「是」表示不應該有必要。希望這能滿足你的需求。問候,Michael – ScampMichael

+0

P.S.如果您希望追究此問題,可以通過Google Apps腳本問題跟蹤器在https://code.google.com/p/google-apps-script-issues/issues/list中提交併發佈更具體的答案 – ScampMichael

1

可以嘗試向後迭代,因爲它是mentioned to me。刪除後投入SpreadsheetApp.flush()也可能有幫助。

+0

你有同樣的問題嗎? – Jack

+0

不完全相同。切換到倒退是否有所作爲? –

+0

看起來沒有工作。 – Jack

1

@Jack,我有一個類似的用例給你。我的代碼是BryanP討論的後向代碼。我的代碼或多或少在這裏:"Batch removal of task items where status = 'Done'"。這是因爲我使用向後方法批量刪除它們,因此刪除具有較高行號的行將不會干擾具有較低行號的任何行的行號。

但你不是在批處理模式下刪除行,所以也許向後不應該有所作爲(也許除非兩個用戶用牀單和刪除在同一時間?)

所以想我會嘗試你的碼。我的鞋子把你的代碼放進了我的電子表格中已經存在的onedit()函數(用於在一段時間內不活動時將行着色爲紅色,並且一旦實際參加任務時放入一個時間戳)。

然後爲了測試我使用了其中一個已經有50行/任務的電子表格的副本。我手動填充所需的單元格在一行中,並從下拉菜單中選擇完成(我將您的代碼更改爲期望「完成」而不是「是」)。我重複了20行。

結果:您的代碼成功,因爲您已經預料到了20次中的每一次...沒有雙重刪除,總是複製數據。它對我而言沒有拖延,也沒有SpreadsheetApp.flush()。

我沒有一個可靠的建議,我害怕。在傳遞過程中,我提到了電子表格未正確刷新本身的已知錯誤,因此不顯示已刪除的行;這可以通過在出現此故障時手動刷新電子表格來檢查。 (但是,這種錯誤的跡象似乎與您的報告有關的兩個連續行的雙重複制在邏輯上不符)。

0

線程鎖?聽起來像一個線程鎖問題。嘗試:

function onEdit() { 

// ****** add lock code 
var lock = LockService.getPublicLock(); 
var hasMutex = lock.tryLock(100); 
if(hasMutex==false) { 
    return; 
} 
// *** end 

var openRequests = SpreadsheetApp.getActive().getSheetByName('Open Requests'); 
var lastRowOpen = openRequests.getLastRow(); 

var closedRequests = SpreadsheetApp.getActive().getSheetByName('Closed Requests'); 
var lastRowClose = closedRequests.getLastRow(); 

var closed = openRequests.getRange(2,8,lastRowOpen,1).getValues(); 

for (var i = 0; i < lastRowOpen; i++) 
{ 
    if (closed[i][0].toString() == 'Yes') 
    { 
     var line = i+2; 
     if (closedRequests.getLastRow() == 1) 
     { 
      openRequests.getRange(line,1,1,9).copyTo(closedRequests.getRange(2,1,1,9)); 
      closedRequests.getRange(2,9,1,1).setValue(new Date()); 
      openRequests.deleteRow(line); 
     } 
     else 
     { 

    openRequests.getRange(line,1,1,9).copyTo(closedRequests.getRange(lastRowClose+1,1,1,9)); 
     closedRequests.getRange(lastRowClose+1,9,1,1).setValue(new Date()); 
     openRequests.deleteRow(line); 
     } 
     } 
    } 


// ****** add lock code 
    lock.releaseLock();  

// *** end 

} 

問題:

1)很多人使用電子表格的時候是如何。

2)它多久發生一次。

+0

有人正在使用它。當它發生時,它會連續發生幾次。有時甚至根本不會發生。 – Jack

+0

你可以刪除「單元格樣式下拉菜單」 - 聽起來這是編輯的被稱爲兩倍的原因。 – eddyparkinson