对照新数据检查旧数据,仅处理工作表上 google 应用脚本中的实际更改值

Checking old data against new and only processing actual changed values in google app scripts on sheets

我有一个 sheet 从另一个 sheet 抓取信息并将其组织成 3 sheets (70%, 80%, 90%)。我当前的 onChange 脚本可以工作,但只要任何单元格发生任何变化都会触发,而不仅仅是客户端的百分比发生变化时;目前我收到了很多重复的电子邮件,其中包含相同的信息。有没有办法存储以前的行值并检查它们并只处理新的内容?

这就是我正在尝试的方法,但脚本调试器不断返回 TypeError: Cannot read property "1" from undefined. (line 12, file "Code")。我知道这是因为 oldData 目前是空的,我不知道该怎么做才能让它发挥作用。如果有人可以提供帮助或至少为我指出更好的方法,那将是一个很大的帮助。

function notification70() {
    var ss = SpreadsheetApp.getActiveSpreadsheet();
    var sheet = ss.getSheets()[0]; //”0″ is the first sheet
    var startRow = 2; // First row of data to process-actual row# (this is cell A1)
    var numRows = 10; // Number of rows to process (goes from A1-A10)
    var dataRange = sheet.getRange(startRow, 1, numRows, 3) //set range
    var formats = dataRange.getNumberFormats(); //get the format style of the cells
    dataRange.setNumberFormats(formats); //set the format of the array to the same as the data (currently not working)
    var data = dataRange.getValues(); // Fetch values for each row in the Range.
    for (i in data) {
        var row = data[i]; //convert data to var to row for easier memory on what I'm writing
        if (row[i] = oldData[i]) continue; //if current data percentage = the previous then skip
        var emailAddress = "email@email.com"; // Email
        var percent = row[1]*100; //convert to % value
        var percentage = parseFloat(percent).toFixed(2); //cut to 2 decimal points
        var message = "You have now reached 70% of your time for " + row[0] + ". You are currently at " + percentage + "% for " + row[0] + ". Keep up the good work."; // emails the information for the row schanged
        var subject = "You have reached 70% of the time for " + row[0] + ". #Notification"; //email subject

        if (percent != 0) Logger.log(emailAddress + "\n" + subject + "\n" + message); //log the output for testing

    }
   var oldData = data //update/save current values for next script run
}

sheet 数据看起来像这样,并且会:

      Client   |     Percentage   |        Date
   ---------------------------------------------------
      BBB      |      78.19%      |      1/18/2016
   ---------------------------------------------------
      DDD      |      79.63%      |      1/18/2016
   ---------------------------------------------------
      FFF      |      74.54%      |      1/18/2016
   ---------------------------------------------------
      KKK      |      72.30%      |      1/18/2016
   ---------------------------------------------------
      MMM      |      71.47%      |      1/18/2016
   ---------------------------------------------------
      PPP      |      73.39%      |      1/18/2016

谢谢大家的帮助^_^

对于错误:add var oldData = [];在 for 循环之前定义它。

将 "old data" 放入文档属性中。要么,要么为 "old data" 创建一个新的 sheet 选项卡。您似乎没有获得那么多数据,因此它可能适合文档属性的 属性。

function storeRowsOfData(data) {

  var objOldData = {};
  var keyName = "",
      thisRowArray;

  for (var i=0;i<data.length;i+=1) {
    keyName = "row" + (i+2).toString();
    thisRowArray = data[i].toString();

    objOldData[keyName] = thisRowArray;
  };

  PropertiesService.getDocumentProperties().setProperties(objOldData, true); //true deletes all other properties
};

如果您不删除所有其他属性,并且当前操作中行的长度小于上一个,您会从旧数据中遗留行。如果您没有将文档属性用于其他任何用途,并且没有使用文档属性的 Add-on,那么您会没事的。

代码:

function getRowsOfOldData() {
  var oldValues = PropertiesService.getDocumentProperties().getProperties();

  var outerArrayOldData = [];
  var thisLoopString,
      thisRowArray;

  for (var key in oldValues) {
    thisLoopString = oldValues[key];
    thisRowArray = []; //Reset
    thisRowArray = thisLoopString.split(","); //Convert the string to an array

    outerArrayOldData.push(thisRowArray);//Push the inner array into the outer array
  };

  Logger.log('outerArrayOldData: ' + outerArrayOldData);
};

获取数据的函数,将所有数据放回一个二维数组中。这就是它的原始形式。将数据放入文档属性的函数,并没有将所有数据放入一个属性,而是放入多个属性。当将某些内容放入文档属性时,它会转换为字符串。您不能将数据存储为文档属性中的数组或对象。而且,将每一行放入它自己的 属性 中可以避免每个 属性 设置的数据限制问题。