我无法理解数组,但我知道我需要做的就是解决我的问题。目前,我正在将我需要的数据从另一个工作表复制到选项卡上,复制该数据表,然后将其粘贴到该工作表上的另一个选项卡中。我现在需要在最终生成的数据的末尾添加另一列,该数据是相邻的每个单元格中的公式,即从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();
}
它在我第一次运行脚本时工作,但是下次运行它时,它不会在最后一列中添加公式。我不是程序员,只知道危险。 :)
你的解决方案很接近。我推荐的方法是创建对脚本将复制到的第一行的引用--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);
}
使用的新功能:
Spreadsheet#deleteSheet
(您不必激活工作表来删除它)Range#getNumColumns
Range
的宽度Range#getNumRows
Range
的高度另一种方法是使用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");
}