如何使用Google Apps脚本在复制的数据范围旁边添加公式?

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

我无法理解数组,但我知道我需要做的就是解决我的问题。目前,我正在将我需要的数据从另一个工作表复制到选项卡上,复制该数据表,然后将其粘贴到该工作表上的另一个选项卡中。我现在需要在最终生成的数据的末尾添加另一列,该数据是相邻的每个单元格中的公式,即从AP2开始的列AP。这是脚本:

function CopyDataToNewFile() {
  var sss = SpreadsheetApp.openById('some id');
  var ss = sss.getSheetByName('Outcome'); // ss = source sheet
  var destination = SpreadsheetApp.openById('other id');
  var target = destination.getSheetByName('Final');

  ss.copyTo(destination);

  var data = destination.getSheetByName('Copy of Outcome');
  var infoTable = data.getRange(2, 1, data.getLastRow(), data.getLastColumn());
  var lastRow = target.getLastRow();

  infoTable.copyTo(target.getRange(lastRow + 1, 1), {contentsOnly: true});

  destination.setActiveSheet(destination.getSheetByName('Copy of Outcome'));
  destination.deleteActiveSheet();
}

我想要附加每个复制行的公式如下:

'=vlookup($I2, IMPORTRANGE("https://docs.google.com/spreadsheets/d/<yet another id>/edit#gid=1203869430", "Source_Hours!A:B"), 2, false)'

这是我试图这样做的方式:

 function CopyDataToNewFile() {
      var sss = SpreadsheetApp.openById('some id');
      var ss = sss.getSheetByName('Outcome'); // ss = source sheet
      var destination = SpreadsheetApp.openById('other id');
      var target = destination.getSheetByName('Final');


  ss.copyTo(destination);

  var data = destination.getSheetByName('Copy of Outcome');
  var infoTable = data.getRange(2, 1, data.getLastRow(), data.getLastColumn());
  var lastRow = target.getLastRow();

  infoTable.copyTo(target.getRange(lastRow + 1, 1), {contentsOnly: true});


 target.getRange(2,infoTable.getLastColumn()+1,infoTable.getLastRow(),1).setFormula('=vlookup($I2,IMPORTRANGE("https://docs.google.com/spreadsheets/d/1f7_unFqRkI6O2EHBLsNGLRCH5j9rlEXBdVnRLTgS_lM/edit#gid=1203869430","Source_Hours!A:B"),2,false)');


  destination.setActiveSheet(destination.getSheetByName('Copy of Outcome'));
  destination.deleteActiveSheet();
}

它在我第一次运行脚本时工作,但是下次运行它时,它不会在最后一列中添加公式。我不是程序员,只知道危险。 :)

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

你的解决方案很接近。我推荐的方法是创建对脚本将复制到的第一行的引用--target.getLastRow() + 1 - 然后将此引用用于数据表副本和公式写入。您的脚本也有一个可能的问题,因为您认为工作表名称始终是"Copy of Outcome" - 这并不是严格保证为真(考虑复制工作表两次而不删除第一个副本)。而是绑定Sheet#copyTo的返回值,因为它是新创建的工作表副本。以这种方式,复制的工作表的名称是无关紧要的 - 脚本不需要它按预期运行。

function CopyDataToNewFile() {
  const source = SpreadsheetApp.openById('some id').getSheetByName('Outcome');
  const destination = SpreadsheetApp.openById('other id');
  const target = destination.getSheetByName('Final');
  if (!source || !target)
    throw new Error("Missing required worksheets (sheet names not found)");

  // Copy the source sheet and get a reference to the copy.
  var datasheet = source.copyTo(destination);
  var infoTable = datasheet.getRange(2, 1, datasheet.getLastRow(), datasheet.getLastColumn());

  // Copy the table contents to the end of the target sheet.
  // Determine the first row we are writing data into.
  const startRow = target.getLastRow() + 1;
  infoTable.copyTo(target.getRange(startRow, 1), {contentsOnly: true});
  // Set a column formula in the adjacent column.
  target.getRange(startRow, 1 + infoTable.getNumColumns(), infoTable.getNumRows(), 1)
    .setFormula("some formula");

  // Remove the intermediate sheet.
  destination.deleteSheet(datasheet);
}

使用的新功能:

另一种方法是使用JavaScript数组来限制所使用的Spreadsheet Service方法的数量,因为您似乎只希望传输值。这利用了链接,因为Range#setValues返回对写入范围的引用。这假设源表上的值“结果”不依赖于工作簿。如果“结果”具有引用同一工作簿中的其他工作表的公式,则自然这将不起作用,因为值将引用原始工作簿,而不是目标工作簿。

  ...
  const dataToCopy = source.getDataRange().getValues();
  dataToCopy.shift(); // remove header row.
  const startRow = target.getLastRow() + 1;
  const numRows = dataToCopy.length;
  const numColumns = dataToCopy[0].length;
  target
    .getRange(startRow, 1, numRows, numColumns)
    .setValues(dataToCopy)
    .offset(0, numColumns, numRows, 1) // offset is from the top-right cell of the range
    .setFormula("some formula");
}
© www.soinside.com 2019 - 2024. All rights reserved.