[英]Copy not contiguous selected rows from a spreadsheet to another
With this script is possible to copy the selected rows from a spreadsheet to another, from the column C to column E.使用此脚本可以将选定的行从电子表格复制到另一个电子表格,从 C 列到 E 列。
When the script is terminated, in the "source" spreadsheet, in column H appears the value sent
for the rows copied.当脚本终止时,在“源”电子表格中,H 列中会出现为复制的行
sent
的值。
The problem is that the script take the rows selected in a contiguous range and so not with the possibility to copy not contiguous selected rows.问题是脚本采用在连续范围内选择的行,因此不可能复制不连续的选定行。
How can I solve this?我该如何解决这个问题?
function main() {
transfer("....", "Foglio1", "Foglio1");
}
function transfer(targetId, sourceSheetName, targetSheetName) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sourceSheet = ss.getSheetByName(sourceSheetName);
var last = sourceSheet.getActiveRange().getRow();
var height = sourceSheet.getActiveRange().getHeight();
var data = sourceSheet.getRange(last, 3, height, 3).getValues();
// copy data
var ss2 = SpreadsheetApp.openById(targetId);
var targetSheet = ss2.getSheetByName(targetSheetName);
//get last row
var lastRow = targetSheet.getLastRow();
//write data
targetSheet.getRange(lastRow + 1, 3, data.length, data[0].length)
.setValues(data);
sourceSheet.getRange(last, 8, height).setValue('Sent');
}
I believe your goal as follows.我相信你的目标如下。
getActiveRangeList()
and the method of spreadsheets.values.batchGet in Sheets API.getActiveRangeList()
和 Sheets API 中的电子表格电子表格getActiveRangeList()
的方法。
When above points are reflected to your script, it becomes as follows.当以上几点反映到你的脚本中时,它变成如下。
In this case, transfer()
is modified.在这种情况下,
transfer()
被修改。 Before you use this script, please enable Sheets API at Advanced Google services .在使用此脚本之前, 请在高级 Google 服务中启用 Sheets API 。
function transfer(targetId, sourceSheetName, targetSheetName) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sourceSheet = ss.getSheetByName(sourceSheetName);
// --- I modified below script.
var ranges = sourceSheet.getActiveRangeList().getRanges().reduce((o, r) => {
var row = r.getRow();
var numRows = r.getNumRows();
o.getValues.push(`${sourceSheetName}!C${row}:E${row + numRows - 1}`);
o.setValue.push(`${sourceSheetName}!H${row}:H${row + numRows - 1}`);
return o;
}, {getValues: [], setValue: []});
var data = Sheets.Spreadsheets.Values.batchGet(ss.getId(), {ranges: ranges.getValues}).valueRanges.reduce((ar, v) => ar.concat(v.values), []);
data = data.map(r => !r ? Array(3).fill("") : (r.length < 3 ? r.concat(Array(3 - r.length).fill("")) : r)); // Added by OP's 3rd question in the comment.
// ---
// copy data
var ss2 = SpreadsheetApp.openById(targetId);
var targetSheet = ss2.getSheetByName(targetSheetName);
//get last row
var lastRow = targetSheet.getLastRow();
//write data
targetSheet.getRange(lastRow + 1, 1, data.length, data[0].length).setValues(data); // Modified by OP's 2nd question in the comment.
sourceSheet.getRangeList(ranges.setValue).setValue('Sent'); // Modified
}
In addition to the elegant solution proposed by Tanaike, I would like to add for completion's sake a simple solution:除了 Tanaike 提出的优雅解决方案之外,为了完成起见,我想添加一个简单的解决方案:
You are defining var height = sourceSheet.getActiveRange().getHeight();
您正在定义
var height = sourceSheet.getActiveRange().getHeight();
The method getHeight() returns the height of an (adjacent) range. getHeight()方法返回(相邻)范围的高度。
If instead you want to copy all the range until the last data containing row - including empty rows, you can define instead:相反,如果您想复制所有范围,直到包含行的最后一个数据 - 包括空行,您可以改为定义:
var height = sourceSheet.getActiveRange().getLastRow() - last + 1;
Now you will select and copy al the rows between the actively selected one and the last data containing row - including empty rows inbetween.现在,您将选择并复制主动选择的行和包含最后一个数据的行之间的所有行 - 包括中间的空行。
Mind that for large amounts of data, Tanaike's solution will be more efficient.请注意,对于大量数据,Tanaike 的解决方案会更高效。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.