ray88’s diary

お仕事で困ったとき用の自分用の覚書

GAS 複数ファイルのライブラリ化

GASライブラリ化と設定管理:複数スプレッドシートで再利用する実践パターン

「あの処理、他のシートでも使いたい…」を解決!
前回のファイル整理&命名規則の応用として、Google Apps Script(GAS)を「ライブラリ化」して、複数スプレッドシート間で再利用する方法を解説します。部署ごとの処理切り替えや通知設定なども柔軟に管理できます!

GASライブラリ化の基本
GASでは、1つのプロジェクトに含まれる複数の`.gs`ファイルをセットで「ライブラリ」として登録し、他のスプレッドシートプロジェクトから呼び出すことができます。

ライブラリ構成例

```
CompanyUtilsLibrary/
├── data.gs // データ操作
├── format.gs // フォーマット
├── validation.gs // バリデーション
├── email.gs // 通知処理
└── config.gs // 設定取得
```

data.gs(例)

function getLastRow_forSpecificColumn(column_num) {
  const sheet = SpreadsheetApp.getActiveSheet();
  return sheet.getRange(sheet.getMaxRows(), column_num)
    .getNextDataCell(SpreadsheetApp.Direction.UP)
    .getRow();
}

function getData_fromRange(range) {
  return SpreadsheetApp.getActiveSheet().getRange(range).getValues();
}

format.gs(例)

function formatDate_YYYYMMDD(date) {
  return Utilities.formatDate(date, 'JST', 'yyyy/MM/dd');
}

function formatNumber_withComma(number) {
  return number.toLocaleString();
}

ライブラリの利用方法(呼び出し側)

function main_monthlyReport() {
  const lastRow = CompanyUtils.getLastRow_forSpecificColumn(1);
  const today = CompanyUtils.formatDate_YYYYMMDD(new Date());

  console.log('最終行:', lastRow);
  console.log('今日:', today);
}

設定値の課題と解決法
ライブラリに固定値を書いてしまうと、他シートでの流用が難しくなります。

× NG例(固定設定)

const SHEET_NAMES = { MAIN: 'メインデータ', LOG: 'ログ' };
const CONFIG = { EMAIL_ADDRESS: 'admin@company.com', START_ROW: 2 };

◎ 解決策1:設定シートで動的に管理(おすすめ)
スプレッドシートに「設定」シートを用意し、そこから値を読み取る方式です。

設定シート例:**

A列 B列
--- ---
シート名 売上データ
通知メール sales@company.com
処理開始行 2

config.gs ライブラリ関数例:**

function getConfig(key) {
  try {
    const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('設定');
    const values = sheet.getRange('A:B').getValues();
    for (let i = 0; i < values.length; i++) {
      if (values[i][0] === key) return values[i][1];
    }
    return null;
  } catch (e) {
    console.log(`設定取得エラー: ${key}`);
    return null;
  }
}

◎ 解決策2:設定オブジェクトを引数で渡す

function processData_withConfig(config) {
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(config.sheetName);
  const startRow = config.startRow || 2;
  const data = sheet.getRange(startRow, 1, sheet.getLastRow() - startRow + 1, 10).getValues();
  // ...
}

◎ 解決策3:ハイブリッド方式(設定 + デフォルト)
設定シートで上書きできない場合は、あらかじめデフォルト設定を定義。

const DEFAULT_CONFIG = {
  startRow: 2,
  emailSubject: 'システム通知',
  retryCount: 3
};

function getConfigWithDefaults(key) {
  const value = getConfig(key);
  return value !== null ? value : DEFAULT_CONFIG[key];
}

実際の活用例:部署ごとの処理を統一ライブラリで

営業部の「設定」シート**

設定項目 設定値
--- ---
シート名 売上実績
通知先 sales@company.com
部署コード SALES

経理部の「設定」シート**

設定項目 設定値
--- ---
シート名 会計データ
通知先 accounting@company.com
部署コード ACCOUNTING

ライブラリ内の関数例**

function generateDepartmentReport() {
  const config = getAllConfig();
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(config['シート名']);
  const deptCode = config['部署コード'];
  const result =
    deptCode === 'SALES'
      ? processSalesReport(sheet)
      : processAccountingReport(sheet);

  sendDepartmentNotification(config['通知先'], deptCode, result);
  return result;
}

ライブラリ化のメリットと注意点

【メリット】

  • 再利用性:共通処理を複数シートで活用
  • 標準化:命名規則と構造が統一
  • 柔軟性:設定シートによる個別対応
  • 保守性:1ヶ所の修正で全体反映

【注意点】

  • 外部ライブラリ呼び出しは若干遅延あり
  • ライブラリ更新の影響を把握する必要あり
  • デバッグがやや複雑
  • バージョン管理の徹底が重要

まとめ:ライブラリ + 設定シートでGASを拡張しよう!
- 複数スプレッドシート間での共通処理はライブラリ化が最適

  • 設定シートによりスクリプトの再利用性と柔軟性が大幅アップ
  • 各部署ごとに処理内容や通知設定を切り替えることも可能
  • 保守性・拡張性に優れた構成で、企業ユースにも最適