Google apps script 在google工作表中简化重复公式计算
摘要选项卡包含项目名称,该名称是“我的谷歌工作表”中剩余选项卡名称的名称,如下所示: 标签名 项目1 项目2 项目3Google apps script 在google工作表中简化重复公式计算,google-apps-script,google-sheets,google-sheets-formula,Google Apps Script,Google Sheets,Google Sheets Formula,摘要选项卡包含项目名称,该名称是“我的谷歌工作表”中剩余选项卡名称的名称,如下所示: 标签名 项目1 项目2 项目3 我相信你的目标如下 您希望使用GoogleApps脚本实现以下情况。(以下结果来自我的示例脚本。) 从 到 在这种情况下,我想提出以下流程 从“摘要”工作表中检索工作表名称 从每个项目工作表中检索值,并创建用于创建结果值的对象 创建一个结果值,用于放入“每周”工作表 将结果值放入“每周”工作表 当上述流程反映到脚本中时,它将变成如下所示 示例脚本: 当这个示例
我相信你的目标如下
- 您希望使用GoogleApps脚本实现以下情况。(以下结果来自我的示例脚本。)
- 从
- 到
- 当这个示例脚本用于您的示例电子表格时,可以获得我在上面图像中显示的结果
- 当我看到您更新的样本电子表格,包括您期望的结果表时,我注意到“每周”表的第一行是空的。当我在您更新之前第一次看到您的示例电子表格时,“每周”工作表的第一行是标题行。所以我把这个弄糊涂了。在这个示例脚本中,我将其设置为“每周”工作表的第一行是标题行。请小心这个
- 此外,此示例脚本适用于您的示例电子表格。因此,如果您的实际情况的每张表的结构与示例电子表格不同,则可能无法使用脚本。请注意这一点。
- 因此,请使用示例电子表格测试示例脚本
- 一是“周报”的第一行不是空的
- 另一个原因是“每周”工作表的第一行是空的
为了正确了解您目前的情况,能否提供电子表格样本?感谢您添加更多信息。我可以看到你的电子表格样本。为了确认您的目标,您能否使用示例电子表格添加您期望的输出情况?因为我不确定我是否能正确理解实现你目标的逻辑。这是因为我的英语水平差。对此我深表歉意。链接是包含在每周选项卡中的SUMPRODUCT和间接公式的文件。这是实际公式的一个更短更简单的版本。例如,项目文件将包含表示远程工作的Y的附加列。我会把它分成两行,在开头加上记号。例如,如果Joe在2月8日在项目2上工作,如果他在项目2上的5天是3天远程工作,2天在现场工作,那么预期结果将是项目2(2)新线R项目2(3)新线项目3(2)。预期结果可以通过公式计算在那里看到。我想把这个重复的公式转换成一个应用程序脚本,这样我的电子表格运行得更快。它至少比以前慢了20倍,比如一秒,现在是20到30秒。谢谢你,塔奈卡。当我运行脚本时,我在第29行和第30行收到一个错误,上面写着“TypeError:h.toISOString不是函数”。@Joyce Brown感谢您的回复。给您带来不便,我深表歉意。现在,我为“每周”工作表的第一行为空的情况又添加了一个脚本。你能确认一下吗?如果这不是您当前问题的直接解决方案,请提供您当前的电子表格,包括用于复制您的问题的当前脚本。我想确认一下,你好,塔奈克。非常感谢你。我能够执行脚本,每周选项卡上的结果正是我所期望的。我将详细查看您的代码。我需要尝试修改您的脚本以考虑两列—Remote,它是资源名称之前的第一列,Cost,它是资源名称之后的列。远程时间需要分开,在TabName前面用R表示。另外,还有3个表使用相同的项目选项卡来获取信息。第二个表适用于所有时间,与第一个表类似,但前面没有文本。第三个表仅适用于远程列没有Y(即空/空)的情况。最后一个表是所有项目的成本,但选项卡名以_FP结尾或选项卡名中有SaaS文本的项目除外。计算所有非远程时间的成本乘以成本。我的示例电子表格是。
function myFunction() {
// 1. Retrieve sheet names from "Summary" sheet.
const ss = SpreadsheetApp.getActiveSpreadsheet();
const summarySheet = ss.getSheetByName("Summary");
const sheetNames = summarySheet.getRange("A2:A" + summarySheet.getLastRow()).getValues();
// 2. Retrieve values from each project sheet and create an object for creating result values.
const obj = sheetNames.reduce((o, s) => {
const [[, ...header], ...values] = ss.getSheetByName(s).getDataRange().getValues();
header.forEach((h, i) => {
const k = h.toISOString();
if (o[k]) {
values.forEach(v => {
if (v[i + 1].toString() != "") o[k][v[0]] = (o[k][v[0]] ? `${o[k][v[0]]}\n` : "") + `${s} (${Number(v[i + 1])})`;
});
} else {
o[k] = values.reduce((o2, v) => {
if (v[i + 1].toString() != "") o2[v[0]] = `${s} (${Number(v[i + 1])})`;
return o2;
}, {});
}
});
return o;
}, {});
// 3. Create an result values for putting to "Weekly" sheet.
const weeklySheet = ss.getSheetByName("Weekly");
const [[, ...header], ...values] = weeklySheet.getDataRange().getValues();
const tempValues = header.reduce((ar, h) => {
const k = h.toISOString();
const temp = [];
if (obj[k]) {
values.forEach(([v]) => temp.push(obj[k][v] || ""));
ar.push(temp);
}
return ar;
}, []);
const res = tempValues[0].map((_, j) => tempValues.map(row => row[j]));
// 4. Put the result values to "Weekly" sheet.
weeklySheet.getRange(2, 2, res.length, res[0].length).setValues(res);
}
const [[, ...header], ...values] = weeklySheet.getDataRange().getValues();
const tempValues = header.reduce((ar, h) => {
const k = h.toISOString();
const temp = [];
if (obj[k]) {
values.forEach(([v]) => temp.push(obj[k][v] || ""));
ar.push(temp);
}
return ar;
}, []);
const res = tempValues[0].map((_, j) => tempValues.map(row => row[j]));
// 4. Put the result values to "Weekly" sheet.
weeklySheet.getRange(2, 2, res.length, res[0].length).setValues(res);
const [,[, ...header], ...values] = weeklySheet.getDataRange().getValues(); // Modified
const tempValues = header.reduce((ar, h) => {
const k = h.toISOString();
const temp = [];
if (obj[k]) {
values.forEach(([v]) => temp.push(obj[k][v] || ""));
ar.push(temp);
}
return ar;
}, []);
const res = tempValues[0].map((_, j) => tempValues.map(row => row[j]));
// 4. Put the result values to "Weekly" sheet.
weeklySheet.getRange(3, 2, res.length, res[0].length).setValues(res); // Modified