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
对应用程序脚本非常陌生,但精通公式,因此需要提高技能。
为了参考我做了一个测试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 中输入
我已经更改了一行(在我的电子表格副本中),以便一个元素实际满足条件并已更新。