将文档属性中的数组与数据范围进行比较不起作用。

3
我有一个脚本(Google Apps Script),从我的表格中提取数据(对,包括缩写和百分比),这个表格的数值是不断变化的(有时每周变化,有时每日变化)。脚本应该检查旧值与新值,并只处理新值,但由于某种原因它正在处理所有值。
在循环过程中,它首先找到与该单元格相关的电子邮件,然后向该人发送生成的电子邮件。最后,将新的值存储在之前找到的值上方。
获取新数据和变量。
var data = dataRange.getValues(); // Fetch values for each row in the Range.
    var oldData = [{}];
    //Declare variable

从文档属性获取旧数据。
var oldValues = PropertiesService.getDocumentProperties().getProperties();
//get values from document properties 
var outerArrayOldData = [];
//empty array
var arr4 = [];
//empty array
var thisLoopString,
    thisRowArray;
for (var key in oldValues) {
    //grabbing keys from document properties 'row[i]' and loop for each
    thisLoopString = oldValues[key];
    thisRowArray = []; //Reset
    array
    thisRowArray = thisLoopString.split(","); //Convert the string to partial array
    arr4.push(thisRowArray); //Push the inner array into the outer array

    outerArrayOldData = arr4.concat(outerArrayOldData); //convert outer to actual usable array
    var arr4 = []; //reset arr4 back to 0
};

//End getting old data

比较旧数据和新数据。
    var oldData = outerArrayOldData;
    var source = oldData.map(function (row) {
            return JSON.stringify(row);
            //map array to string
        }),
        searchRow,
        dataLength = data.length;
    for (i = 0; i < dataLength; i += 1) {
        searchRow = JSON.stringify(data[i]);
        if (source.indexOf(searchRow) == -1) {
            //search old data and compare to new data using index search and if data isn't in old stack process it through functions

                //doing stuff with new pairs
            }
        }
    }
}

如何将旧数据存储到文档属性中。
    var objOldData = {};
    //empty
    var keyName = "",
        //empty
        thisRowArray;
    for (i = 0; i < data.length; i++) {
        keyName = "row" + (i).toString();
        //set keys
        thisRowArray = data[i].toString();
        //convert each pair array to string
        if (thisRowArray == "") continue;
        //skip blanks

        objOldData[keyName] = thisRowArray;
        //add keys and values to properties as a string
    }
    PropertiesService.getDocumentProperties().setProperties(objOldData,
        true); //true deletes all other properties
    //Store the Updated/New Values back to Properties

}

日志控制台:

<<<<<<<<Imported Range data>>>>>>>>
[[BBB, 0.9], [CCC, 0.76], [DDD, 0.89], [, ]]

<<<<<<<<Old data from dpcument properties>>>>>>>>
[[DDD, 0.89], [, ], [BBB, 0.9], [CCC, 0.76]]


<<<<<Processing New Values Not in Old Data>>>>>
[CCC, 0.76]
[BBB, 0.9]
[DDD, 0.89]

 <<<<<<<<Store the Updated/New Values back to Properties>>>>>>>>
 {row1=CCC,0.76, row0=BBB,0.9, row3=,, row2=DDD,0.89}

正如您所看到的,即使这些值已经存在于系统中且不是新的,它仍在处理所有值。为什么搜索没有发现它们已经存在?我在哪里出了问题?


4
如果你将问题简化到最小限度以证明它,会更有帮助。发布超过100行没有注释的代码会给那些想要回答的人带来困难。 - RobG
记录器控制台输出对我来说看起来太杂乱了,所以我没有注意它。很抱歉。 - Rubén
@Runén 对不起,我的错。我没有像应该做的那样清理它。 - hakarune
@Sujay searchRow和dataLength没有传递到source。source只是要搜索的旧数据字符串。 - hakarune
这是来自 @Sujay 的记录器的输出:source:[["DDD","0.89"],["",""],["BBB","0.9"],["CCC","0.76"]] && searchRow: undefined && DataLength: 4.0 - hakarune
显示剩余7条评论
2个回答

1
我很难理解你的代码,因此我自己创建了一个:

var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1");
var data = {};

function getData() {

  var range = sheet.getRange("A1:B3");
  var values = range.getValues();

  for (var i=0; i < values.length; i++) {

    var key = 'row' + i;
    var currentRow = values[i];

    // for each cell value,
    //   toString : convert to string
    //   trim     : remove all whitespaces from both ends of cell values
    //   encode…  : encode the values so we don't have any ","
    var arr = currentRow.map(function(v){return encodeURIComponent(v.toString().trim())});

    // join the array with "," delimiter
    var s = arr.join();

    data[key] = s;
  }  
} // getData()

function saveData() {
  getData();
  PropertiesService.getDocumentProperties().setProperties(data);
}

function compareData() {
  getData();
  var props = PropertiesService.getDocumentProperties().getProperties();
  for (var idx in props) {
    if (idx in data) {
      if (data[idx] != props[idx]) {
        Logger.log('\n%s is different\nOld value is "%s"\nNew value is "%s"',
                   idx,
                   decodeURIComponent(props[idx]),
                   decodeURIComponent(data[idx]));
      }
    } else {
      Logger.log('missing row: ' + idx);
    }
  }  
}

// Test function. Check all document properties
function peekProperties() {
 var props = PropertiesService.getDocumentProperties().getProperties();
 for (var idx in props) {
   Logger.log('%s = %s', idx, props[idx]);
 }
}

问题:如果删除一行,key 不应该是 A 列中的值而不是行号吗?


1
在您的“将旧数据与新数据进行比较”的循环代码中,尝试更改:

searchRow = JSON.stringify(data[i]);

到:

searchRow = JSON.stringify([data[i][0], data[i][1].toString()]);

这样可以确保第二个数组索引处的值始终被转换为字符串,以便与“旧”导入值进行比较,后者似乎是从作为字符串传递的行中解析出来的。
目前看起来,使用第二个值为数字(或者可能是null或空值)声明的新数据数组值:
 [["BBB", 0.9], ["CCC", 0.76], ["DDD", 0.89], ["",""]];

在将从Google文档导入的“旧”行导入并转换为数组时,其中值为字符串:

 [["CCC","0.76"],["BBB","0.9"],["",""],["DDD","0.89"]]

在使用JSON.stringify比较行时,例如'["DDD","0.89"]'与'["DDD",0.89]'不匹配,因此所有行都会被错误地注册为“new”。我从你的例子中猜测了一些内容,但这可能是你的bug的原因。祝你好运!

哇!谢谢你!我甚至没有看到那个差异。这个小改变完美地解决了它。现在它百分之百地工作,十次运行都是完美的。 - hakarune

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接