当前位置: 首页 > 知识库问答 >
问题:

Google应用程序脚本-使OneEdit()识别setValue()更改

东郭承业
2023-03-14

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

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()); 
    }
}

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

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()所做的更改?

共有3个答案

冀望
2023-03-14

如果您喜欢玩fire,我个人也喜欢,您可以在进行更改后调用onEdit(e)函数。只要将e对象调用和使用的内容发送到对象中即可。

对我来说,我只需要补充:

    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.
公冶嘉茂
2023-03-14

有一些很好的理由可以解释为什么要打电话。setValue()不会触发onEdit事件,并且大多数都与无限递归有关。事实上,您自己在onEdit()中调用setValue()。这将触发一个递归调用,从我所看到的情况来看,您没有处理基本情况的准备,因此如果setValue()做了您想要的事情,您的代码将爆炸。

为什么不干脆将所有代码从事件处理程序中取出,并将其放入另一个函数中:

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,并将适当的范围传递给它。

钮兴安
2023-03-14

onEdit()仅在手动编辑范围时触发。这里可以看到,当用户更改值时,onEdit()会触发。

测试了这个函数,让函数将值插入到我的onEdit响应的列中,但什么也没有发生。包括我能想到的各种其他技术。这里最好的做法是建议将其作为应用程序脚本问题跟踪程序的增强。

但是,我编写了另一个函数,在脚本中的另一个函数对工作表进行更改时调用该函数。以下是我编写的测试函数:

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++;
  }
}

自动更改功能:

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--");
  } 
}

不是最优雅的解决方案,但这似乎是您试图做的唯一变通方法。

 类似资料:
  • 我正试图制作一个电子表格来管理我的资金/开支,但在尝试自动化我的流程时遇到了一个问题 我想制作一段代码,每次在工作表中编辑单元格时运行。 当被触发时,我希望它计算ssum,lsum和betal(在循环中),然后将其放入3个不同的单元格中。代码的行为符合预期,但onedit触发器不起作用。 这是我的代码: 输出变量根据调用函数的位置相应地设置相邻单元格 我试过使用setValue和clearCont

  • 在谷歌工作表上,尝试根据特定单元格中的值隐藏/取消隐藏行,并尝试在AppsScript中为此编写脚本。发现一个隔离工作(如果B55=NO,则隐藏64行): 但我需要对多个单元格和多行使用相同的方法,只要我展开它,就只有代码的最后一部分有效,而不是第一部分: 从这里开始,B121号牢房开始工作,但我的B55停止工作。有什么提示吗?谢谢!

  • 我欣赏这个团体的集体智慧。 我在互联网上找到了这些代码片段,并试图将它们应用到我的情况中,决不打算剽窃任何人。。。 我想把单元格中的每个单词大写。我从onEdit(e)函数中调用如下脚本。什么都不做。这看起来不太对,很明显我错过了重要的数据... 我是一个新手,我真的很感激任何指导。 吉姆

  • 我有一个谷歌表单,在a列中,我需要用无替换按钮上的文本。该列在几个不同的行中具有需要保持不变的标题。我写了以下脚本: 当我尝试运行脚本时,会出现以下错误:数据中的行数与范围中的行数不匹配。数据有1,但范围有2。 我知道这与具有比其他行更多列的行有关,但不确定如何修复代码。

  • 我试图创建弹出窗口和电子邮件通知时,某些每日限制超过编辑的电子表格。 当与今天日期相关的值超过限制并且我运行脚本时,将发送弹出窗口和电子邮件通知。但是当使用onEdit函数时,即编辑编辑范围中定义的列...只引发弹出通知,不发送电子邮件。 有人知道为什么onEdit功能适用于电子表格应用程序吗。getUi()。警报,但不是MailApp。发送电子邮件?为什么它在运行代码时工作,而不是onEdit?

  • 我正在开发一个GoogleApps脚本电子表格应用程序,我希望该程序具备的能力之一是根据来自两个不同列的数据自动排序一系列表单响应。所以我想按第16列中的数据排序,然后按第1列排序。我可以使用以下方法手动实现此功能:https://drive.googleblog.com/2010/06/tips-tricks-advanced-sorting-rules-in.html 目前我正在运行函数与第一