Google Apps Script: Получение названий всех листов в таблице

Что такое Google Apps Script и его преимущества

Google Apps Script (GAS) — это облачная платформа для разработки на JavaScript, которая позволяет автоматизировать задачи, интегрировать и расширять функциональность приложений Google Workspace (Таблицы, Документы, Формы, Диск и т.д.). Ключевые преимущества GAS включают тесную интеграцию с сервисами Google, отсутствие необходимости в инфраструктуре (скрипты выполняются на серверах Google) и использование JavaScript, что делает его доступным для веб-разработчиков.

Объект Spreadsheet и его методы для работы с листами

Центральным объектом при работе с Таблицами является SpreadsheetApp, который предоставляет доступ к текущей или конкретной таблице (Spreadsheet). Объект Spreadsheet содержит методы для манипуляции таблицей в целом, включая управление листами. Основные методы для работы с листами:

getSheets(): Возвращает массив всех объектов Sheet в таблице.

getSheetByName(name): Возвращает объект Sheet по его имени.

insertSheet(): Добавляет новый лист.

deleteSheet(sheet): Удаляет указанный лист.

setActiveSheet(sheet): Делает указанный лист активным.

Краткий обзор Sheet (лист) как элемента Spreadsheet

Объект Sheet представляет собой отдельный лист в Google Таблице. Он содержит методы для работы с данными на этом листе (получение и установка значений ячеек, форматирование, управление строками/столбцами) и для получения его свойств, таких как имя (getName()), индекс (getIndex()) и идентификатор (getSheetId()).

Получение названий всех листов в Google Таблице

Задача получения списка имен всех листов является стандартной при автоматизации работы с многолистовыми таблицами, например, для создания оглавления, динамических отчетов или навигации.

Метод `getSheets()`: получение массива всех листов

Первым шагом является получение доступа ко всем листам таблицы. Метод getSheets() объекта Spreadsheet идеально подходит для этой цели. Он не требует аргументов и возвращает массив объектов типа Sheet.

/**
 * Получает массив всех объектов листов в активной таблице.
 * @returns {GoogleAppsScript.Spreadsheet.Sheet[]} Массив объектов листов.
 */
function getAllSheetObjects(): GoogleAppsScript.Spreadsheet.Sheet[] {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const sheets = ss.getSheets();
  Logger.log(`Найдено листов: ${sheets.length}`);
  return sheets;
}

Использование `getName()` для извлечения имени листа

После получения массива объектов Sheet, необходимо извлечь имя каждого листа. Для этого используется метод getName(), вызываемый у каждого элемента массива (объекта Sheet).

Создание массива с названиями всех листов

Наиболее лаконичным способом создания массива имен является использование метода map() для массива листов, полученного с помощью getSheets().

/**
 * Получает названия всех листов в активной таблице.
 *
 * @returns {string[]} Массив строк с названиями листов.
 */
function getAllSheetNames(): string[] {
  const ss: GoogleAppsScript.Spreadsheet.Spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  const sheets: GoogleAppsScript.Spreadsheet.Sheet[] = ss.getSheets();

  // Используем map для преобразования массива объектов Sheet в массив их имен
  const sheetNames: string[] = sheets.map((sheet: GoogleAppsScript.Spreadsheet.Sheet): string => {
    return sheet.getName();
  });

  return sheetNames;
}

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

Простой скрипт для вывода названий листов в лог

Этот скрипт демонстрирует базовое получение имен и их вывод в журнал выполнения Apps Script.

/**
 * Получает и выводит в лог названия всех листов активной таблицы.
 */
function logAllSheetNames(): void {
  const sheetNames: string[] = getAllSheetNames(); // Используем функцию из предыдущего примера
  if (sheetNames.length > 0) {
    Logger.log('Названия листов:');
    sheetNames.forEach((name: string, index: number): void => {
      Logger.log(`${index + 1}. ${name}`);
    });
  } else {
    Logger.log('В таблице нет листов.');
  }
}

Скрипт для записи названий листов в ячейки таблицы

Часто требуется создать лист-оглавление. Этот скрипт записывает названия всех листов (кроме самого листа-оглавления, если он есть) в указанный столбец на листе ‘Содержание’.

/**
 * Записывает названия всех листов (кроме 'Содержание') 
 * в столбец A листа 'Содержание'.
 *
 * @param {string} [indexSheetName='Содержание'] Название листа для записи оглавления.
 * @param {string} [outputColumn='A'] Буква столбца для вывода названий.
 */
function writeSheetNamesToIndexSheet(indexSheetName: string = 'Содержание', outputColumn: string = 'A'): void {
  const ss: GoogleAppsScript.Spreadsheet.Spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  const allSheetNames: string[] = getAllSheetNames();

  // Фильтруем массив, исключая сам лист 'Содержание'
  const filteredNames: string[] = allSheetNames.filter((name: string): boolean => name !== indexSheetName);

  if (filteredNames.length === 0) {
    Logger.log(`Нет других листов для добавления в оглавление на листе '${indexSheetName}'.`);
    return;
  }

  let indexSheet: GoogleAppsScript.Spreadsheet.Sheet | null = ss.getSheetByName(indexSheetName);

  // Если листа 'Содержание' нет, создаем его
  if (!indexSheet) {
    indexSheet = ss.insertSheet(indexSheetName, 0); // Вставить первым
    Logger.log(`Создан лист '${indexSheetName}'.`);
  }

  // Очищаем целевой столбец перед записью
  const outputRangeNotation: string = `${indexSheetName}!${outputColumn}1:${outputColumn}${indexSheet.getMaxRows()}`;
  const outputRange: GoogleAppsScript.Spreadsheet.Range = ss.getRange(outputRangeNotation);
  outputRange.clearContent();

  // Преобразуем одномерный массив имен в двумерный для записи в диапазон
  const namesForSheet: string[][] = filteredNames.map((name: string): string[] => [name]);

  // Записываем данные
  const targetRange: GoogleAppsScript.Spreadsheet.Range = indexSheet.getRange(1, outputRange.getColumn(), namesForSheet.length, 1);
  targetRange.setValues(namesForSheet);

  Logger.log(`Названия ${namesForSheet.length} листов записаны в столбец ${outputColumn} листа '${indexSheetName}'.`);
}
Реклама

Скрипт для создания выпадающего списка с названиями листов

Этот пример создает правило проверки данных (выпадающий список) в указанной ячейке, используя названия всех листов в качестве опций. Это полезно для создания пользовательских интерфейсов навигации или выбора источника данных.

/**
 * Создает выпадающий список с названиями всех листов в указанной ячейке.
 *
 * @param {string} targetCellNotation Ячейка в формате A1-нотации (например, 'Sheet1!A1').
 */
function createSheetNameDropdown(targetCellNotation: string): void {
  const ss: GoogleAppsScript.Spreadsheet.Spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  const sheetNames: string[] = getAllSheetNames();

  if (sheetNames.length === 0) {
    Logger.log('Нет листов для создания выпадающего списка.');
    return;
  }

  try {
    const targetRange: GoogleAppsScript.Spreadsheet.Range = ss.getRange(targetCellNotation);

    // Создаем правило проверки данных
    const rule: GoogleAppsScript.Spreadsheet.DataValidation = SpreadsheetApp.newDataValidation()
      .requireValueInList(sheetNames, true) // true - показывать выпадающий список
      .setAllowInvalid(false) // Запретить ввод значений не из списка
      .setHelpText('Выберите название листа из списка.')
      .build();

    targetRange.setDataValidation(rule);
    Logger.log(`Выпадающий список с названиями листов создан в ячейке ${targetCellNotation}.`);

  } catch (e: any) {
    Logger.log(`Ошибка при создании выпадающего списка в ${targetCellNotation}: ${e.message}`);
  }
}

// Пример вызова:
// createSheetNameDropdown('Настройки!B1');

Обработка ошибок и особые случаи

Проверка наличия листов в таблице

Хотя это редкий случай, технически таблица может не содержать листов (например, сразу после создания и удаления единственного листа). Метод getSheets() вернет пустой массив []. Важно проверять длину массива перед дальнейшей обработкой, чтобы избежать ошибок.

const sheets = ss.getSheets();
if (sheets.length === 0) {
  // Обработка случая отсутствия листов
  console.warn('В таблице нет листов.');
  return;
}

Обработка пустых или некорректных имен листов

Google Таблицы не позволяют создавать листы с пустыми именами или именами, содержащими определенные спецсимволы (:, \, /, ?, *, [, ]). Метод getName() всегда вернет валидную строку. Проблемы могут возникнуть, если вы пытаетесь использовать полученные имена для создания ссылок или имен файлов без должной обработки или экранирования, но само получение имен безопасно.

Оптимизация скрипта для больших таблиц

Вызовы SpreadsheetApp.getActiveSpreadsheet(), getSheets() и getName() являются достаточно эффективными. Для таблиц с очень большим количеством листов (сотни) основной прирост производительности достигается за счет минимизации других операций внутри цикла, особенно чтения/записи данных (getValue(), setValue(), getRange(), setValues()).

При записи данных, как в примере writeSheetNamesToIndexSheet, всегда используйте пакетные операции (setValues() вместо множества setValue()). При создании выпадающего списка requireValueInList эффективно работает даже с большим количеством опций.

Заключение и полезные советы

Рекомендации по эффективному использованию скриптов для работы с листами

Кэшируйте результат getSheets(): Если вам нужно многократно обращаться к списку листов или их именам в рамках одного выполнения скрипта, получите массив один раз и работайте с ним.

Используйте map(), filter(), forEach(): Встроенные методы массивов JavaScript часто делают код более читаемым и лаконичным по сравнению с традиционными циклами for.

Минимизируйте обращения к Spreadsheet Service: Группируйте операции чтения и записи.

Добавляйте комментарии и типизацию: Это улучшает поддержку и понимание кода, особенно в сложных скриптах.

Дополнительные ресурсы для изучения Google Apps Script

Официальная документация Google Apps Script

Справочник по Spreadsheet Service


Добавить комментарий