为范围内的每个名称创建一个单独的 sheet,并将每个名称下的值移动到每个 sheet

Create a separate sheet for every name in a range and move values under each name to each sheet

我有一个主列表,其中第 2 行有几十个名字,分布在一堆列 (A2:Z2) 中。每个名称下都有一个值和数据列表。

row 2 John Sally James
row 3 Value Value Value
row 4 Value Value Value
row 5 Value Value
row 6 Value Value

每个名字都应该创建成sheet.

这是用于为第 2 行中的每个名称创建 sheet 的脚本:

function generateSheetByName() {
  const ss = SpreadsheetApp.getActive();
  var mainSheet = ss.getSheetByName('Master List');
  const sheetNames = mainSheet.getRange(2, 1, mainSheet.getLastRow(), 1).getValues().flat();
  sheetNames.forEach(n => ss.insertSheet(n));
}

我希望此脚本不仅为每个名称创建一个 sheet,而且还将每个名称下的所有值一直保留到相应列的最后一行。

例如John 在 A2 中,A3:A 是应该传递给创建的 sheet 的值。 Sally 是 B2,B3:B 是应该继承的值。

在 John 的 sheet 中 - “John”是 A1 中的 header,列值位于 A2:A

对于每个 sheet 我还想手动添加其他值。例如,如果创建了“John”sheet,并在 A2:A22 中添加了 20 个值,我希望脚本在 B2:B22 中添加复选框。或者总是在 B1 中添加公式,例如“=counta(a2:a)”或其他内容。

我怎样才能用高效的循环来做到这一点?请注意,这可能会创建 50 sheets 并在每个 sheet

中携带 10-50 个值

示例图片:

主列表:

每个名称都会创建一个 sheet,看起来像这样

约翰的 sheet

我相信你的目标如下。

  • 您想使用 Google Apps 脚本实现从第一张图片到第二张图片。
  • 将值放入创建的 sheet 后,您想要将复选框插入列“B”,并将公式放入单元格“B1”。
  • 您想降低脚本的处理成本。

在这种情况下,下面的示例脚本怎么样?

示例脚本:

在这个示例脚本中,为了减少脚本的处理成本,我使用了Sheets API。使用Sheets API 时,工艺成本可以降低一些。所以,在你使用这个脚本之前,please enable Sheets API at Advanced Google services.

function generateSheetByName() {
  // 1. Retrieve values from "Master List" sheet.
  const ss = SpreadsheetApp.getActive();
  const mainSheet = ss.getSheetByName('Master List');
  const values = mainSheet.getRange(2, 1, mainSheet.getLastRow(), mainSheet.getLastColumn()).getValues();

  // 2. Transpose the values without the empty cells.
  const t = values[0].map((_, c) => values.reduce((a, r) => {
    if (r[c]) a.push(r[c]);
    return a;
  }, []));

  // 3. Create a request body for using Sheets API.
  const requests = t.flatMap((v, i) => {
    const sheetId = 123456 + i;
    const ar = [{ addSheet: { properties: { sheetId, title: v[0] } } }];
    const temp = {
      updateCells: {
        range: { sheetId, startRowIndex: 0, startColumnIndex: 0 },
        fields: "userEnteredValue,dataValidation"
      },
    };
    temp.updateCells.rows = v.map((e, j) => {
      if (j == 0) {
        return { values: [{ userEnteredValue: { stringValue: e } }, { userEnteredValue: { formulaValue: "=counta(a2:a)" } }] }
      }
      const obj = typeof (e) == "string" || e instanceof String ? { stringValue: e } : { numberValue: e }
      return { values: [{ userEnteredValue: obj }, { dataValidation: { condition: { type: "BOOLEAN" } } }] }
    });
    return ar.concat(temp);
  });

  // 4. Request to the Sheets API using the created request body.
  Sheets.Spreadsheets.batchUpdate({requests}, ss.getId());
}

注:

  • 在这个示例脚本中,我使用了您的示例输入和输出情况。所以当这些结构与您的实际情况不同时,脚本可能无法使用。请注意这一点。

参考: