Google Sheet 应用脚本:将两个值从一个 sheet 匹配到另一个 sheet,然后设置一个值(如果它们匹配)

Google Sheet App Script: Match two values from one sheet to another sheet and then set a value if they match

对应用程序脚本非常陌生,但精通公式,因此需要提高技能。

为了参考我做了一个测试sheetHERE

我的脚本一直是教程的科学怪人,但本质上我试图将 sheet 2 中的名称和日期与 sheet 1 中的数据匹配,如果它们匹配,则在列中“ C”我想将值设置为“已发送”

这是我到目前为止尝试过的方法:

    function sendReport() {
  var ss = SpreadsheetApp.getActiveSpreadsheet()
  var clientName = ss.getRange ("Sheet2!B1");
  var testDate = ss.getRange ("Sheet2!B2")
  var destSheet = ss.getSheetByName("Sheet1");
  var range = destSheet.getDataRange();
  var values = range.getValues();
  for(var i = 1; i < values.length; i++){

    if (values[i][1] == clientName
        && values[i][2] == testDate) {
      values[i][3] = Yes; 
}
range.setValues(values)
  }

实际 sheet 相当大,它似乎一次检查每一行,因为脚本需要很长时间才能 运行 但它没有添加“是”值进入专栏以确认报告已发送。

非常感谢任何帮助。

您可以使用以下脚本

function sendReport() {
  Logger.log("Starting script...");
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  // you need to get the actual sheets of the array
  // you can use array destructuring (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment) for this
  const [sheet1, sheet2] = ss.getSheets(); // getSheets() returns an array of sheets
  // get ranges from sheet 2
  // no need to provide the sheet name as a parameter, because we're calling it on sheet2 already
  const clientName = sheet2.getRange("B1").getDisplayValue(); // you need to get the display value, not just the range
  const testDate = sheet2.getRange("B2").getDisplayValue(); 

  // start in row 2, column 1 and get all rows expect the first (=> last - 1) and get 3 columns
  const range = sheet1.getRange(2, 1, sheet1.getLastRow() - 1, 2);
  // use forEach() and array destructuring again here. 
  // the second parameter idx is a zero-based index we need to set the value of column sent 
  range.getDisplayValues().forEach(([name, date, sent], idx) => {
    // Use JavaScript strict comparison with === instead of ==
    // check if name and date match and sent is not already set to "sent"
    Logger.log(`Comparing name ${name} with ${clientName} and date ${date} with ${testDate}...`);
    if(name === clientName && date === testDate && sent !== "sent") {
      // we need to use idx + 2 because line 1 is the heading and idx of forEach() is zero-based but Spreadsheet API is one-based
      Logger.log(`Ìn row ${idx + 2} name and date match! Setting "sent"...`);
      sheet1.getRange(idx + 2, 3).setValue("sent");
    }
  })
  // set value "report sent" on sheet2  to "sent"
  sheet2.getRange("B3").setValue("sent")
  Logger.log("Report sent.")
}

关于您的代码的一些提示。

  • 您需要在 Range 上使用 getValue()getDisplayValue() 获取实际值才能获得这些值。
  • 你可以使用 destructuring 这将比一直处理索引更方便和更易读
  • 您应该使用 forEach 或其他 JavaScript 数组方法来遍历数组
  • JavaScript 有多个比较运算符。你应该使用 strict equality operator === whenever possible as this also takes data types into account in contrast to the normal equality operator ==
  • 您可以使用 Logger.log() 在脚本执行时向控制台打印一些内容
  • 每次您不打算更改变量值时尝试使用 const 变量而不是 var。最好的做法是完全不更改值,而是将它们视为 immutable,因为这样可以避免很多错误。

输入

在工作表 1 中输入

我已经更改了一行(在我的电子表格副本中),以便一个元素实际满足条件并已更新。

在工作表 2 中输入

结果

输出工作表 1

输出工作表 2