【问题标题】:Apps Script doesn't compare 2 values in if-statementApps 脚本不比较 if 语句中的 2 个值
【发布时间】:2018-05-01 11:33:30
【问题描述】:

我创建了一个新项目,该项目应将 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找到。但是,很多东西都是德语的,而且非常简陋。我刚开始,还没有时间清理它。只是为了让您不要怀疑。

【问题讨论】:

  • 我会检查 playerNameSheet1 是否设置正确:Logger.log(Utilities.formatString("[%s]", playerNameSheet1)) 另外,我会记录每个 playerNameSheet2 以重新检查比较在做什么
  • 您是否尝试在 if 条件之外记录 playerNameSheet2 和 playerNameSheet1 以检查 if 条件失败的原因?
  • @Umair 是的,我已经检查过了。但是,在 tehhowch 的帮助下,我现在完全重复了我的代码,它可以工作了。

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


【解决方案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 */

如果您只需要在函数调用中对名称 once 进行do stuff(例如,当工作表 1 名称为“Bob”时,您不需要执行循环体 20 次,并且第 2 页上有 20 个“Bob”实例),您可以使用 Array#indexOf 方法简化检查 allNames 的值。首先,必须将值数组的“2D”数组折叠成值数组。我们想对外部数组的每个元素应用一个函数并构造一个输出数组,因此我们选择在其上调用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 */

上面写着“如果名称不在工作表 2 上,记录失败的查找,然后退出运行该函数。” 为了促进实际记录,日志被发送到 Stackdriver,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 将名称保存为“键”(对象属性)和索引关联工作表数据(甚至直接数据)作为键值对的关联值。

【讨论】:

    【解决方案2】:

    您可以尝试将数据转换为数组并在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
    
          }
        }
    
      }
    

    【讨论】:

    • stackoverflow.com/questions/500504/… 另外,请注意您使用的不同索引 - 您假设名称位于第一张纸的 B 列和第二张纸的 A 列。
    • 在这种特殊情况下,我认为使用 for ...in 并没有什么特别之处,另外 for...in 在官方 GAS 文章中用作示例:developers.google.com/apps-script/articles/removing_duplicates
    • 仅仅因为他们在那里使用它并不意味着我们必须在这里向新的编码人员和提问者教授它。并非所有文档示例都是由之前被该模式所困扰的编码人员编写的:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-07
    • 1970-01-01
    • 2017-10-01
    • 2019-07-24
    相关资源
    最近更新 更多