Ваш скрипт выглядит довольно неплохо, но есть возможности для улучшения, как по производительности, так и по организации кода. Вот несколько изменений и оптимизаций, которые вы можете рассмотреть:
1. **Избегайте удаления всех триггеров**: Если не требуется удалять все триггеры, это может быть дорогостоящей операцией. Можно просто проверить наличие триггера и, если он существует, обновить его.
2. **Используйте пакетную обработку**: Вместо обработки URL-адресов по одному, можно обрабатывать их пакетами, чтобы минимизировать количество вызовов к `UrlFetchApp.fetch`.
3. **Обработка ошибок**: Необходимо добавить предотвращение сбоев на случай, если URL будет недоступен или вернет ошибку. Например, можно обрабатывать ошибки `try-catch` и добавлять логи для отслеживания.
4. **Оптимизация записей в таблице**: Вместо записи в ячейки по одной, можно собирать данные и записывать их за один раз, что ускорит процесс.
Вот улучшенная версия вашего скрипта с учетом этих рекомендаций:
```javascript
function createOrUpdateTimeDrivenTrigger() {
var triggers = ScriptApp.getProjectTriggers();
var triggerExists = false;
// Проверяем, есть ли триггер и обновляем его, если он существует
triggers.forEach(function(trigger) {
if (trigger.getHandlerFunction() === 'fetchDataFromUrls') {
triggerExists = true;
// Удаляем старый триггер, чтобы создать новый
ScriptApp.deleteTrigger(trigger);
}
});
// Создаем новый триггер, который будет запускать скрипт каждые 5 минут
ScriptApp.newTrigger('fetchDataFromUrls')
.timeBased()
.everyMinutes(5)
.create();
}
function fetchDataFromUrls() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var lastRow = sheet.getLastRow();
// URLs в столбцах C, D, E, F
var urlColumns = ['C', 'D', 'E', 'F'];
var outputColumns = ['G', 'H', 'I', 'J'];
// Получаем текущее состояние
var scriptProperties = PropertiesService.getScriptProperties();
var currentRow = parseInt(scriptProperties.getProperty('currentRow')) || 1;
// Обрабатываем строки по 20 за раз
var rowsToProcess = 20;
// Определяем конец обработки
var endRow = Math.min(currentRow + rowsToProcess - 1, lastRow);
// Обрабатываем строки, пока есть строки для обработки
if (currentRow <= lastRow) {
// Сохраним результаты в массиве
var results = [];
urlColumns.forEach(function(column, index) {
var range = sheet.getRange(column + currentRow + ':' + column + endRow);
var urls = range.getValues();
urls.forEach(function(row, rowIndex) {
var url = row[0];
if (url) {
try {
var response = UrlFetchApp.fetch(url);
var jsonData = JSON.parse(response.getContentText());
results[rowIndex + currentRow - 1] = jsonData; // Передаем результат по индексу
} catch (error) {
Logger.log('Error fetching URL: ' + url + ' - ' + error.message);
results[rowIndex + currentRow - 1] = 'Error'; // Или какое-то значение по умолчанию
}
} else {
results[rowIndex + currentRow - 1] = 'No URL';
}
});
// Запись результатов в соответствующий столбец
var outputRange = sheet.getRange(outputColumns[index] + currentRow + ':' + outputColumns[index] + endRow);
outputRange.setValues(results.map(result => [result])); // оборачиваем в массив
});
// Обновляем текущее состояние
scriptProperties.setProperty('currentRow', endRow + 1);
}
}
```
### Краткий обзор изменений:
- Функция `createOrUpdateTimeDrivenTrigger` теперь проверяет наличие триггера и обновляет его.
- Заголовок для триггера изменен на `everyMinutes(5)`.
- Обработка ошибок происходит с помощью блока `try-catch`.
- Вместо записи результата по одному записывается массив результатов за один вызов `setValues`.
Это должно значительно повысить производительность вашего скрипта и улучшить его стабильность.