2012-11-18 43 views
1

我想刪除空行。行885是一個非空行,應該保留。但是,我的代碼說(並在msgbox中顯示)885是空的,應該刪除。當它到達i = 884時,它會打印出真正在第885行的內容,並表示它不會被刪除。所以,我很困惑。它似乎正確地處理了這些數據,但它報告的行號是錯誤的。我懷疑你會告訴我補償是基於零的,行從1開始,所以如果lastrow = 888(基於1),那麼我需要減去1以匹配補償。所以我在電子表格中看到的第885行實際上是第884行的偏移量。在谷歌電子表格中關閉一行的行數

但是......當i =第885行有數據時,偏移量爲884.而當i = 884時,偏移量爲883 ......那麼爲什麼它要打印第885行呢?在這裏嚴重困惑。我錯了什麼?

最後但最重要的是......它刪除了錯誤的行!它如何能夠引用正確的數據,但仍然刪除錯誤的行?

var s = SpreadsheetApp.getActiveSheet(); 
var range = SpreadsheetApp.getActiveSheet().getDataRange(); 
var i = range.getLastRow(); 
var msg; 
var colNum; 

for (; i > 1; i--) { // I like to start at the end 
    var foundAvalue=0; // reset flag for each row 

    rowRange = range.offset(i, 0, 1); 

    var valArray=rowRange.getValues(); 
    var foundAvalue=0; 
    var msg; 
    var totalColumns=rowRange.getNumColumns(); 

    colNum=0; 

    while (colNum < totalColumns && (foundAvalue==0)) { 
    if (valArray[0][colNum] != '') {  
     foundAvalue=1; 
     msg="Row " + i + " =" + valArray[0]; 
     Browser.msgBox(msg); 
     msg="Row " + i + " will not be deleted"; 
     Browser.msgBox(msg); 
    } 
    colNum++; 
    } 
    if (foundAvalue == 0) { 
     msg="Row " + i + " =" + valArray[0] + "WILL be deleted"; 
     Browser.msgBox(msg); 
      // delete empty row 
     // s.deleteRow(i); 
    } 

} // end for(i) 
+0

對於在未來走來的人...... RocketDonkey讓我瞭解到,與上面的代碼的基本問題是,偏移量()函數需要的「i-1 「,我只用了」我「。 –

+0

原因是offset()將其答案作爲基於零的值返回。所以我的範圍通常是1到LastRow的偏移量返回爲0到LastRow-1。必須小心,因爲像deleteRow()這樣的函數需要一行從1到LastRow,而不是從零開始。 –

回答

3

下面是一些代碼應該完成你想要的。你是正確的,問題的根源在於基於0的索引。棘手的部分是JavaScript/Apps腳本陣列使用基於0的索引,但當您撥打類似getLastRow()的內容時,返回的範圍是基於1的。總而言之,你的代碼是好的 - 只有這個問題讓你感到沮喪。希望這有助於:

function DeleteFun(){ 
    var mySheet = SpreadsheetApp.getActiveSheet(); 
    var range = mySheet.getDataRange(); 

    // Iterate using a counter, starting at the last row and stopping at 
    // the header (assumes the header is in the first row) 
    for (i = mySheet.getLastRow() - 1; i > 0; i--) { 
    var foundAvalue = 0; 
    // Here we get the values for the current row and store in an array 
    rowRange = range.getValues()[i] 
    // Now we iterate through that array 
    for (j = 0; j <= rowRange.length; j++) { 
     // If any non-nulls are found, alert they won't be deleted and move on 
     if (rowRange[j] != null && rowRange[j] != '') { 
     foundAvalue = 1; 
     msg="Row " + (i+1) + " =" + rowRange[0] + " and will not be deleted"; 
     Browser.msgBox(msg); 
     break; 
     } 
    } 

    if (foundAvalue == 0) { 
     msg="Row " + (i+1) + " =" + rowRange[0] + "WILL be deleted"; 
     Browser.msgBox(msg); 
     // Delete empty row 
     mySheet.deleteRow(i+1); 
    } 
    } 
} 
+0

好吧,看起來你是從lastRow - 1開始行計數器「我」,這意味着我被用作數組的索引。所以「getvalues」顯然會返回一個基於零的範圍。嗯。我還沒有看到它。你正在獲取一行數據,並將其填充到一個數組中。所以過去的「rowNum」現在通過數組作爲「rowNum - 1」來適應基於零的索引。所以如果我的數據從第1行到第888行,數組索引是0到887.我明白了,總是有。現在,因爲你沒有改變deleteRow - 只有評論(續) –

+0

getLastRow塊返回實際的行號(從1開始),所以我們減1以允許'getValues [i]'函數正確引用它返回的基於0的數組。那有意義嗎?高興的幫助,直到它明確:) – RocketDonkey

+0

所以我不會丟失數據...我猜,deleteRow也需要零基索引?好的,我和你之間的主要區別似乎是我使用了「偏移」函數來使用rowNum來獲得範圍,並且你消除了這一步。你使用rowNum-1得到了範圍。所以你得到了887行,而不是888.我不明白爲什麼這會更好。現在我們只需跳過最後一行,幷包含我不需要處理的第一個標題行。我仍然不明白爲什麼我的代碼刪除錯誤的行。你測試了你的代碼嗎? –

1

你可以做到這一點在「純」陣列,以及如果您在您的工作表不使用的公式。

喜歡本作例子:

function deleteEmptyRows(){ 
var sh = SpreadsheetApp.getActiveSheet(); 
var data = sh.getDataRange().getValues(); 
var targetData = new Array(); 
for(n=0;n<data.length;++n){ 
if(data[n].join().replace(/,/g,'')!=''){ targetData.push(data[n])};// checks the whole row 
Logger.log(data[n].join().replace(/,/g,'')) 
} 
sh.getDataRange().clear(); // clear the whole sheet 
sh.getRange(1,1,targetData.length,targetData[0].length).setValues(targetData);//write back all non empty rows 
} 
+0

好吧,謝謝你提供了一種替代方式來完成工作。給我一些新的東西來學習...加入,取代,推...我相信有一天我會研究所有這些... –

+0

數組就像巧克力:一旦你品嚐它,你就無法抗拒了; - )試一試,你會感染! –

+0

我對數組非常熟悉。這是其他未知因素需要時間讓我的大腦不只是處理,而是研究。我在篝火旁開水。你剛剛用微波爐煮熟茄子帕爾米加納,並告訴我也這樣做。這將是一段時間。但是,謝謝你讓我知道那裏有什麼! –