我再次回到SO处理GAS问题,因为我对Javascript / GAS还不太熟悉。基于处理函数调用的方法,我在运行脚本的速度有点麻烦。
我在几个地方读过(啊,它是here),为获取解析设置值做“read-all”然后“write-all” (至少在Spreadsheets中)比“get-one,write-one”方法 更快(出于显而易见的原因,这是有道理的)。
我知道如何获取Range中的所有值,但我不确定如何通过(多维)数组,处理数据,并相应地设置新的Range 。
问题:启动该功能大约需要2秒钟,大约需要5秒才能运行50行。问题是,我可能在这个电子表格中有数千行,并且让这个功能运行到确保数据被正确地进行后处理,以便Boomerang日历正确地获取时间数据有点在我看来是荒谬的。对于需要处理的每一列数据,脚本需要两倍的时间,这是可怕的。我担心在下一学期学期我经常会超过我的“GAS处理时限”。
以下是起始代码(糟糕,我承认):
function fixApostrophes() {
// Get the active spreadsheet to run the script on
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
// Get the active sheet within the document to run the script on
var sheet = spreadsheet.getActiveSheet();
// Get max number of rows needed to process
var maxRows = sheet.getLastRow();
// Get the range for the startTime column and endTime column
var apostropheRange = sheet.getRange(1, 10, maxRows, 2);
// Get the value in each cell, remove apostrophes from the start,
// and replace the value in that cell
for (var i = 1; i < apostropheRange.getNumRows(); ++i) {
// Get the cells for startTime and endTime to speed things up a bit
var startCell = apostropheRange.getCell(i, 1);
var endCell = apostropheRange.getCell(i, 2);
// Get the values for startTime and endTime
var startTime = startCell.getValue();
var endTime = endCell.getValue();
// Remove apostrophes from start of startTime
while(startTime.charAt(0) == "'") {
startTime = startTime.substring(1);
}
// Remove apostrophes from start of startTime
while(endTime.charAt(0) == "'") {
endTime = endTime.substring(1);
}
// Set the values for startTime and endTime
startCell.setValue(startTime);
endCell.setValue(endTime);
}
}
这与我的previous question高度相关,关于修复时间格式撇号问题,该问题打破了Boomerang日历功能以安排事件。
解决方案:使用Range.getValues()
函数将Range中的值拉入2D数组。处理2D数组中的每个值(逐行可能是最合理的方法),然后使用新值更新编辑值的索引(请参阅代码中的Srik-answer注释)。之后,使用Range.setValues(2Darray)
将2D数组中的元素放回原始Range中。如果遇到它,我希望这可以帮到你!这比我原始代码中多次调用API还要快 。
function myNewLibraryFunction(startCol, numColumns) {
// Get the active spreadsheet to run the script on
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
// Get the active sheet within the document to run the script on
var sheet = spreadsheet.getActiveSheet();
// Get max number of rows needed to process
var maxRows = sheet.getLastRow();
// Get the range for the startTime column and endTime column
var dataRange = sheet.getRange(1, startCol, maxRows, numColumns);
var values = dataRange.getValues();
// Get the value in each cell, remove apostrophes from the start,
// and replace the value in that cell
for (var i = 1; i < maxRows; ++i) {
// Get the values for startTime and endTime
var startTime = values[i][0];
var endTime = values[i][1];
// Remove apostrophes from start of startTime
while(startTime.charAt(0) == "'") {
startTime = startTime.substring(1);
}
// Remove apostrophes from start of startTime
while(endTime.charAt(0) == "'") {
endTime = endTime.substring(1);
}
values[i][0] = startTime; // New stuff from Srik's answer
values[i][1] = endTime; // New stuff from Srik's answer
}
dataRange.setValues(values);
SpreadsheetApp.flush(); // New stuff from Srik's answer
}
答案 0 :(得分:3)
基本上,您对GAS中列出的API所做的大多数函数调用都需要比常规JavaScript更多的时间。在您的情况下,减少对Range和Sheet类的调用次数
function fixApostrophes() {
// Get the active spreadsheet to run the script on
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
// Get the active sheet within the document to run the script on
var sheet = spreadsheet.getActiveSheet();
// 1. Replace two calls and many other calls later with one.
var dataRange = sheet.getDataRange();
var values = dataRange.getValues();// a 2D array
// Get the value in each cell, remove apostrophes from the start,
// and replace the value in that cell
for (var i = 1; i < values .length ; ++i) {
// Get the values for startTime and endTime
var startTime = values [i][0];
var endTime = values [i][1];
// Remove apostrophes from start of startTime
// These are okay. Regular Javascript - not time consuming
while(startTime.charAt(0) == "'") {
startTime = startTime.substring(1);
}
// Remove apostrophes from start of startTime
while(endTime.charAt(0) == "'") {
endTime = endTime.substring(1);
}
}
dataRange.setValues(values);
}
提示:您可以看到每次通话在执行记录中花费了多少时间