18

我需要检测是否在某个数据范围内对电子表格进行了更改,如果是,请设置当前更新时间。

问题是,我有一个电子表格,我在上面编辑标题和文本,我不希望在电子表格上更新特定单元格中的更新时间,但是当我编辑一系列单元格中的数据时,我确实想要更新时间变了。

这是我要更新的时间。

function onEdit(e) 
{
  var ss = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();

  ss.getRange("G10").setValue(new Date());
} ​

如果我编辑某些单元格(在“B4:J6”范围内),我只想设置 G10 中的日期

4

6 回答 6

31

有一个事件作为onEdit()函数的参数提供,它包含有关编辑内容的必要信息。如果您想知道那(e)是怎么回事,就是这样。

由于每次onEdit()编辑都会调用一个函数,因此您应该在确定是否应该退出时投入尽可能少的处理。通过使用传入的事件,您将需要更少的服务调用,因此效率更高。如果您需要灵活,Rasmus 的答案将 A1 表示法转换为列号和行号的方式很好,但如果编辑范围是固定的,您可以简单地使用常量值进行比较 - 再次减少所需的处理时间。

function onEdit(e) 
{
  var editRange = { // B4:J6
    top : 4,
    bottom : 6,
    left : 2,
    right : 10
  };

  // Exit if we're out of range
  var thisRow = e.range.getRow();
  if (thisRow < editRange.top || thisRow > editRange.bottom) return;

  var thisCol = e.range.getColumn();
  if (thisCol < editRange.left || thisCol > editRange.right) return;

  // We're in range; timestamp the edit
  var ss = e.range.getSheet();
  ss.getRange(thisRow,7)   // "G" is column 7
    .setValue(new Date()); // Set time of edit in "G"
} ​
于 2013-07-16T18:31:07.183 回答
15

最简单的方法是命名您的触发范围

通过命名您的“触发”范围,一旦您在脚本中设置了范围名称,您就不必弄乱脚本。通过简单地在标准 google 表格界面中编辑命名范围的范围,即使您扩大或缩小范围的大小,脚本仍然可以工作。

第 1 步:命名您的范围

如果您按照此处的说明编辑范围内的任何单元格,请将您感兴趣的单元格范围命名为脚本的触发器:https: //support.google.com/docs/answer/63175

我将我的范围命名为“triggerRange”。

第 2 步:将您的范围名称编辑到以下脚本中:

function onEdit(e) {
      var myRange = SpreadsheetApp.getActiveSheet().getRange('triggerRange'); //<<< Change Your Named Ranged Name Here inside the getRange() function.
      //SpreadsheetApp.getUi().alert("myRange in A1 Notation is: " + myRange.getA1Notation()); //If you're having problems, uncomment this to make sure your named range is properly defined

      //Let's get the row & column indexes of the active cell
      var row = e.range.getRow();
      var col = e.range.getColumn();
      //SpreadsheetApp.getUi().alert('The Active Cell Row is ' + row + ' and the Column is ' + col); //uncomment this out to do testing

      //Check that your active cell is within your named range
      if (col >= myRange.getColumn() && col <= myRange.getLastColumn() && row >= myRange.getRow() && row <= myRange.getLastRow()) { //As defined by your Named Range
        SpreadsheetApp.getUi().alert('You Edited a Cell INSIDE the Range!');//Repalace Your Custom Code Here
      } else {
        SpreadsheetApp.getUi().alert('You Edited a Cell OUTSIDE the Range!');//Comment this out or insert code if you want to do something if the edited cells AREN'T inside your named range
        return;
      }
    }

PS:感谢其他发帖者为这个基本脚本提供了基本框架。我显然已经对脚本进行了大量评论,因此您可以轻松地对其进行测试。删除我在脚本中创建的警报以获得更清晰的外观......或者只是复制并粘贴它:

function onEdit(e) {
  var myRange = SpreadsheetApp.getActiveSheet().getRange('triggerRange'); //<<< Change Your Named Ranged Name Here

  //Let's get the row & column indexes of the active cell
  var row = e.range.getRow();
  var col = e.range.getColumn();

  //Check that your active cell is within your named range
  if (col >= myRange.getColumn() && col <= myRange.getLastColumn() && row >= myRange.getRow() && row <= myRange.getLastRow()) { //As defined by your Named Range
    SpreadsheetApp.getUi().alert('You Edited a Cell INSIDE the Range!');//Repalace Your Custom Code Here
  }
}
于 2018-04-13T05:33:28.617 回答
4

您可以简单地检查编辑事件是否在范围内发生。

function onEdit(e)
{
  var sheet = SpreadsheetApp.getActiveSheet();
  var editRange = sheet.getActiveRange();
  var editRow = editRange.getRow();
  var editCol = editRange.getColumn();
  var range = sheet.getRange("B4:J6");
  var rangeRowStart = range.getRow();
  var rangeRowEnd = rangeRowStart + range.getHeight();
  var rangeColStart = range.getColumn();
  var rangeColEnd = rangeColStart + range.getWidth();
  if (editRow >= rangeRowStart && editRow <= rangeRowEnd 
      && editCol >= rangeColStart && editCol <= rangeColEnd)
  {
    // Do your magic here
  }
}

我承认这非常冗长,但我仍然没有在 range ala range.contains(range) 上找到一个简单的方法

于 2012-11-23T09:32:52.323 回答
3

只是对 Rasmus 先前答案的可能问题的快速修复:

线上:

var rangeRowEnd = rangeRowStart + range.getHeight();
var rangeColEnd = rangeColStart + range.getWidth();

它正在添加(实际上它没有减去初始行和列。这导致范围比 1 行和 1 个整列的预期范围更大。只需在同一行中减去 1:

var rangeRowEnd = rangeRowStart + range.getHeight()-1;
var rangeColEnd = rangeColStart + range.getWidth()-1;

Rasmus Fuglsnag 的代码和更正应如下所示:

function onEdit(e)
{
  var sheet = SpreadsheetApp.getActiveSheet();
  var editRange = sheet.getActiveRange();
  var editRow = editRange.getRow();
  var editCol = editRange.getColumn();
  var range = sheet.getRange("B4:J6");
  var rangeRowStart = range.getRow();
  var rangeRowEnd = rangeRowStart + range.getHeight()-1;
  var rangeColStart = range.getColumn();
  var rangeColEnd = rangeColStart + range.getWidth()-1;
  if (editRow >= rangeRowStart && editRow <= rangeRowEnd 
      && editCol >= rangeColStart && editCol <= rangeColEnd)
  {
    // Do your magic here
  }
}

感谢Rasmus Fuglsnag提供了最简单的方法。我不敢相信有更好更简单的方法可以通过代码来做到这一点。

于 2015-07-22T16:26:57.633 回答
2

如果你想要很少的代码行,你可以使用:

function onEdit(){
  var cell = SpreadsheetApp.getActive().getActiveCell();
  var row = cell.getRow();
  var col = cell.getColumn();

  //if col > A && col < K ...
  if(col > 1 && col < 11 && row > 3 && row < 7){ //B4:J6
    //do something
  }

但是,更改范围可能需要比其他方法更长的时间。

于 2017-10-13T04:51:25.537 回答
1

为了保持舒适的代码,您可以使用调度程序(受Doomd答案的启发)。

/** 
 if the changed cell is in the good sheet and range:
 @returns {Range} : the changed cell range
 else
 @returns {boolean} : false
*/
function onEdit_inRange(e,sheetName,sheetRange){
    var sh=e.range.getSheet();
    if(sh.getName()===sheetName){
        var range = SpreadsheetApp.getActiveSheet().getRange(sheetRange);
        var xy=[e.range.getColumn(),e.range.getRow()];
        if (xy[0]>=range.getColumn() && xy[0]<=range.getLastColumn() && xy[1]>=range.getRow() && xy[1]<=range.getLastRow()) {
            return e.range;
        }
    }
    return false;
}

如何使用 :

function onEdit(e){
    var range=0;
    if((range=onEdit_inRange(e,'Stats','Q47:Z47'))){
        _handle_stats(range);
    }else if ((range=onEdit_inRange(e,'Calendar','A5:B29'))) {
        _handle_calendar(range);
    }// etc ...
}
于 2020-01-24T20:29:59.167 回答