在Google Apps Scripts中将整张纸替换为另一张

时间:2015-03-11 21:34:45

标签: google-apps-script google-sheets

我想要做的是从电子表格中的特定工作表中存储信息,并在每天结束时将其复制到第二个电子表格。第二个电子表格将运行复杂的支点,并根据不需要在一天内运行的复制信息进行报告。

我可以设置一个time-driven trigger,它将在一小时内每天运行作业。

我正在处理以下脚本,该脚本使用SpreadsheetApp.getActiveSpreadsheet来获取当前的电子表格。然后使用spreadsheet.getSheetByName获取要备份的单个工作表。然后使用sheet.copyTo方法将当前工作表添加到新电子表格中。我通过SpreadsheetApp.openById查找ID来获取新的电子表格,如下所示:

function startBackupJob() {

  var currentSpreadSheet = SpreadsheetApp.getActiveSpreadsheet()
  var masterSheet = currentSpreadSheet.getSheetByName("Sheet1")

  var backupSpreadSheetId = "#######################################";
  var backupSpreadSheet = SpreadsheetApp.openById(backupSpreadSheetId);

  // var backupSheet = backupSpreadSheet.getSheetByName("Sheet1");
  // backupSpreadSheet.deleteSheet(backupSheet);

  masterSheet.copyTo(backupSpreadSheet).setName("Sheet1");

}

我遇到的问题是copyTo会创建一个新的工作表,而不是覆盖现有的电子表格。迁移到新工作簿的目的是从数据中运行数据透视表,而不是重新连接它们以指向新工作表。

我可以删除之前的工作表以便为新工作表腾出空间,但是这也会杀死数据透视表上的引用,所以它没有多大帮助。

是否有一种简单的方法可以将一个工作表的全部内容传输到另一个工作表?


这类似于(但不同于)以下问题:


更新

我或许可以通过在每张工作表上调用getRange,然后使用getValuessetValues来执行此操作:

var currentValues = masterSheet.getRange(1, 1, 50, 50).getValues()
backupSheet.getRange(1, 1, 50, 50).setValues(currentValues)

但是我担心主表的可用范围与备份表不同的边缘情况。我也不想在该范围内进行硬编码,但是它要包含整个工作表。如果我调用.getRange("A:E"),则两个工作表必须具有完全相同的行数,这是不可能的。

1 个答案:

答案 0 :(得分:1)

您的更新大约有90%的路径。诀窍是在将数据复制到目标表之前显式检查目标表的大小。例如,如果我做了这样的事情:

var cromulentDocument = SpreadsheetApp.getActiveSpreadsheet();
var masterSheet = cromulentDocument.getSheetByName('master');
var logSheet = cromulentDocument.getSheetByName('log');
var hugeData = masterSheet.getDataRange().getValues();
var rowsInHugeData = hugeData.length;
var colsInHugeData = hugeData[0].length;

/* cross fingers */
logSheet.getRange(1, 1, rowsInHugeData, colsInHugeData).setValues(hugeData);

...那么我的成功完全取决于logSheet是否至少与masterSheet一样大。这是显而易见的,但更不用说如果logSheet 更大那么边缘会留下一些旧垃圾。解精

我们试试别的。和以前一样,我们将获取主数据,但我们也会调整logSheet的大小。如果我们不关心logSheet太大,我们可能只会clear()其中的数据,但让我们保持整洁。

var cromulentDocument = SpreadsheetApp.getActiveSpreadsheet();
var masterSheet = cromulentDocument.getSheetByName('master');
var logSheet = cromulentDocument.getSheetByName('log');
var hugeData = masterSheet.getDataRange().getValues();
var rowsInHugeData = hugeData.length;
var colsInHugeData = hugeData[0].length;

/* no finger crossing necessary */
var rowsInLogSheet = logSheet.getMaxRows();
var colsInLogSheet = logSheet.getMaxCols();

/* adjust logSheet length, but only if we need to... */
if (rowsInLogSheet < rowsInHugeData) {
  logSheet.insertRowsAfter(rowsInHugeData, rowsInHugeData - rowsInLogSheet);
} else if (rowsInLogSheet > rowsInHugeData) {
  logSheet.deleteRows(rowsInHugeData, rowsInLogSheet - rowsInHugeData);
}

/* likewise, adjust width */
if (colsInLogSheet < colsInHugeData) {
  logSheet.insertColumnsAfter(colsInHugeData, colsInHugeData - rowsInLogSheet);
} else if (colsInLogSheet > colsInHugeData) {
  logSheet.deleteColumns(colsInHugeData, colsInLogSheet - colsInHugeData);
}

/* barring typos, insert data with confidence */
logSheet.getRange(1, 1, rowsInHugeData, colsInHugeData).setValues(hugeData);

这里发生的事情非常简单。我们计算出日志需要多大,然后调整目标表的大小以匹配该数据。