Google Apps 脚本 - 尝试有效地将不连续的单元格从一个 Sheet 复制到另一个的第一个空行
Google Apps Script- Trying to Efficiently Copy Noncontiguous Cells From One Sheet to a First Empty Row of Another
在单个 Google 工作表工作sheet 中,我有一个用户输入 sheet,它被安排为不喜欢传播的人很好地工作sheets,因此标签散布在数据中,分类帐 sheet 用于记录保存。输入 sheet 结合了以用户为中心的计算单元格和以记录为中心的单元格。我正在尝试创建一个脚本(通过 sheet 上的一个按钮成为 运行,它已经可以工作)将以记录为中心的单元格的当前内容复制到分类帐 sheet,然后重置所有输入单元以供下次使用。我将需要脚本为输入 sheet 的多个副本工作,我希望它在使用时不会明显跳转到记录 sheet,但这是可选的。
到目前为止,我已经从宏录制和许多其他答案中拼凑了我的脚本;我不拘泥于任何当前代码,但输入和输出 sheets 需要保持原样。但是,我确实有一个计算胆量 sheet,可用于保存我当前代码中的一些常量值。我已经看到一些类似问题的解决方案,这些解决方案采用了从传播 sheet 本身复制哪些单元格的定义 from/to,但我并不太担心它。
编辑:好的,我对代码进行了相当大的清理,它目前可以满足我的需要,只是效率低下。
function MakeMasterLogRecord() {
var spreadsheet = SpreadsheetApp.getActive();
var sourcesheet = SpreadsheetApp.getActiveSheet();
const masterlog = spreadsheet.getSheetByName('Master Log');
var firstemptyrow = masterlog.getLastRow() + 1;
var currentcolumn = 1
var targetcell = masterlog.getRange(firstemptyrow, currentcolumn, 1, 1);
var sourcecells = ['Z12','C2','N2','C10','F2','C4','E4','C5','E5','L5','L4','Z13','T4','T5','C6'];
sourcesheet.getRange('Z12').copyTo(targetcell, SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
currentcolumn++;
targetcell = masterlog.getRange(firstemptyrow, currentcolumn, 1, 1);
sourcesheet.getRange('C2').copyTo(targetcell, SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
currentcolumn++;
targetcell = masterlog.getRange(firstemptyrow, currentcolumn, 1, 1);
sourcesheet.getRange('N2').copyTo(targetcell, SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
currentcolumn++;
targetcell = masterlog.getRange(firstemptyrow, currentcolumn, 1, 1);
sourcesheet.getRange('C10').copyTo(targetcell, SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
currentcolumn++;
targetcell = masterlog.getRange(firstemptyrow, currentcolumn, 1, 1);
sourcesheet.getRange('F2').copyTo(targetcell, SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
currentcolumn++;
targetcell = masterlog.getRange(firstemptyrow, currentcolumn, 1, 1);
sourcesheet.getRange('C4').copyTo(targetcell, SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
currentcolumn++;
targetcell = masterlog.getRange(firstemptyrow, currentcolumn, 1, 1);
sourcesheet.getRange('E4').copyTo(targetcell, SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
currentcolumn++;
targetcell = masterlog.getRange(firstemptyrow, currentcolumn, 1, 1);
sourcesheet.getRange('C5').copyTo(targetcell, SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
currentcolumn++;
targetcell = masterlog.getRange(firstemptyrow, currentcolumn, 1, 1);
sourcesheet.getRange('E5').copyTo(targetcell, SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
currentcolumn++;
targetcell = masterlog.getRange(firstemptyrow, currentcolumn, 1, 1);
sourcesheet.getRange('L5').copyTo(targetcell, SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
currentcolumn++;
targetcell = masterlog.getRange(firstemptyrow, currentcolumn, 1, 1);
sourcesheet.getRange('L4').copyTo(targetcell, SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
currentcolumn++;
targetcell = masterlog.getRange(firstemptyrow, currentcolumn, 1, 1);
sourcesheet.getRange('Z13').copyTo(targetcell, SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
currentcolumn++;
targetcell = masterlog.getRange(firstemptyrow, currentcolumn, 1, 1);
sourcesheet.getRange('T4').copyTo(targetcell, SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
currentcolumn++;
targetcell = masterlog.getRange(firstemptyrow, currentcolumn, 1, 1);
sourcesheet.getRange('T5').copyTo(targetcell, SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
currentcolumn++;
targetcell = masterlog.getRange(firstemptyrow, currentcolumn, 1, 1);
sourcesheet.getRange('C6').copyTo(targetcell, SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
currentcolumn++;
};
变量“sourcecells”是包含我要复制的信息的单元格列表,我希望能够将它用作循环的输入,而不必直接调用列表。目前未使用。
再次编辑:
使用 Kessy 建议的 getValue 和 setValue,以及 Cooper 建议的 forEach 循环。
这个“有效”是因为它 运行 是正确的次数,尽管使用相同的数据,而且它比我刚刚手动布置单元格引用的版本慢得多。
function MakeMasterLogRecord() {
var spreadsheet = SpreadsheetApp.getActive();
var sourcesheet = SpreadsheetApp.getActiveSheet();
const masterlog = spreadsheet.getSheetByName('Master Log');
var firstemptyrow = masterlog.getLastRow() + 1;
var currentcolumn = 1
var targetcell = masterlog.getRange(firstemptyrow, currentcolumn, 1, 1);
const sourcecell = ['\'Z12\'','\'C2\'','\'N2\'','\'C10\'','\'F2\'','\'C4\'','\'E4\'','\'C5\'','\'E5\'','\'L5\'','\'L4\'','\'Z13\'','\'T4\'','\'T5\'','\'C6\''];
for (const element of sourcecell) {
var targetcell = masterlog.getRange(firstemptyrow, currentcolumn, 1, 1);
targetcell.setValue(sourcesheet.getRange('Z12').getValue());
currentcolumn++;
};
};
我已经尝试过使用和不使用转义引号的数组条目,但都导致找不到范围错误。我无法让转义引号在“sourcecell”变量周围正常工作,所以我不知道如果我那样做它是否会起作用。它始终认为“sourcecell”一词在引号内。
试试这个来稍微提高性能:
function submitData() {
const ss = SpreadsheetApp.getActive();
const formRangeList = ss.getActiveSheet()
.getRangeList(['Z12', 'C2', 'N2', 'C10', 'F2', 'C4', 'E4', 'C5', 'E5', 'L5', 'L4', 'Z13', 'T4', 'T5', 'C6']);
ss.getSheetByName('Master Log')
.appendRow(formRangeList.getRanges().map(range => range.getValue()));
formRangeList.clearContent(); // remove this line if you do not want to clear the "form"
}
这还远未达到最佳状态,因为它调用了 Range.getValue()
15 次。为了提高运行时性能十倍,使用.getRange('A1:Z13').getValues()
一次性获取所有数据,然后使用数组索引提取您需要的值并附加到目标sheet,像这样:
function submitDataOhSoMuchFaster() {
const ss = SpreadsheetApp.getActive();
const values = ss.getActiveSheet().getRange('A1:Z13').getValues();
const spec = [
{ column: 26, row: 12 }, // Z12
{ column: 3, row: 2 }, // C2
{ column: 14, row: 2 }, // N2
// ...
];
ss.getSheetByName('Master Log')
.appendRow(spec.map(cell => values[cell.row - 1][cell.column - 1]));
}
在单个 Google 工作表工作sheet 中,我有一个用户输入 sheet,它被安排为不喜欢传播的人很好地工作sheets,因此标签散布在数据中,分类帐 sheet 用于记录保存。输入 sheet 结合了以用户为中心的计算单元格和以记录为中心的单元格。我正在尝试创建一个脚本(通过 sheet 上的一个按钮成为 运行,它已经可以工作)将以记录为中心的单元格的当前内容复制到分类帐 sheet,然后重置所有输入单元以供下次使用。我将需要脚本为输入 sheet 的多个副本工作,我希望它在使用时不会明显跳转到记录 sheet,但这是可选的。
到目前为止,我已经从宏录制和许多其他答案中拼凑了我的脚本;我不拘泥于任何当前代码,但输入和输出 sheets 需要保持原样。但是,我确实有一个计算胆量 sheet,可用于保存我当前代码中的一些常量值。我已经看到一些类似问题的解决方案,这些解决方案采用了从传播 sheet 本身复制哪些单元格的定义 from/to,但我并不太担心它。
编辑:好的,我对代码进行了相当大的清理,它目前可以满足我的需要,只是效率低下。
function MakeMasterLogRecord() {
var spreadsheet = SpreadsheetApp.getActive();
var sourcesheet = SpreadsheetApp.getActiveSheet();
const masterlog = spreadsheet.getSheetByName('Master Log');
var firstemptyrow = masterlog.getLastRow() + 1;
var currentcolumn = 1
var targetcell = masterlog.getRange(firstemptyrow, currentcolumn, 1, 1);
var sourcecells = ['Z12','C2','N2','C10','F2','C4','E4','C5','E5','L5','L4','Z13','T4','T5','C6'];
sourcesheet.getRange('Z12').copyTo(targetcell, SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
currentcolumn++;
targetcell = masterlog.getRange(firstemptyrow, currentcolumn, 1, 1);
sourcesheet.getRange('C2').copyTo(targetcell, SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
currentcolumn++;
targetcell = masterlog.getRange(firstemptyrow, currentcolumn, 1, 1);
sourcesheet.getRange('N2').copyTo(targetcell, SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
currentcolumn++;
targetcell = masterlog.getRange(firstemptyrow, currentcolumn, 1, 1);
sourcesheet.getRange('C10').copyTo(targetcell, SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
currentcolumn++;
targetcell = masterlog.getRange(firstemptyrow, currentcolumn, 1, 1);
sourcesheet.getRange('F2').copyTo(targetcell, SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
currentcolumn++;
targetcell = masterlog.getRange(firstemptyrow, currentcolumn, 1, 1);
sourcesheet.getRange('C4').copyTo(targetcell, SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
currentcolumn++;
targetcell = masterlog.getRange(firstemptyrow, currentcolumn, 1, 1);
sourcesheet.getRange('E4').copyTo(targetcell, SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
currentcolumn++;
targetcell = masterlog.getRange(firstemptyrow, currentcolumn, 1, 1);
sourcesheet.getRange('C5').copyTo(targetcell, SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
currentcolumn++;
targetcell = masterlog.getRange(firstemptyrow, currentcolumn, 1, 1);
sourcesheet.getRange('E5').copyTo(targetcell, SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
currentcolumn++;
targetcell = masterlog.getRange(firstemptyrow, currentcolumn, 1, 1);
sourcesheet.getRange('L5').copyTo(targetcell, SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
currentcolumn++;
targetcell = masterlog.getRange(firstemptyrow, currentcolumn, 1, 1);
sourcesheet.getRange('L4').copyTo(targetcell, SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
currentcolumn++;
targetcell = masterlog.getRange(firstemptyrow, currentcolumn, 1, 1);
sourcesheet.getRange('Z13').copyTo(targetcell, SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
currentcolumn++;
targetcell = masterlog.getRange(firstemptyrow, currentcolumn, 1, 1);
sourcesheet.getRange('T4').copyTo(targetcell, SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
currentcolumn++;
targetcell = masterlog.getRange(firstemptyrow, currentcolumn, 1, 1);
sourcesheet.getRange('T5').copyTo(targetcell, SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
currentcolumn++;
targetcell = masterlog.getRange(firstemptyrow, currentcolumn, 1, 1);
sourcesheet.getRange('C6').copyTo(targetcell, SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
currentcolumn++;
};
变量“sourcecells”是包含我要复制的信息的单元格列表,我希望能够将它用作循环的输入,而不必直接调用列表。目前未使用。
再次编辑:
使用 Kessy 建议的 getValue 和 setValue,以及 Cooper 建议的 forEach 循环。
这个“有效”是因为它 运行 是正确的次数,尽管使用相同的数据,而且它比我刚刚手动布置单元格引用的版本慢得多。
function MakeMasterLogRecord() {
var spreadsheet = SpreadsheetApp.getActive();
var sourcesheet = SpreadsheetApp.getActiveSheet();
const masterlog = spreadsheet.getSheetByName('Master Log');
var firstemptyrow = masterlog.getLastRow() + 1;
var currentcolumn = 1
var targetcell = masterlog.getRange(firstemptyrow, currentcolumn, 1, 1);
const sourcecell = ['\'Z12\'','\'C2\'','\'N2\'','\'C10\'','\'F2\'','\'C4\'','\'E4\'','\'C5\'','\'E5\'','\'L5\'','\'L4\'','\'Z13\'','\'T4\'','\'T5\'','\'C6\''];
for (const element of sourcecell) {
var targetcell = masterlog.getRange(firstemptyrow, currentcolumn, 1, 1);
targetcell.setValue(sourcesheet.getRange('Z12').getValue());
currentcolumn++;
};
};
我已经尝试过使用和不使用转义引号的数组条目,但都导致找不到范围错误。我无法让转义引号在“sourcecell”变量周围正常工作,所以我不知道如果我那样做它是否会起作用。它始终认为“sourcecell”一词在引号内。
试试这个来稍微提高性能:
function submitData() {
const ss = SpreadsheetApp.getActive();
const formRangeList = ss.getActiveSheet()
.getRangeList(['Z12', 'C2', 'N2', 'C10', 'F2', 'C4', 'E4', 'C5', 'E5', 'L5', 'L4', 'Z13', 'T4', 'T5', 'C6']);
ss.getSheetByName('Master Log')
.appendRow(formRangeList.getRanges().map(range => range.getValue()));
formRangeList.clearContent(); // remove this line if you do not want to clear the "form"
}
这还远未达到最佳状态,因为它调用了 Range.getValue()
15 次。为了提高运行时性能十倍,使用.getRange('A1:Z13').getValues()
一次性获取所有数据,然后使用数组索引提取您需要的值并附加到目标sheet,像这样:
function submitDataOhSoMuchFaster() {
const ss = SpreadsheetApp.getActive();
const values = ss.getActiveSheet().getRange('A1:Z13').getValues();
const spec = [
{ column: 26, row: 12 }, // Z12
{ column: 3, row: 2 }, // C2
{ column: 14, row: 2 }, // N2
// ...
];
ss.getSheetByName('Master Log')
.appendRow(spec.map(cell => values[cell.row - 1][cell.column - 1]));
}