通过 Google Script PT2 求和

问题描述 投票:0回答:1

这是我不久前问过的问题的后续。回答它的人要求我设置一个新问题而不是修改现有问题,所以就这样了。

这是示例文档。本文档共有 5 个选项卡:

  1. 数据集之前 - 这是数据集在处理之前的样子。
  2. 数据集结果(旧)- 这是使用当前脚本处理后数据集的样子。
  3. 数据集结果(新要求)- 这是添加我的新要求后数据集应该是什么样子。
  4. 完成数据 - 这是确定完成状态的数据。
  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");
进行更改,但我不断收到错误。目前这对我来说有点太先进了,我非常感谢您的帮助。

如果我遗漏了任何内容或有任何不清楚的地方,请告诉我,以便我可以编辑我的帖子。谢谢。

google-apps-script
1个回答
0
投票

按照你的情况,作为一个简单的修改,下面的修改怎么样?

修改后的脚本:

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);
}

测试:

当此脚本运行到您提供的电子表格时,将在“数据集之前”表中获得以下结果。

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.