【簡単GAS】Googleドライブ内の全スプレッドシートの中身を集計する方法

アフィリエイト広告を利用しています。
運営者・ポテ

いつもありがとうございます!

ノンプログラマー向け「GAS(Google Apps Script)解説シリーズ」へようこそ。

本稿では「Googleドライブ内の全スプレッドシートの中身を集計する方法」を解説いたします。

Information
  • Google Apps Script(GAS)
    Googleが提供するスクリプト言語で、GoogleスプレッドシートやGoogleドキュメントなどの操作を自動化できます。JavaScriptをベースにしています。
  • GASとVBAの違い
    GASはWebベースで動作し、クラウド上のファイルを操作します。一方、VBAはローカル環境のExcelに組み込まれた言語です。どちらも「自動化」のために使いますが、GASはGoogleの各種サービスと連携しやすいのが強みです。

複数のスプレッドシートの中身を、ひとつにまとめて集計する処理は、GASによる自動化の中でも、基本かつ定番の操作のひとつです。

たとえば、各店舗や営業担当者が管理している売上データを、全社分として一括で集計したい場合などに役立ちます。もちろん、これは一例にすぎません。さまざまな業務で応用が可能です。

この記事では、初心者の方にもわかりやすいよう、丁寧にコードの解説をしています。ぜひ参考にしてみてください。

GAS で Googleドライブ内の全スプレッドシートの中身を集計する方法

アプリーションの仕様

ここでは、以下のようなシステム構成を例にとります。

your_folder/
  ├── フォルダ
  │   ├── ファイルA
  │   ├── ファイルB
  │   └── ファイルC
  └── 複数のファイルの中身を集計する

Google ドライブ内の任意のフォルダ(ここでは your_folder)の直下に、「フォルダ」という名前のサブフォルダと、「複数ファイルの中身を集計する」というスプレッドシートが格納されています。「フォルダ」の中には、ファイルA~Cという3つのスプレッドシートが保存されています。

なお、各スプレッドシートには、次のようなデータが記載されています。代表としてファイルAの中身を示します。

「複数ファイルの中身を集計する」というスプレッドシートにGAS(Google Apps Script)のコードを記述し、「フォルダ」内にある全スプレッドシートの中身を自動的に取得します。

運営者・ポテ

次のセクションで、この処理を実現するスクリプトの具体的な内容を解説します!

コードの実装

まず、コード全文を示します。

Information
  • 本稿での構文のハイライトについて
    本稿で掲載しているコードは Google Apps Script(GAS)ですが、JavaScript の構文としてハイライト表示しています。
  • コードとスクリプトの違い
    コードはプログラムを構成する記述全般を指し、広い意味を持つ言葉です。スクリプトはその中でも、特定の処理を自動で実行するために書かれた比較的軽量なコードのことを指します。
function onOpen() {
  const ui = SpreadsheetApp.getUi();
  ui.createMenu("スクリプトの実行") // メニューのタイトル
    .addItem("フォルダ内のファイルの中身を集計", "listFilesInFolder")
    .addToUi();
}


function listFilesInFolder() {

  const FOLDER_ID = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
  const SPREADSHEET_ID = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
  const SHEET_NAME = '各ファイルの中身';

  const ss = SpreadsheetApp.openById(SPREADSHEET_ID);
  const sheet = ss.getSheetByName(SHEET_NAME);
  if (!sheet) throw new Error(`シート "${SHEET_NAME}" が見つかりません`);

  // 初期化とヘッダ行の追加
  sheet.clearContents();
  sheet.appendRow(['ファイル名', '商品名', '単価', '数量', '合計']);

  const folder = DriveApp.getFolderById(FOLDER_ID);
  const files = folder.getFiles();

  while (files.hasNext()) {
    const file = files.next();

    // Googleスプレッドシートだけを対象に
    if (file.getMimeType() === MimeType.GOOGLE_SHEETS) {
      const externalSS = SpreadsheetApp.openById(file.getId());
      const firstSheet = externalSS.getSheets()[0];
      const values = firstSheet.getDataRange().getValues();

      // ヘッダ(1行目)をスキップして、2行目以降を処理
      for (let i = 1; i < values.length; i++) {
        if (values[i].join('') === '') continue; // 空行はスキップ
        sheet.appendRow([file.getName(), ...values[i].slice(0, 4)]);
      }
    }
  }
}

次に、基本的な動作の流れを説明します。

このコードは、スプレッドシートに追加されたカスタムメニューから実行します。メニュー「スクリプトの実行」から「フォルダ内のファイルの中身を集計」をクリックすると、処理が開始されます。

スクリプトの実行

処理が始まると、指定したフォルダ内のファイルの情報が順に取得され、スプレッドシート内に書き込まれます。

スクリプト実行結果

以上が、基本的な処理の流れです。


運営者・ポテ

ここからは、コードの詳細な解説をしていきます。

function onOpen() {
  const ui = SpreadsheetApp.getUi();
  ui.createMenu("スクリプトの実行") // メニューのタイトル
    .addItem("フォルダ内のファイルの中身を集計", "listFilesInFolder")
    .addToUi();
}

ここでは、スプレッドシートを開いたときに表示されるカスタムメニューを追加しています。

onOpen() は、スプレッドシートを開いたタイミングで自動的に実行される関数です。

この中で、SpreadsheetApp.getUi() を使ってユーザーインターフェースを取得し、「スクリプトの実行」という名前のメニューを作成しています。

そのメニューの中に「フォルダ内のファイルの中身を集計」という項目を追加し、クリックすると exportSheetAsExcel() 関数が実行されるように設定しています。

このようにすることで、ユーザーがスプレッドシートのメニューから、スクリプトを直接呼び出せるようになります。

function listFilesInFolder() {

  const FOLDER_ID = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
  const SPREADSHEET_ID = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
  const SHEET_NAME = '各ファイルの中身';

ここでは、処理対象となるGoogleドライブのフォルダと、結果を書き込むGoogleスプレッドシートの情報を定数として指定しています。

  • FOLDER_ID は、一覧を取得したいGoogleドライブフォルダのIDです。
  • SPREADSHEET_ID は、結果を書き込むスプレッドシートのIDです。
  • SHEET_NAME は、スプレッドシート内の書き込み先シートの名前です。
  const ss = SpreadsheetApp.openById(SPREADSHEET_ID);
  const sheet = ss.getSheetByName(SHEET_NAME);
  if (!sheet) throw new Error(`シート "${SHEET_NAME}" が見つかりません`);

ここでは、出力先となるスプレッドシートと、その中の対象シートを取得しています。

  • const ss = SpreadsheetApp.openById(SPREADSHEET_ID);
    定数 SPREADSHEET_ID で指定したスプレッドシートを開きます。ここで開いたスプレッドシートに、後ほどデータを書き込んでいきます。
  • const sheet = ss.getSheetByName(SHEET_NAME);
    開いたスプレッドシートの中から、定数 SHEET_NAME で指定したシートを取得します。
  • if (!sheet) throw new Error(...)
    指定したシートが存在しなかった場合に、エラーを発生させて処理を中断します。シート名のミスや削除などに備えたエラーハンドリングです。
  // 初期化とヘッダ行の追加
  sheet.clearContents();
  sheet.appendRow(['ファイル名', '商品名', '単価', '数量', '合計']);

ここでは、出力先のシートを初期化し、ヘッダ行を追加しています。

  • sheet.clearContents();
    シート内の既存のデータをすべて削除します。前回の集計結果が残っていると正しい結果にならないため、最初に初期化しておきます。
  • sheet.appendRow([...]);
    新しいデータの書き込みに備えて、1行目にヘッダを追加します。ここでは、各列の項目名として「ファイル名」「商品名」「単価」「数量」「合計」を指定しています。
  const folder = DriveApp.getFolderById(FOLDER_ID);
  const files = folder.getFiles();

ここでは、Googleドライブ上の対象フォルダを取得し、その中にあるファイルの一覧を取得しています。

  • const folder = DriveApp.getFolderById(FOLDER_ID);
    定数 FOLDER_ID で指定されたGoogleドライブのフォルダを取得します。このフォルダの中にあるスプレッドシートが処理対象となります。
  • const files = folder.getFiles();
    フォルダ内に格納されているすべてのファイルを取得します。戻り値は FileIterator オブジェクトとして返します。このオブジェクトは、あとでwhile ループを使って順に処理されます。
Information

FileIterator
複数のファイルを1件ずつ順番に取り出すための特別なデータ構造です。「Iterate」は英語で「繰り返す」「反復する」、という意味を持ちます。

  while (files.hasNext()) {
    const file = files.next();

    // Googleスプレッドシートだけを対象に
    if (file.getMimeType() === MimeType.GOOGLE_SHEETS) {
      const externalSS = SpreadsheetApp.openById(file.getId());
      const firstSheet = externalSS.getSheets()[0];
      const values = firstSheet.getDataRange().getValues();

      // ヘッダ(1行目)をスキップして、2行目以降を処理
      for (let i = 1; i < values.length; i++) {
        if (values[i].join('') === '') continue; // 空行はスキップ
        sheet.appendRow([file.getName(), ...values[i].slice(0, 4)]);
      }
    }
  }
}

ここでは、対象フォルダ内のスプレッドシートを1つずつ処理し、それぞれのファイルからデータを読み込んで、出力用シートに書き込んでいます

  • while (files.hasNext()) {
    files.hasNext() は、まだ処理していないファイルが残っているかどうかを判定する関数です。whileによって、ファイルが残っている間はループを続けます。
  • const file = files.next();
    次のファイルを1つ取得します。
  • if (file.getMimeType() === MimeType.GOOGLE_SHEETS) {
    取得したファイルが Google スプレッドシート形式であるかを判定し、True の場合にのみ処理を続けます。これにより、PDF や画像などの他の形式のファイルは処理の対象から除外されます。
    ここで使われている === は「厳密等価演算子」と呼ばれ、「値」と「型」の両方が完全に一致しているかどうかを判定します。file.getMimeType() は MIMEタイプの文字列(たとえば "application/vnd.google-apps.spreadsheet")を返し、MimeType.GOOGLE_SHEETS も同じ文字列を返します。どちらも文字列型(string)です。したがって、=== を使うことで「MIMEタイプの中身(値)も型も、どちらも一致しているかどうか」をチェックしています。
  • const externalSS = SpreadsheetApp.openById(file.getId());
    対象のスプレッドシートを開きます。externalは「外部の」という意味で、つまり自身(コードを記述しているファイル)とは別の(外部の)という意味です。ここでは、「フォルダ」内にある集計対象スプレッドシートを指します。
  • const firstSheet = externalSS.getSheets()[0];
    集計対象スプレッドシートの1枚目のシートを取得します。
  • const values = firstSheet.getDataRange().getValues();
    シート内の全データ(途中の空白を含む範囲)を2次元配列で取得します。
  • for (let i = 1; i < values.length; i++) {
    ヘッダ行(1行目)をスキップし、2行目以降を処理します。ここで使われている i++ は「インクリメント演算子」と呼ばれ、i = i + 1 と同じ意味です。i の値を1ずつ増やしながらループを繰り返すために使われています。
  • if (values[i].join('') === '') continue;
    行がすべて空白だった場合は、処理をスキップします。
  • sheet.appendRow([file.getName(), ...values[i].slice(0, 4)]);
    ファイル名と、取得した行の左端から4列分のデータを出力用シートに追記します。
運営者・ポテ

以上で解説は終了です。ありがとうございました!

【初心者歓迎】【無料相談受付中】業務改善アプリケーション作成のご相談を承ります

運営者・ポテ

いつもありがとうございます!

限られた時間をより良く使い、日本の生産性を高めたい──

みんなの実用学を運営するソフトデザイン工房では、業務整理や業務改善アプリケーション作成のご相談を承っております。

お気軽にご相談ください。


こちらの記事でも紹介しております。

おわりに

運営者・ポテ

ご覧いただきありがとうございました!

今回の記事では、「Googleドライブ内の全スプレッドシートの中身を集計する方法」を解説いたしました。

お問い合わせやご要望等ございましたら、「お問い合わせ/ご要望」またはコメントにて、ご連絡いただければ幸いでございます。

皆様の人生がより一層素晴らしいものになるよう、少しでもお役に立てれば幸いでございます。

なお、当サイトでは様々な情報を発信しております。もしよろしければ、トップページもご覧いただけると幸いでございます。

この記事を書いた人

運営者・ポテソフトデザイン工房|日々の業務にちょうどいい自動化を
■人生を追求する凡人 ■日本一安全で、気の向くままに自分の時間を過ごせる、こだわりのキャンプ場を作るのが夢 ■ソフトデザイン工房代表(個人事業者) - 業務設計&業務支援アプリケーション作成サービスを展開 ■人生は時間そのもの。ひとりでも多くの人が「より良い人生にするために時間を使って欲しい」と願い、仕事のスキルの向上、余暇の充実、資産形成を研究。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です