Код спрашивающего занимает более 4-6 минут для выполнения и получает ошибку Exceeded maximum execution time
.
Следующий ответ основан исключительно на коде, предоставленном спрашивающим.У нас нет никакой информации о «комбинированной» электронной таблице, ее размере и триггерах.Мы также находимся в неведении относительно различных электронных таблиц студентов, их размера и т. Д., За исключением того, что мы знаем, что существует 2000 таких файлов.Мы не знаем, как часто эта процедура выполняется, и сколько учеников имеют баллы <120. Заявления </p>
getvalues
и setvalues
очень дороги;как правило, 0,2 секунды каждый.Код задаваемых вопросов включает в себя множество таких утверждений - некоторые из них неизбежны, а другие нет.
Рассматривая оптимизацию этого кода, я внес два основных изменения.
1 - я переместил строку 27 var data2 = sheet2[0].getDataRange().getValues();
Эта строка должна быть выполнена только один раз, и я переместил ее в верхнюю часть кода сразу после различных команд "filecombined".В нынешнем виде эта строка выполнялась один раз для каждой таблицы ученика;это, возможно, способствовало нескольким минутам времени выполнения.
2) Я преобразовал некоторые команды setvalue
в массив, а затем обновил «объединенную в файл» электронную таблицу из массива только один раз, в концеобработка.В зависимости от количества учеников с низким кредитом и тех, кто еще не занесен в «комбинированный файл», это может существенно сэкономить.Код затрагивал строки с 47 по 50.
line47: sheet2[0].getRange(lastrow+1, 1).setValue(nombre);
line48: sheet2[0].getRange(lastrow+1, 2).setValue(email);
line49: sheet2[0].getRange(lastrow+1, 3).setValue(credits);
line50: sheet2[0].getRange(lastrow+1, 4).setValue(fecha);
В строках 38 и 39 также выполняются команды setvalue
(если учащийся уже находится в электронной таблице с комбинированием файлов), но я решил оставитьэто как есть.Как отмечалось выше, мы не знаем, сколько таких студентов может быть, и стоимость этих setvalue
команд может быть незначительной или нет.До тех пор, пока это не станет ясно, и с учетом экономии времени я решил оставить их как есть.
function updated() {
//Final file data (Combined)
var filecombined = SpreadsheetApp.openById("XXXXXXXXXX");
var sheet2 = filecombined.getSheets();
//Take data from final file (Combined)
var data2 = sheet2[0].getDataRange().getValues();
// create some arrays
var Newdataarray = [];
var Masterarray = [];
//Folder with all the files
var parentFolder = DriveApp.getFolderById("YYYYYYYYYYYY");
var files = parentFolder.getFiles();
//Current Date
var fecha = new Date();
//Path for each file in the folder
while (files.hasNext()) {
var idarchivo = files.next().getId();
var sps = SpreadsheetApp.openById(idarchivo);
var sheet = sps.getSheetByName('STUDENT PROFILE');
var data = sheet.getDataRange().getValues();
var credits = data[5][1];
//Flat; bandera:1 (new row), bandera:2 (update row)
var bandera = 1;
//If credits are less than X: write
if (credits < 120){
var email = data[2][1];
var lastrow = filecombined.getLastRow();
var u = 0;
//comparison loop by email, if found it, update and exit the loop
while (u < lastrow) {
u = u + 1;
if (email == data2[u-1][1]){
sheet2[0].getRange(u, 3).setValue(credits);
sheet2[0].getRange(u, 4).setValue(fecha);
u = lastrow;
bandera = 2;
}
}
//if that email does not exist, write a new row
if(bandera == 1){
var nombre = data[0][1];
Newdataarray = [];
Newdataarray.push(nombre);
Newdataarray.push(email);
Newdataarray.push(credits);
Newdataarray.push(fecha);
Masterarray.push(Newdataarray);
}
}
}
// update the target sheet with the contents of the array
// these are all adding new rows
lastrow = filecombined.getLastRow();
sheet2[0].getRange(lastrow+1, 1, Masterarray.length, 4);
sheet2[0].setValues(Masterarray);
SpreadsheetApp.flush();
}