【问题标题】:How can my frozen backup script be improved to avoid timeout?如何改进我的冻结备份脚本以避免超时?
【发布时间】:2019-11-13 00:33:59
【问题描述】:

我有一个可用的冻结备份脚本(如下),但由于行数和公式过多,它会超时。该脚本将创建一个仅包含整个电子表格(或某些工作表)的值(无公式)的冻结备份。我试图通过不将带有公式的工作表复制到新电子表格来改进它,而只复制这些工作表的“冻结”副本。任何帮助/指导将不胜感激。

下面的脚本适用于没有太多行和公式的电子表格。我试图通过使用SpreadsheetApp.create 而不是.copy 来创建一个空白电子表格来修改它,然后尝试想出如何使用.forEach 方法和if 语句来识别_temp 表和只复制它们。我被困了一段时间,因此提出了这个问题。

当前脚本是:

function copyEntireSpreadsheet() {
  var id = "ID"; // Please set the source Spreadsheet ID.

  var ss = SpreadsheetApp.openById(id);
  var srcSheets = ss.getSheets();
  var tempSheets = srcSheets.map(function(sheet, i) {
    var sheetName = sheet.getSheetName();
    var dstSheet = sheet.copyTo(ss).setName(sheetName + "_temp");
    var src = dstSheet.getDataRange();
    src.copyTo(src, {contentsOnly: true});
    return dstSheet;
  });
  var destination = ss.copy(ss.getName() + " - " + new Date().toLocaleString());
  tempSheets.forEach(function(sheet) {ss.deleteSheet(sheet)});
  var dstSheets = destination.getSheets();
  dstSheets.forEach(function(sheet) {
    var sheetName = sheet.getSheetName();
    if (sheetName.indexOf("_temp") == -1) {
      destination.deleteSheet(sheet);
    } else {
      sheet.setName(sheetName.slice(0, -5));
    }
  });
}

上面的脚本超时,因为在新的(复制的)电子表格中处理所有带有公式的单元格需要很长时间,但首先应该不需要复制它们。

以上脚本的工作方式:

  1. 创建所有工作表的副本并重命名并添加 “_temp”。
  2. 使用参数contentsOnly: true 重写每个“_temp”工作表,以便公式变为值。
  3. 创建整个电子表格的副本。
  4. 从源电子表格中删除“_temp”工作表。
  5. 从目标电子表格中删除原始工作表。

我想要完成的是:

  1. 创建所有工作表的副本(“_temp”)并将其自身重写为 摆脱公式。 (以上 1 和 2)
  2. 创建一个空白电子表格(新)
  3. 仅将“_temp”工作表复制到新电子表格中(新)
  4. 删除源电子表格中的“_temp”工作表(以上 4 个)

如果我可以修改它,以便确定应该复制哪些工作表,那就更好了,但是所有 _temp 工作表的简单副本也可以完成这项工作。

提前感谢您的帮助!

最终脚本

@Tanaike 的回答既快速又简单——效果很好!添加了.slice 以从新复制的工作表中删除“_temp”文本。这是寻找类似脚本的任何人的最终脚本:

function copyEntireSpreadsheetTest() {
  var id = "ID"; // Please set the source Spreadsheet ID.

  var ss = SpreadsheetApp.openById(id);
  var srcSheets = ss.getSheets();
  var tempSheets = srcSheets.map(function(sheet, i) {
    var sheetName = sheet.getSheetName();
    var dstSheet = sheet.copyTo(ss).setName(sheetName + "_temp");
    var src = dstSheet.getDataRange();
    src.copyTo(src, {contentsOnly: true});
    return dstSheet;
  });

  var destination = SpreadsheetApp.create(ss.getName() + " - " + new Date().toLocaleString());
  tempSheets.forEach(function(sheet) {
    sheet.copyTo(destination).setName(sheet.getSheetName().slice(0,-5));
    ss.deleteSheet(sheet);
  });
  destination.deleteSheet(destination.getSheets()[0]);
}

【问题讨论】:

    标签: google-apps-script google-sheets


    【解决方案1】:
    • 您想通过修改脚本来实现以下流程。

      1. 创建所有工作表的副本(“_temp”)并自行重写以摆脱公式。 (以上 1 和 2)
      2. 创建一个空白电子表格(新)
      3. 仅将“_temp”工作表复制到新电子表格中(新)
      4. 删除源电子表格中的“_temp”工作表(以上 4 个)

    如果我的理解是正确的,那么这个修改呢?

    发件人:

    var destination = ss.copy(ss.getName() + " - " + new Date().toLocaleString());
    tempSheets.forEach(function(sheet) {ss.deleteSheet(sheet)});
    var dstSheets = destination.getSheets();
    dstSheets.forEach(function(sheet) {
      var sheetName = sheet.getSheetName();
      if (sheetName.indexOf("_temp") == -1) {
        destination.deleteSheet(sheet);
      } else {
        sheet.setName(sheetName.slice(0, -5));
      }
    });
    

    收件人:

    var destination = SpreadsheetApp.create(ss.getName() + " - " + new Date().toLocaleString());
    tempSheets.forEach(function(sheet) {
      sheet.copyTo(destination).setName(sheet.getSheetName());
      ss.deleteSheet(sheet);
    });
    destination.deleteSheet(destination.getSheets()[0]);
    

    参考:

    如果我误解了您的问题并且这不是您想要的结果,我深表歉意。

    【讨论】:

    • 谢谢你,一如既往,Tanaike。这正是我想要完成的。我还将.slice(0, -5) 添加到.setName(sheet.getSheetName() 以在复制后摆脱“_temp”文本,效果很好。干杯!
    • @BearsBeetsBSG 感谢您的回复和其他信息。我很高兴你的问题得到了解决。也谢谢你。
    猜你喜欢
    • 2012-06-27
    • 1970-01-01
    • 1970-01-01
    • 2011-08-22
    • 2020-11-11
    • 2017-07-14
    • 2018-05-03
    • 2017-11-02
    • 2012-11-17
    相关资源
    最近更新 更多