У меня есть сотни таблиц, которые были сделаны из листа шаблона. Все они имеют одинаковое количество / имя листов, строк, столбцов и т. Д. *
Я добавил некоторые проверки данных в шаблон. Я хочу скопировать проверки данных из шаблона в каждую из таблиц. У меня есть код, и он работает, но он выдает ошибку памяти.
Он всегда выдает ошибку - меняется только то, сколько электронных таблиц назначения он обработал, прежде чем выдает ошибку. Иногда он обрабатывает 4 таблицы до того, как выдает ошибку, иногда 50, иногда больше / меньше. Я не могу понять, почему.
Я сократил свой код до рабочего образца. Я не могу поделиться исходными файлами, но это просто обычные таблицы с 5 листами / вкладками и различными проверками данных. Если это имеет значение, проверки данных используют именованные диапазоны. Например: =REGEXMATCH(LOWER(google_drive_url) , "^https:\/\/drive\.google\.com\/drive\/folders\/[a-z0-9_-]{33}$")
.
Я прокомментировал приведенный ниже код, но вот резюме:
- Получите электронную таблицу шаблона и кешируйте в ней все проверки данных
- Пройдите через каждый пункт назначения. Электронная таблица:
- Просмотрите все проверки данных
- Примените проверки данных из шаблона
Вмой реальный код у меня есть массив идентификаторов файла назначения. В целях тестирования я просто использую один файл назначения и несколько раз проверяю данные из шаблона.
function myFunction() {
var sourceFileID = "1rB7Z0C615Kn9ncLykVhVAcjmwkYb5GpYWpzcJRjfcD8";
var destinationFileID = "1SMrwTuknVa1Xky9NKgqwg16_JNSoHcFTZA6QxzDh7q4";
// get the source file
var sourceSpreadsheet = SpreadsheetApp.openById(sourceFileID);
var sourceDataValidationCache = {};
// go through each sheet and get a copy of the data validations
// cache them for quick access later
sourceSpreadsheet.getSheets().forEach(function(sourceSheet){
var sheetName = sourceSheet.getName();
// save all the data validations for this sheet
var thisSheetDataValidationCache = [];
// get the full sheet range
// start at first row, first column, and end at max rows and max columns
// get all the data validations in it
// go through each data validation row
sourceSheet.getRange(1, 1, sourceSheet.getMaxRows(), sourceSheet.getMaxColumns()).getDataValidations().forEach(function(row, rowIndex){
// go through each column
row.forEach(function(cell, columnIndex){
// we only need to save if there is a data validation
if(cell)
{
// save it
thisSheetDataValidationCache.push({
"row" : rowIndex + 1,
"column" : columnIndex + 1,
"dataValidation" : cell
});
}
});
});
// save to cache for this sheet
sourceDataValidationCache[sheetName] = thisSheetDataValidationCache;
});
// this is just an example
// so just update the data validations in the same destination numerous times to show the memory leak
for(var i = 0; i < 100; ++i)
{
// so we can see from the log how many were processed before it threw a memory error
Logger.log(i);
// get the destination
var destinationSpreadsheet = SpreadsheetApp.openById(destinationFileID);
// go through each sheet
destinationSpreadsheet.getSheets().forEach(function(destinationSheet){
var sheetName = destinationSheet.getName();
// get the full range and clear existing data validations
destinationSheet.getRange(1, 1, destinationSheet.getMaxRows(), destinationSheet.getMaxColumns()).clearDataValidations();
// go through the cached data validations for this sheet
sourceDataValidationCache[sheetName].forEach(function(dataValidationDetails){
// get the cell/column this data validation is for
// copy it, build it, and set it
destinationSheet.getRange(dataValidationDetails.row, dataValidationDetails.column).setDataValidation(dataValidationDetails.dataValidation.copy().build());
});
});
}
}
Что-то не так с кодом? Почему это вызвало бы ошибку памяти? Есть ли способ поймать / предотвратить это?