首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Google脚本-让onEdit()识别setValue()更改

Google脚本-让onEdit()识别setValue()更改
EN

Stack Overflow用户
提问于 2015-08-14 18:43:16
回答 3查看 6.4K关注 0票数 2

我有一个带有一些功能的电子表格。其中一个是onEdit(事件)函数,它根据条件将一些值复制到其他工作表。这是代码(简化,但重要部分完好无损):

代码语言:javascript
运行
复制
function onEdit(event) {
    var ss = SpreadsheetApp.getActiveSpreadsheet();
    var s = event.source.getActiveSheet();
    var r = event.range;
    if(s.getName() === "Lista" && r.getColumn() === 9 && r.getValue() === "Posicionada") {
      var sheetname = s.getRange(r.getRow(),3).getValue();
      var columnRef = s.getRange(r.getRow(),4).getValue();
      var row = s.getRange(r.getRow(),5).getValue();
      var targetSheet = ss.getSheetByName("Mapa " + sheetname);
      var headers = targetSheet.getRange(1, 1, 1, targetSheet.getLastColumn());
      for (var i = 0; i < headers; i++) {
        if (headers[i] === columnRef) {
          break;
        }
      }
      var column;
      if (columnRef === "A1") {
        column = 2;
      }
      else if (columnRef === "A2") {
        column = 3;
      }
      else if (columnRef === "B1") {
        column = 4;
      }
      else if (columnRef === "B2") {
        column = 5;
      } 
      if (sheetname === "N2") {
        row = row - 30;
      }
      if (sheetname === "N3") {        
        column = column - 10;
        row = row - 42;
      }
      targetSheet.getRange(row,column).setValue(s.getRange(r.getRow(), 1, 1, 1).getValue()); 
    }
}

当我手动编辑单元格时,代码的工作原理是一样的。但是,当用户按下侧边栏中的按钮时,我有一个编辑单元格的代码,这是代码:

代码语言:javascript
运行
复制
function positionMU(){
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var cell = ss.getActiveCell().activate();
  var cellLevel = cell.offset(0,2);
  var cellLetter = cell.offset(0,3);
  var cellNumber = cell.offset(0,4);
  var cellStatus = cell.offset(0,8);
  var dbq = "Posicionada";
  var fora = "Pendente de recebimento";  
  if (cellStatus.getValue() == "Aguardando posicionamento"){
      cellStatus.setValue(dbq);    //attention in this line  
  }
  else if (cellStatus.getValue() == "Aguardando saída"){
      cellStatus.setValue(fora);
      var cellExitDate = cell.offset(0,6);
      cellExitDate.setValue(getDate());
  }
}

如您所见,这个函数用setValue()来更改单元格内容,但是,当我使用这个函数时,单元格的值会发生变化,但是onEdit()触发器不能工作。

如何使onEdit()触发器识别使用setValue()所做的更改?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-08-14 20:40:30

你是正确的。只有在手动编辑范围时才触发onEdit()。可以看到,当一个值被这里用户更改时,onEdit()会触发。

我通过使函数将值插入到onEdit响应的列中来测试该函数,但没有发生任何事情。包括我能想到的各种其他技术。这里最好的做法是将其作为App脚本的问题跟踪器上的一种增强。

但是,当脚本中的另一个函数对工作表进行更改时,我编写了另一个要调用的函数,从而使其工作起来。这些是我编写的测试函数:

代码语言:javascript
运行
复制
function addValues()
{
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getSheetByName("Sheet1");
  var range = sheet.getDataRange();

  var book = "Book";
  var cancel = "Cancel";

  var maxRow = range.getLastRow()+1;

  for(var i=0; i<4; i++)
  {
    if (i%2 == 0)
    {
      sheet.getRange(maxRow, 1).setValue(book);
      autoChanges(maxRow);
    }else{
      sheet.getRange(maxRow, 1).setValue(cancel);
      autoChanges(maxRow);
    }

    maxRow++;
  }
}

autoChanges函数:

代码语言:javascript
运行
复制
function autoChanges(row)
{
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getSheetByName("Sheet1");
  var range = sheet.getDataRange();
  var data = range.getValues();

  var response = "";

  sheet.getRange(row, 2).protect();

  response = data[row-1][0];

  if (response == "Book")
  {
    sheet.getRange(row, 2).canEdit();
  }else{
    sheet.getRange(row, 2).setValue("--NA--");
  } 
}

这不是最优雅的解决方案,但这似乎是解决您所要做的事情的唯一方法。

票数 2
EN

Stack Overflow用户

发布于 2018-02-21 06:33:15

调用range.setValue()不触发onEdit事件有一些很好的理由,其中大多数都与无限递归有关。实际上,您在setValue()中自己调用了onEdit()。这将触发一个递归调用,据我所见,您没有处理基本情况的准备,因此,如果setValue()做了您想做的事情,那么您的代码就会爆炸。

为什么不简单地将所有代码从事件处理程序中删除,并将其放入另一个函数:

代码语言:javascript
运行
复制
function onEdit (e) {
  return handleEdits(e.range);
}

function handleEdits(r) {
  s = r.getSheet();
  ss = s.getParent();
  //the rest of your code should drop right in.
}

然后,在您的autoChanges函数中,在调用setValue()之后,继续调用handleEdits,并传递适当的范围。

票数 1
EN

Stack Overflow用户

发布于 2021-10-18 17:35:29

如果你喜欢玩火,我个人也喜欢,你可以在你做出改变后调用onEdit(e)函数。只要发送一个由e对象调用和使用的对象即可。

对我来说,我只是想补充一下:

代码语言:javascript
运行
复制
    var e={};
    e.range=the range you are making a change to in the script;
    e.source = SpreadsheetApp.getActiveSpreadsheet();//or make sure you have the sheet for wherever you are setting the value
    e.value=whatever value you are setting
    e.oldValue=if you onEdit needs this, set it here
    //if you are using any of the other standard or special properties called by your onEdit...just add them before calling the function.
    onEdit(e);//call the function and give it what it needs.
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32016776

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档