javascript - 在 onEdit 触发器的事件对象中,如何将 range get 同时定义为实际范围对象和属性标识符?

标签 javascript google-apps-script google-sheets triggers

我有一个小代码示例来突出显示我创建的对象和触发事件对象之间的区别。在触发事件对象中,我可以使用术语 e.range与标准范围类函数一起使用,效果很好。但是,我真的不知道如何创建伪事件对象,以便范围项不仅仅是属性的名称。

   function onEdit(e) {
      console.log(JSON.stringify(e));
      var sh=e.range.getSheet();//e.range is a real range object
      if(sh.getName()=='Sheet2' && e.range.columnStart>1) {
        sh.getRange(1,1).setValue(JSON.stringify(e)+ '\n' + e.range.getA1Notation());
        var rg=sh.getRange(e.range.getA1Notation());//e.range is a real range object
        var myObj={value:rg.getValue,range:{columnStart:e.range.columnStart,rowStart:e.range.rowStart,columnEnd:e.range.columnEnd,rowEnd:e.range.rowEnd}};
        console.log(JSON.stringify(myObj));
        try{
          sh.getRange(2,1).setValue(JSON.stringify(myObj)+ '\n' + myObj.range.getA1Notation());//myObj.range is not a real range object
        }
        catch(m) {
          console.log('Error: ' + m);
        }
        try{
          sh.getRange(3,1).setValue(e.range.getValue());
        }
        catch(n) {
          console.log('Error: ' + n);
        }
      }
    }

如果您适本地编辑 Sheet2,您将获得以下堆栈驱动程序日志:

Stackdriver 日志

May 29, 2020, 1:21:30 PM    Debug   {"source":{},"value":"55","user":{"email":"","nickname":""},"range":{"columnEnd":5,"columnStart":5,"rowEnd":3,"rowStart":3},"authMode":"LIMITED"}
May 29, 2020, 1:21:30 PM    Debug   {"range":{"columnStart":5,"rowStart":3,"columnEnd":5,"rowEnd":3}}
May 29, 2020, 1:21:30 PM    Debug   Error: TypeError: myObj.range.getA1Notation is not a function

注意上面我不能将 myObj.range 与 getA1Notation() 方法一起使用。 (注意:我实际上并没有期望它能够工作......我想知道如何正确构建该对象以便它能够工作,而且我还没有偶然发现正确的解释。

所以我想学习的是如何创建一个伪事件对象,以便我可以使用 myObj.range就像我可以使用 e.range 一样。

田池经历了这么多麻烦之后我感觉很糟糕。但我真正的目标是能够精确地创建服务器创建的事件对象。这样我就可以使用调用 onEdit(e) 的测试函数来测试 onEdit(),而不需要实际编辑。更重要的是,我真的很想知道如何构建这样的对象。

我认为这说明了我的拍摄目的。我想知道如何精确地创建事件对象,因为它是从 onEdit 触发器提供给我们的,包括让 e.range 成为一个相当于 Class Range 的对象,从而能够利用 here 中找到的任何方法。 。我希望这是可能的。我对这些迟来的补充表示歉意,但它们是由田池的一些问题促使的。我可能需要再次查看该问题并使其更清楚。

这是我正在编写的一些代码,它还远未完成,但这是人们在了解我的问题答案后可能会做的事情。

function onXditTest(row) {
  var row=row||2;
  const ss=SpreadsheetApp.getActive();
  const sh=ss.getSheetByName('OnEditTest');
  const v=sh.getRange(row,1,1,sh.getLastColumn()).getValues()[0];
  const xsh=ss.getSheetByName(v[5]);
  const xrg=xsh.getRange(v[0],v[2],v[1]-v[0]+1,v[3]-v[2]+1);
  const evobj={range:{rowStart:v[0],rowEnd:v[1],columnStart:v[2],columnEnd:v[3]},value:v[4],range:xrg,source:ss};
  onXdit(evobj);
}

真正的问题是如何制作 evobj,使 evobj.range 成为 Range 类的对象,同时具有可用的 evobj.range.columnStart、evobj.range.rowStart、evobj.range.columnEnd 和 evobj.range。 rowEnd 以便测试代码在 onEdit(e) 中的行为与在 onXdit(e) 中的行为相同

function onXdit(e) {//changed name so edits dont trigger the function
  e.source.toast('Entry');
  console.log(JSON.stringify(e));
  const sh=e.range.getSheet();
  if(sh.getName()=="Sheet2" && e.range.columnStart==4 && e.value=="TRUE" ) {
    e.source.toast('Past Condition');
    e.range.setValue("FALSE");
  }
}

最佳答案

我相信您的目标如下。

  • 您想要创建一个事件对象,类似于使用 Google Apps 脚本通过 OnEdit 事件触发器返回的事件对象。

对于这个,这个答案怎么样?

我认为 OnEdit 事件触发器的事件对象是从 Google 端的内部服务器返回的。所以我不确定实际的脚本。因此,在这个答案中,我想提出您所说的创建伪事件对象的方法。

在这个答案中,我使用了可与 V8 一起使用的 JavaScript 类。但我不确定这是否是您期望的方向。

示例脚本:

为了使用此脚本,请将以下脚本复制并粘贴到脚本编辑器中,然后保存。然后,请编辑该单元格。这样,onEdit 由 OnEdit 事件触发器运行。

const createEventObject = obj => {
  // Class for creating the range object.
  class createRangeObject {
    constructor(obj) {
      this.columnEnd = obj.columnEnd;
      this.columnStart = obj.columnStart;
      this.rowEnd = obj.rowEnd;
      this.rowStart = obj.rowStart;
    }

    getA1Notation() {
      return SpreadsheetApp
        .getActiveSheet()
        .getRange(this.rowStart, this.columnStart, this.rowEnd - this.rowStart + 1, this.columnEnd - this.columnStart + 1)
        .getA1Notation();
    }

    getSheet() {
      return SpreadsheetApp
        .getActiveSheet();
    }
  }

  // Main script of createEventObject.
  class main {
    constructor(obj) {
      this.obj = obj;
    }

    get range() {
      return new createRangeObject(this.obj);
    }
  }
  return new main(obj);
}

// This function is run by editing cells.
function onEdit(e) {
  // This is your object.
  var myObj={range:{columnStart:e.range.columnStart,rowStart:e.range.rowStart,columnEnd:e.range.columnEnd,rowEnd:e.range.rowEnd}};

  // Create the pseudo event object.
  const obj = createEventObject(myObj.range);

  console.log(obj.range)
  console.log(obj.range.getA1Notation())
  console.log(obj.range.getSheet().getSheetName())
}

结果:

在上面的示例脚本中,例如,当编辑单元格“B3:C5”时,将检索到以下结果。

  • obj.range{ columnEnd: 3, columnStart: 2, rowEnd: 5, rowStart: 3 }
  • obj.range.getA1Notation()B3:C5
  • obj.range.getSheet().getSheetName()Sheet1,它是事件工作表。

注意:

  • 这个答案使用 JavaScript 类,是一种方法。所以我认为可能还有更简单的方法。
  • 这是一个用于解释此解决方法的简单脚本。因此,当您想根据自己的实际情况使用此内容时,请修改此内容。
  • 请将此脚本与 V8 一起使用。

引用:

关于javascript - 在 onEdit 触发器的事件对象中,如何将 range get 同时定义为实际范围对象和属性标识符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62093632/

相关文章:

google-apps-script - 将单元格值中的 Char(10) 带入 Google Sheets 电子邮件中

javascript - 将日期格式从 mm/dd/yy 更改为 dd/mm/yy

javascript - 使用Google脚本从Google表格中的单元格列表中获取数组

google-apps-script - 如何删除数据验证?

javascript - 如何使用XML文档的childNodes?

javascript - for循环中的值错误

javascript - rq 值在 Node js 和 pug 中未定义

javascript - 将每个字符显示为数组的 Map 函数

ios - XML 到对象 Objective-C

javascript - Alexa 提出问题并从外部 API 获得响应