我在理解数组时遇到了麻烦,但是我知道这是解决我的问题所需要做的。目前,我正在将需要的数据从另一个工作表复制到选项卡上,然后复制该数据表,然后将其粘贴到该工作表的另一个选项卡中。现在,我需要在此最终产生的数据的末尾添加另一列,该列是相邻每个单元格中的公式,该列是从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();
}
它在我第一次运行脚本时有效,但是下次我运行它时,它不会在最后一栏中添加公式。我不是程序员,只是知道足够危险。 :)
答案 0 :(得分:0)
您的解决方案即将结束。我推荐的方法是创建对脚本将复制到的第一行的引用-target.getLastRow() + 1
-然后将该引用用于数据表副本和公式write。您的脚本还存在一个可能的问题,因为您假设工作表名称始终为"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");
}