如何使onEdit()脚本适用于从剪贴板粘贴的值列表时修改的所有行?

时间:2017-02-11 17:25:02

标签: google-apps-script google-sheets

我有一张工作表,我想跟踪每个新行,第一次填充某个单元格的值的日期,以及该行中任何单元格更新的日期。所以我有这个脚本可以做我想要的:

function onEdit() {

 var s = SpreadsheetApp.getActiveSheet();
 var r = s.getActiveCell();

 // If it is first time keyword added, we will add the current date to "Date Added" Column 

 if( s.getName() == "Sheet1" ) { //checks that we're on the correct sheet
   var r = s.getActiveCell();

   // We will if it is the first time the "Keyword" column has been written
   if( r.getColumn() == 2 ) { 
     var nextCell = r.offset(0, 2);
     if( nextCell.getValue() === '' ) //is empty?
       var time = new Date();
       time = Utilities.formatDate(time, "GMT-08:00", "MM/dd/yy");
       nextCell.setValue(time);
   };
 };

 // If there is any further change, then add/change the date in the "Date last modified" column 

 var r = s.getActiveCell();

  if( r.getValue() !== '' && r.getRow() !== 1){ // Disregard when it was just a new row that was inserted

    if( r.getColumn() != 5 ) { //checks the column
    var row = r.getRow();
    var time = new Date();
    time = Utilities.formatDate(time, "GMT-08:00", "MM/dd/yy");
    SpreadsheetApp.getActiveSheet().getRange('E' + row.toString()).setValue(time);
    };

  };  
}

我的问题是,每当我提供一个值列表并将它们粘贴到空行空间时,该脚本似乎只适用于我添加的新值的所有行的第一行。

所以,如果我来,我粘贴它:

value1
value2
value3
value4
value5

我结束:

value1     2/11/2017     2/11/2017
value2
value3
value4
value5

但是我希望脚本能以这样的方式工作:

value1     2/11/2017     2/11/2017
value2     2/11/2017     2/11/2017
value3     2/11/2017     2/11/2017
value4     2/11/2017     2/11/2017
value5     2/11/2017     2/11/2017

有人可以让我知道我需要更改/添加什么来修复此行为吗?

非常感谢!

1 个答案:

答案 0 :(得分:1)

您可以使用can activeRange而不是activeCell,如下所示:

range = s.getActiveRange()

这将为您提供粘贴新数据的范围,然后循环遍历该范围内的每一行:

for(var i = 1; i<= range.getNumRows() ; i++){
   var r = range.getCell(i, 1)
   ...
}
当p = 1时,

range.getCell(i,1)将给出活动范围中的第一个单元格,当i = 2时,它将在第二个单元格下面,等等。 注意:这里的假设是您将新列表一次粘贴到一列中,尤其是在修改第2列时。因此,如果将数据粘贴到A2:C5的范围内,则range.getCell(1,1)将给出A2并且代码将假定第2列未被修改。如果我的假设不正确,只需修改脚本以确定第2列是否在活动范围内并选择该列。

function onEdit() {

 var s = SpreadsheetApp.getActiveSheet();
 // Instead of getting activeCell we get the whole range
 var range = s.getActiveRange()

 //Use For loop to go through each row and add the time Stamp
 for(var i = 1; i<= range.getNumRows() ; i++){

   var r = range.getCell(i, 1) //Assumption here is that data is pasted in one column only
   // IF that is not always the case, you will have to get the range over which the data was pasted and select column 2

   if( s.getName() == "Sheet1" ) { //checks that we're on the correct sheet
      //var r = s.getActiveCell(); calling it again doesnt change its the value
      // If it is first time keyword added, we will add the current date to "Date Added" Column  
      // We will if it is the first time the "Keyword" column has been written

     if( r.getColumn() == 2 ) { 
        var nextCell = r.offset(0, 2);
        if( nextCell.getValue() === '' ) {//is empty?
           var time = new Date();
           time = Utilities.formatDate(time, "GMT-08:00", "MM/dd/yy");
           nextCell.setValue(time);
        }
      };
    };

    // If there is any further change, then add/change the date in the "Date last modified" column 
    // var r = s.getActiveCell(); calling it again doesnt change its the value
  if( r.getValue() !== '' && r.getRow() !== 1){ // Disregard when it was just a new row that was inserted
    if( r.getColumn() != 5 ) { //checks the column
       var row = r.getRow();
       var time = new Date();
       time = Utilities.formatDate(time, "GMT-08:00", "MM/dd/yy");
       SpreadsheetApp.getActiveSheet().getRange('E' + row.toString()).setValue(time);
     };

   };  
 }
}

PS:在此代码中一次更新一个单元格值不是一个好习惯。而是使用getValues和setValues来批量访问和设置值。特别是如果用户将大量数据粘贴到工作表中。 http://googleappsscript.blogspot.com/2010/06/optimizing-spreadsheet-operations.html