这是我不久前问过的问题的后续。回答它的人要求我设置一个新问题而不是修改现有问题,所以就这样了。
这是示例文档。本文档共有 5 个选项卡:
这是我目前拥有的:
// This is from your provided Spreadsheet.
const obj = [
{ name: "Dataset Before", range: "A2:A" },
{ name: "Completion Data", range: "A2:C" },
{ name: "Settings", range: "E5:I" }
];
// 1. Retrieve values and ranges from 3 sheets.
const ss = SpreadsheetApp.getActiveSpreadsheet();
const [sheet1, sheet2, sheet3] = obj.map(({ name, range }, i) => {
obj[i].sheet = ss.getSheetByName(name);
obj[i].range = obj[i].sheet.getRange(range + obj[i].sheet.getLastRow());
obj[i].values = obj[i].range.getValues();
if (i == 1) {
// For "Completion Data" sheet.
// Create an object for searching values.
obj[i].values = obj[i].values.reduce((o, [a, b, c]) => {
if (c == "Completed") {
o[b] = o[b] ? { ...o[b], [a]: c } : { [a]: c };
}
return o;
}, {});
} else if (i == 2) {
// For "Settings" sheet.
// Transpose the retrieved values.
obj[i].len = obj[i].values[0].length;
obj[i].values = obj[i].values[0].map((_, col) => obj[i].values.map((row) => row[col]));
}
return obj[i];
});
// Create an array for putting into the destination range by follwoing your logic.
const values = sheet1.values.map(([a]) => {
if (sheet2.values[a]) {
return sheet3.values.map(e => e.some(f => sheet2.values[a][f]) ? "Completed" : "Incomplete");
}
return Array(sheet3.len).fill("Incomplete");
});
// Put the values to the destination range.
sheet1.sheet.getRange(2, 2, values.length, values[0].length).setValues(values);
}
目前该脚本可以实现我想要的效果,并且在大约 40 秒内完成。与我之前相比,真的很快。它会在“完成数据”选项卡上搜索人员的 ID,如果状态显示“已完成”,则返回“已完成”;如果返回任何其他状态,则返回“未完成”。
新要求: 我现在需要它来带回与“已完成”一词相连的完成日期,例如
Completed (04/24/2024)
,或者如果状态显示“已注册”,则带回 Incomplete (Enrolled)
,否则只是 Incomplete
。
不幸的是,对我来说,我并没有完全理解这个脚本中发生了什么来进行我想要的调整。我尝试使用我现有的知识自己从头开始创建一些东西,但它涉及循环中的循环,每列花费超过 15 分钟。执行时间不允许这一切完成。
当尝试调整上面的代码时,我最好的猜测是对
return sheet3.values.map(e => e.some(f => sheet2.values[a][f]) ? "Completed" : "Incomplete");
进行更改,但我不断收到错误。目前这对我来说有点太先进了,我非常感谢您的帮助。
如果我遗漏了任何内容或有任何不清楚的地方,请告诉我,以便我可以编辑我的帖子。谢谢。
按照你的情况,作为一个简单的修改,下面的修改怎么样?
function myFunction() {
// This is from your provided Spreadsheet.
const obj = [
{ name: "Dataset Before", range: "A2:A" },
{ name: "Completion Data", range: "A2:D" },
{ name: "Settings", range: "E5:I" }
];
// 1. Retrieve values and ranges from 3 sheets.
const ss = SpreadsheetApp.getActiveSpreadsheet();
const [sheet1, sheet2, sheet3] = obj.map(({ name, range }, i) => {
obj[i].sheet = ss.getSheetByName(name);
obj[i].range = obj[i].sheet.getRange(range + obj[i].sheet.getLastRow());
obj[i].values = obj[i].range.getDisplayValues();
if (i == 1) {
// For "Completion Data" sheet.
// Create an object for searching values.
obj[i].values = obj[i].values.reduce((o, [a, b, c, d]) => {
if (c == "Completed") {
o[b] = o[b] ? { ...o[b], [a]: `${c} (${d})` } : { [a]: `${c} (${d})` };
} else if (c == "Enrolled") {
o[b] = o[b] ? { ...o[b], [a]: `Incomplete (${c})` } : { [a]: `Incomplete (${c})` };
}
return o;
}, {});
} else if (i == 2) {
// For "Settings" sheet.
// Transpose the retrieved values.
obj[i].len = obj[i].values[0].length;
obj[i].values = obj[i].values[0].map((_, col) => obj[i].values.map((row) => row[col]));
}
return obj[i];
});
// Create an array for putting into the destination range by following your logic.
const values = sheet1.values.map(([a]) => {
if (sheet2.values[a]) {
return sheet3.values.map(e => {
const k = e.find(f => sheet2.values[a][f])
return k ? sheet2.values[a][k] : "Incomplete";
});
}
return Array(sheet3.len).fill("Incomplete");
});
// Put the values to the destination range.
sheet1.sheet.getRange(2, 2, values.length, values[0].length).setValues(values);
}
当此脚本运行到您提供的电子表格时,将在“数据集之前”表中获得以下结果。