Задать вопрос
@Yanemane

Почему не удается вставить полученный из цикла массив?

function sv21() {
var ss1 = SpreadsheetApp.openByUrl('');
var sheet1 = ss1.getSheetByName('ссылки');
var urls = sheet1.getRange('b3:b').getValues();//берет ссылки на папку в заданных ячейках
urls = urls.filter(function (row) { //удаляет пустые строки, где нет ссылок
return row[0] != ''})
var arr = [];
for (var url in urls){
var ss = SpreadsheetApp.openByUrl(urls[url]);
let obj = {}
ss.getSheets().forEach(sh => {
obj[sh.getName()] = sh.getDataRange().getValues();
// var ssName = ss.getName()
// obj[sh].push(ssName)
})

arr = arr.concat(obj);//объединяет массивы
Logger.log(JSON.stringify(arr));
}

SpreadsheetApp.openByUrl('').getSheetByName('все расчеты').getRange(1, 1, arr.length, arr[0].length).setValues(arr); //вставляет массив
}

После логов выдает "The parameters (number,number,number,null) don't match the method signature for SpreadsheetApp.Sheet.getRange."
  • Вопрос задан
  • 32 просмотра
Подписаться 1 Простой Комментировать
Пригласить эксперта
Ответы на вопрос 1
oshliaer
@oshliaer Куратор тега Google Apps Script
Google Products Expert
The parameters (number,number,number,null) don't match the method signature for SpreadsheetApp.Sheet.getRange.


Означает, что вы в метод getRange передаете аргументы несвойственные его сигнатуре. Обратите внимание, что четвертый аргумент null, а это значит, что ваш вызов arr[0].length возвращает null. Что в свою очередь означает, что ваш массив arr содержит первый элемент, у которго отсутствует свойство length. Что очевидно, т.к. obj - не массив, см. тут obj[sh.getName()] = sh.getDataRange().getValues();

Дальше мне было лень

Давайте починим код. Ошибка возникает из-за того, что вы пытаетесь использовать метод `getRange(1, 1, arr.length, arr[0].length)` с некорректными параметрами. Кроме того, есть несколько других проблем в коде, которые нужно исправить:

1. **Пустые URL-адреса**: Вы фильтруете массив ссылок, но не проверяете, действительно ли они являются действительными URL-адресами.
2. **Структура данных**: В вашем коде `arr` становится объектом, а не массивом, и это вызывает проблемы при использовании `setValues`.
3. **Логика записи данных**: Метод `setValues` ожидает двумерный массив, но ваша структура данных не соответствует этому требованию.

Вот исправленная версия кода:

function sv21() {
  // Открываем основную таблицу
  var ss1 = SpreadsheetApp.openByUrl('URL_ОСНОВНОЙ_ТАБЛИЦЫ'); // Замените на реальный URL
  var sheet1 = ss1.getSheetByName('ссылки');
  
  // Получаем ссылки из столбца B
  var urls = sheet1.getRange('B3:B').getValues().flat(); // Берем значения из столбца B
  urls = urls.filter(function (url) { // Удаляем пустые строки
    return url !== '' && url.startsWith('https://'); // Проверяем, что это действительно URL
  });

  var allData = []; // Здесь будем хранить все данные

  // Проходимся по каждой ссылке
  for (var i = 0; i < urls.length; i++) {
    try {
      var ss = SpreadsheetApp.openByUrl(urls[i]); // Открываем таблицу по URL
      ss.getSheets().forEach(function (sh) {
        var data = sh.getDataRange().getValues(); // Получаем данные с листа
        allData = allData.concat(data); // Добавляем данные в общий массив
      });
    } catch (e) {
      Logger.log('Ошибка при обработке URL: ' + urls[i] + '. Подробности: ' + e.message);
    }
  }

  // Если есть данные для записи
  if (allData.length > 0) {
    // Открываем целевую таблицу и записываем данные
    var targetSheet = SpreadsheetApp.openByUrl('URL_ЦЕЛЕВОЙ_ТАБЛИЦЫ') // Замените на реальный URL
      .getSheetByName('все расчеты');
    
    // Очищаем предыдущие данные
    targetSheet.clearContents();
    
    // Записываем новые данные
    targetSheet.getRange(1, 1, allData.length, allData[0].length).setValues(allData);
  } else {
    Logger.log('Нет данных для записи.');
  }
}


Что было исправлено:
1. **Обработка URL-адресов**:
- Добавлена проверка на то, что ссылка начинается с `https://`.
- Используется метод `.flat()` для преобразования многомерного массива в одномерный.

2. **Сбор данных**:
- Все данные собираются в массив `allData`, который затем используется для записи в целевую таблицу.

3. **Запись данных**:
- Перед записью данных очищается содержимое целевого листа (`clearContents`).
- Проверяется, что массив `allData` не пустой, прежде чем выполнять запись.

4. **Обработка ошибок**:
- Добавлен блок `try-catch` для обработки ошибок при открытии таблицы по URL.

5. **Логирование**:
- Логируется информация об ошибках, чтобы легче было находить проблемы.

Как использовать:

1. Замените `'URL_ОСНОВНОЙ_ТАБЛИЦЫ'` и `'URL_ЦЕЛЕВОЙ_ТАБЛИЦЫ'` на реальные URL-адреса ваших таблиц.
2. Убедитесь, что у скрипта есть необходимые права доступа к таблицам.

Теперь код должен работать корректно!
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы