Apps脚本不会比较if语句

时间:2018-05-01 11:33:30

标签: javascript if-statement google-apps-script

我创建了一个新项目,它应该将Sheet1中的名称与Sheet2中的名称列表进行比较,并检查该名称是否已在该列表中。为此,我选择了一个for循环来浏览Sheet2中的列表,并将每个列表条目与Sheet1中的名称进行比较。只有当名称已经存在于列表中时才会发生。

function myFunction() {
  var tabSheet1 = 'Sheet1';
  var tabSheet2 = 'Sheet2';

  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet1 = ss.getSheetByName(tabSheet1);
  var sheet2 = ss.getSheetByName(tabSheet2);
  var lastRow1 = sheet2.getLastRow() + 1;
  var playerNameSheet1 = sheet1.getRange(1, 1).getValue();

  for (var j = 1; j < lastRow1; j++) {
    var playerNameSheet2 = sheet2.getRange(j, 1).getValue();
    if (playerNameSheet2 == playerNameSheet1) {
      ...stuff...
    }
  }
}

现在我的问题是,似乎脚本无法识别列表中已存在名称。两个值(playerNameSheet1和playerNameSheet2)完全相同(没有空格或其他隐藏的障碍),但是脚本永远不会继续使用if语句中的内容。我测试我的脚本的示例名称是“Oliver Baumann”。

我对它有点困惑 - 甚至更多,因为稍后在脚本代码中的另一个比较工作得很好。

我已经尝试将运算符更改为===,但这也无效。

if (playerNameSheet2 === playerNameSheet1) {
   ...stuff...
}

我还观察到,如果我在两个变量后面放一个点,我只能用playerNameSheet2选择更多的函数,而不能用playerNameSheet1。也许我做了一个输入错误,我只是太盲目看不到它?我不知道。有人知道如何解决这个问题吗?

可以找到完整的项目here。然而,很多东西都是德语,非常基础。我刚刚启动它,没有时间清理它。所以你不要怀疑。

2 个答案:

答案 0 :(得分:1)

您可能会从更改检查例程中受益 - 目前您所拥有的内容由于slow, repeated对电子表格服务的调用而无法扩展。使用批处理方法 - getValues() - 返回一个Javascript Array,其中包含您希望从“主列表”中获取的所有内容。名字:

// Create an N x 1 array of arrays, e.g. [ [r1c1], [r2c1], [r3c1], ... [rNc1] ],
// of data in column A in sheet2. There will be blanks at the end if other columns have more data.
var allNames = sheet2.getRange(1, 1, sheet2.getLastRow(), 1).getValues();

要检查第一张纸上的名字是否存在,我们可以替换此代码:

for (var j = 1; j < lastRow1; j++) {
  var playerNameSheet2 = sheet2.getRange(j, 1).getValue();
  if (playerNameSheet2 == playerNameSheet1) {
    /* do stuff */

使用此代码(注释j现在从0开始):

for (var j = 0; j < allNames.length; ++j) {
  if (playerNameSheet1 === allNames[j][0]) {
    /* do stuff */

如果您只需要在功能调用中使用名称一次 do stuff(例如,当工作表1名称为时,您不需要执行循环体20次&#34; Bob&#34;并且在表2中有20个&#34; Bob&#34;的实例,您可以使用Array#indexOf方法简化检查allNames的值。首先,必须摧毁&#34; 2D&#34;值数组的数组到一个值数组中。我们想要将一个函数应用于外部数组的每个元素并构造其输出数组,因此我们选择在其上调用Array#map

var db = allNames.map(function (row) { return row[0]; });

我们使用的函数只返回传递元素的第一个元素 - 即第一列中的值,从而产生类似[ r1c1, r2c1, r3c1, ... rNc1 ]的输出。

替换代码是:

if (db.indexOf(playerNameSheet1) === -1) {
  console.log({
    message: "Did not find '" + playerNameSheet1 + "' in database.",
    database: db, original: allNames, searched: playerNameSheet1
  });
  return;
}
/* do stuff */

其中说&#34;如果名称不在表2上,请记录失败的查找,然后退出运行该功能。&#34; 为了促进实际记录,将日志发送到Stackdriver,它将比原始的Logger类保持更长的时间。

如果您的do stuff位使用j索引,您仍然可以获取该索引并使用表2中的相关行:

var index = db.indexOf(playerNameSheet1);
if (index === -1) {
  console.log({
    message: "Did not find '" + playerNameSheet1 + "' in database.",
    database: db, original: allNames, searched: playerNameSheet1
  });
  return;
}
/* do stuff with the user's existing row of data, e.g.

var userDataRow = sheet2.getRange(index + 1, 1, 1, sheet2.getLastColumn()).getValues();
var userData = userDataRow[0];
...
 */

我留给您调查和/或实施的indexOf修改的可能改进是使用Object将名称保存为&#34;键&#34; (对象属性)和相关表单数据的索引(甚至是直接数据)作为键值对的关联值。

答案 1 :(得分:0)

您可以尝试转换数组中的数据并在for循环中进行比较:

  var dataRangeSpieler = sheetSpieler.getDataRange().getValues();
  var dataRangeDBSpiele = sheetDBSpieler.getDataRange().getValues();


  for (i in dataRangeSpieler ) {

    for (j in dataRangeDBSpiele) {

      if (dataRangeSpieler[i][1] == dataRangeDBSpiele[j][0]) {

      Logger.log(dataRangeSpieler[i][1]); //Oliver Baumann

      }
    }

  }