Как говорится в сообщении об ошибке, вы достигли предела времени выполнения скрипта, который может составлять 6 или 30 минут в зависимости от типа вашей учетной записи, как указано здесь .
Чтобы избежать этого, вы можете сделать две вещи (не взаимоисключающие):
Повысить эффективность кода:
Повысить эффективность вашего кода. Вы можете, например, заменить разные setValue
на одно единственное setValues. Вам придется заменить это:
SpreadsheetApp.getActiveSheet().getRange(1+i,1).setValue(code);
SpreadsheetApp.getActiveSheet().getRange(1+i,2).setValue(stock100);
SpreadsheetApp.getActiveSheet().getRange(1+i,3).setValue(stock801);
На это:
SpreadsheetApp.getActiveSheet().getRange(1+i, 1, 1, 3).setValues([[code, stock100, stock801]]);
Разбить скрипт на несколько исполнений:
Вы также можете разбить свой l oop на различные исполнения, устанавливая основанный на времени триггер, который будет запускать каждое последующее выполнение после завершения предыдущего. Вам нужно будет сделать следующее:
Узнайте, сколько итераций вы можете выполнить, прежде чем достигните предела времени (в приведенном ниже примере это значение равно 3). Каждое выполнение должно будет выполнить это количество итераций до завершения.
Создайте следующий основанный на времени триггер в конце вашей функции: after (durationMilliseconds) . Благодаря этому вы можете запускать любую функцию, указанную вами, по истечении указанного вами количества миллисекунд. После каждого выполнения будет создан триггер для запуска следующего.
Поскольку вы хотите разделить l oop, вы должны сохранить счетчик l oop (i
) где-нибудь (вы можете использовать PropertiesService в конце каждого выполнения или записать его в электронную таблицу) и извлечь его в начале следующего, чтобы каждый сценарий в последовательном выполнении знал, где возобновить l oop. См., Например, этот ответ , если вы не знаете, как хранить и извлекать свойства скрипта.
Пример кода (проверьте встроенные комментарии):
function myFunction(){
var i_old = // Retrieve i stored in previous execution (from PropertiesService? Spreadsheet?) (should be 0 if first execution)
var n_int = 3 // Number of iterations that can be done in a single execution without reaching time limit (change accordingly)
var total = 20 // Total number of iterations (change accordingly)
var url = '<<file name>>';
var bggXml = UrlFetchApp.fetch(url).getContentText();
var document = XmlService.parse(bggXml);
var root = document.getRootElement();
var now = new Date();
// Loop starts at previous i store until it reaches the specified number of iterations for one execution or reaches the total number:
for(var i = i_old; i <= i_old + n_int && i <= total; i++) {
var shopitem = root.getChildren('SHOPITEM')[i];
var code = shopitem.getChild('CODE').getText();
var stock100 = shopitem.getChild('STOCK').getChild('WAREHOUSES').getChildren('WAREHOUSE')[0].getChild('VALUE').getText();
var stock801 = shopitem.getChild('STOCK').getChild('WAREHOUSES').getChildren('WAREHOUSE')[1].getChild('VALUE').getText();
SpreadsheetApp.getActiveSheet().getRange(1 + i, 1, 1, 3).setValues([[code, stock100, stock801]]);
}
// Store i somewhere (PropertiesService? Spreadsheet?)
if (i <= total) { // Create trigger if i hasn't reach the total number of iteration
ScriptApp.newTrigger("myFunction")
.timeBased()
.after(1000 * 60) // This fires the function 1 minute after the current execution ends. Change this time according to your preferences
.create();
}
}
Ссылка: