Почему возникает ошибка при попытке вставить массив, полученный из цикла?

Какое изменение необходимо внести в код функции `sv21()`, чтобы устранить ошибку "The parameters (number, number, number, null) don't match the method signature for SpreadsheetApp.Sheet.getRange" после выполнения логирования?
  • 18 февраля 2025 г. 10:34
Ответы на вопрос 2
Ошибка "The parameters (number, number, number, null) don't match the method signature for SpreadsheetApp.Sheet.getRange" возникает, когда вы пытаетесь вызвать метод `getRange` с неправильным количеством параметров или с параметрами неправильного типа.

Метод `getRange` в Google Apps Script может принимать несколько форматов параметры, но чаще всего он используется с четырьмя параметрами: `getRange(row, column, numRows, numColumns)`, где `row` и `column` — это номера строки и столбца, а `numRows` и `numColumns` — это количество строк и столбцов в диапазоне.

Проблема в вашем коде может заключаться в том, что вы передаете `null` в качестве одного из параметров, когда это недопустимо. Например, если вы хотите создать диапазон размером 1x1 (одна ячейка), убедитесь, что все параметры — это числа.

Вот некоторые шаги, которые вы можете предпринять, чтобы устранить ошибку:

1. Проверьте логирование значений, которые вы передаете в `getRange`, и убедитесь, что они не равны `null` или не имеют некорректные значения.
2. Убедитесь, что вы правильно инициализировали все переменные с числами перед вызовом функции `getRange`.

Вот изменённый пример функции `sv21()`, чтобы включить проверки и устранить ошибку:

```javascript
function sv21() {
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  
  // Пример массива значений
  const data = [];
  
  for (let i = 1; i <= 10; i++) {
    data.push([i]); // Создаём массив из чисел 1-10
  }
  
  // Логируем массив для отладки
  Logger.log(data);
  
  // Получите количество строк и столбцов
  const numRows = data.length;
  const numColumns = data[0].length;

  // Проверяем значения
  Logger.log(`numRows: ${numRows}, numColumns: ${numColumns}`);

  // Используем полученные значения в getRange
  sheet.getRange(1, 1, numRows, numColumns).setValues(data);
}
```

В этом пример мы создаем массив `data`, который содержит набор значений, а затем используем его для выполнения операции `setValues` после вызова метода `getRange`. Убедитесь, что все значения для `numRows` и `numColumns` корректные и не равны `null` или любым другим недопустимым типам.
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. Убедитесь, что у скрипта есть необходимые права доступа к таблицам.

Теперь код должен работать корректно!
Похожие вопросы