【问题标题】:How do I use a GoogleScript to replace an entire row in a template googlesheet based off of a master googlesheet如何使用 Google 脚本替换基于主 googlesheet 的模板 google sheet 中的整行
【发布时间】:2022-01-31 05:30:28
【问题描述】:

我目前有两张谷歌表格。

  • 1 是一个主表,其中每一行都包含特定于个别学生的信息。
  • 另一个是我希望复制的模板,然后用主表特定行中的信息填充(这样每个学生都会有自己的 googlsheet,其中只有他们的信息。

我遇到的问题是我不知道如何一次导入整行。

我最初的尝试是基于this idea。但是,由于我试图导入大约 1000 个不同的单元格(是的,都在同一行中),因此脚本在为 60 名学生完成脚本之前超时。我认为导入整行而不是使用“createTextFinder”替换所有 1000 个引用会更快。我还读到使用触发器可能是脚本超时的一种解决方法 - 但我也无法弄清楚(还)。我很乐意使用这两种解决方案。 我认为您需要参考的代码部分如下。还有我的主表的this is a copy。 [更新] This 是模板表的副本(请注意,我制作了副本,因此表 ID 与代码不匹配)。

// Loop over the rows
data.forEach((row,i) => {

// Identify whether notification has been sent
if (row[936] === 'send') {


  //Enter collected info into Requirements Template
  const googleSheetTemplate = DriveApp.getFileById('1DZZVZ5y1r5RmP4dMYmZuBQWPzIPp6eVZsdUrrador3o');
  const destinationFolder = DriveApp.getFolderById('10px5WeNyVa9jSNQjCKV9jwcacCDvpByp');

  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Data');

  const copy = googleSheetTemplate.makeCopy(`${row[1]}, ${row[2]}, ${row[938]} Report Card` , destinationFolder);
  const newSheet = SpreadsheetApp.openById(copy.getId());
  const A1 = newSheet.getDataRange();

  for (currentsheet = 0; currentsheet < newSheet.getSheets().length; currentsheet++) {
  const a1 = newSheet.getSheets()[currentsheet].getDataRange();
  A1.createTextFinder("{{StudentEmail}}").replaceAllWith(row[0]);
  A1.createTextFinder("{{FirstName}}").replaceAllWith(row[1]);
  A1.createTextFinder("{{LastName}}").replaceAllWith(row[2]);

【问题讨论】:

  • 关于The issue I'm having is that I can't figure out how to import an entire row all at once.,能否提供googleSheetTemplate的示例电子表格作为图片?而且,在您的情况下,您的脚本工作正常。但是您想降低脚本的处理成本。我的理解正确吗?
  • 感谢您的帮助!我在上面的模板副本中添加了一个链接(因为它全部输入一行,图像只会捕获前几列)。你是对的,我正在尝试降低流程成本,尽管我也可以使用谷歌脚本超时的解决方法。
  • 感谢您的回复。根据您的回复,我提出了一个修改后的脚本作为答案。你能确认一下吗?如果我误解了您的目标并且没有用,我深表歉意。

标签: google-apps-script google-sheets replace


【解决方案1】:

我相信你的目标如下。

  • 您希望降低脚本的处理成本。

修改点:

  • 当我看到您的模板电子表格和源电子表格时,我了解到您希望将源电子表格的一行中的值复制到模板电子表格中。而且,我认为复制行的列顺序在源和模板之间是相同的。在这种情况下,可以使用SpreadsheetApp.create 代替makeCopy。而且,很多createTextFinder也不需要使用。
  • 在您的脚本中,orderBlob 未被使用。所以在这次修改中,我删除了它。
  • 为了放置 URL 和 Spreadsheet Ready 的值,我使用了 Sheets API。

当这些点反映在你的脚本中后,接下来的修改如何?

修改后的脚本:

在使用此脚本之前,please enable Sheets API at Advanced Google services

function sample() {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const sheet = ss.getSheetByName("Data");
  const [, ...data] = sheet.getDataRange().getValues();
  const destinationFolder = DriveApp.getFolderById('10px5WeNyVa9jSNQjCKV9jwcacCDvpByp');
  const values = data.flatMap((row, i) => {
    if (row[936] != 'send') return;
    const newSheet = SpreadsheetApp.create(`${row[1]}, ${row[2]}, ${row[938]} Report Card`);
    newSheet.getSheets()[0].setName("Import Data").appendRow(row);
    DriveApp.getFileById(newSheet.getId()).moveTo(destinationFolder);
    return [
      {values: [[newSheet.getUrl()]],range: `'Data'!${sheet.getRange(i + 1, 939).getA1Notation()}`},
      {values: [["Spreadsheet Ready"]],range: `'Data'!${sheet.getRange(i + 1, 950).getA1Notation()}`}
    ]
  });
  if (values.length == 0) return;
  Sheets.Spreadsheets.Values.batchUpdate({data: values, valueInputOption: "USER_ENTERED"}, ss.getId());
}

参考:

补充:

根据您的以下回复,

脚本的工作方式与您描述的完全一样。很高兴知道我不会发疯。我使用 makeCopy 的原因是因为我想插入公式和条件格式来帮助学生处理数据(想想图形和图表)。我目前正在尝试编辑您的脚本,以使用 makecopy 函数替换电子表格应用程序。我会再次回复,但也可以随时进行编辑。

当你需要使用makeCopy时,下面的示例脚本怎么样?

修改后的脚本:

function sample2() {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const sheet = ss.getSheetByName("Data");
  const [, ...data] = sheet.getDataRange().getValues();
  const googleSheetTemplate = DriveApp.getFileById('1DZZVZ5y1r5RmP4dMYmZuBQWPzIPp6eVZsdUrrador3o');
  const destinationFolder = DriveApp.getFolderById('10px5WeNyVa9jSNQjCKV9jwcacCDvpByp');
  const values = [data[0], data[1]].flatMap((row, i) => {
    if (row[936] != 'send') return;
    const copy = googleSheetTemplate.makeCopy(`${row[1]}, ${row[2]}, ${row[938]} Report Card` , destinationFolder);
    const newSheet = SpreadsheetApp.open(copy);
    newSheet.getSheets()[0].getRange(1, 1, 1, row.length).setValues([row]);
    DriveApp.getFileById(newSheet.getId()).moveTo(destinationFolder);
    return [
      {values: [[newSheet.getUrl()]],range: `'Data'!${sheet.getRange(i + 1, 939).getA1Notation()}`},
      {values: [["Spreadsheet Ready"]],range: `'Data'!${sheet.getRange(i + 1, 950).getA1Notation()}`}
    ]
  });
  Sheets.Spreadsheets.Values.batchUpdate({data: values, valueInputOption: "USER_ENTERED"}, ss.getId());
}

【讨论】:

  • 谢谢!该脚本的工作方式与您描述的完全一样。很高兴知道我不会发疯。我使用 makeCopy 的原因是因为我想插入公式和条件格式来帮助学生处理数据(想想图形和图表)。我目前正在尝试编辑您的脚本以用 makecopy 函数替换电子表格应用程序。我会再次回复,但也可以随意进行编辑。再一次 - 我不能说谢谢!
  • @Matt 感谢您的回复。我带来的不便表示歉意。为了您的回复,我在回答中又添加了一个示例脚本。你能确认一下吗?如果我误解了您的回复,我再次道歉。
  • 你太棒了,没有必要道歉!这行代码: Sheets.Spreadsheets.Values.batchUpdate({data: values, valueInputOption: "USER_ENTERED"}, ss.getId());给我一条错误消息,指出“工作表”未定义。我还意识到,如果我将 URL 填充到另一个单元格中,我可以使用第二个脚本将 URL 直接通过电子邮件发送给学生。我设法修复了所有错误并获得了一个工作脚本。我不确定如何在评论中发布链接,但我已经在上面发布的示例表中编辑了脚本以显示最终的工作代码。谢谢!
  • @Matt 感谢您的回复。关于Gives me an error message that says that "sheets" is undefined.,我认为您的问题的原因是您从未在高级 Google 服务中启用 Sheets API。但我很高兴你的问题得到了解决。如果您的问题得到解决,请按接受按钮。与您有相同问题的其他人也可以将您的问题作为可以解决的问题。我认为您的问题和解决方案将对他们有用。如果找不到按钮,请随时告诉我。 stackoverflow.com/help/accepted-answer
  • 啊——我相信你是对的!我分心了,忘了启用它!再次感谢您的帮助 - 试图找出接受按钮现在的位置:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-03-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多