見出し画像

Google Apps Scriptのイベントトリガー「編集」の活用例

Google Apps Script(GAS)とGoogleスプレッドシートを組み合わせたとき、イベントトリガー「編集」はセルの値が更新された際に作業を自動化できる有用な仕組みです。

この記事では、編集イベントを使った効率的でエラーの少ないスクリプトを実現する方法について、具体的な例とともに紹介します。

なお、編集イベント自体の説明は前回の記事をご参照ください。


▍編集イベントで取得できる情報

以下のコードで、編集されたセルの更新後の値を出力できます。

function editHandler(e) {
  console.log(e.value);
}

このように、e がイベントを表し、その中にイベント情報が入っています。編集イベントの代表的な情報は以下です。

  • oldValue:更新前の値

  • value:更新後の値

  • range:編集されたセル範囲(Rangeオブジェクト)

  • source:編集されたスプレッドシート(Spreadsheetオブジェクト)

他にもユーザー情報なども取得できます。詳細は以下の公式リファレンスをご参照ください。RangeオブジェクトやSpreadsheetオブジェクトへのリンクも以下にあります。

▍具体例

■状況

以下のような構成の、"main" という名前のシートがあるとします。

シート例

C列(処理状況)は入力規則によって、「未処理」「処理」「処理済」を選ぶようになっています。ここで「処理」を選ぶと、所定の処理を自動実行するとします。
「所定の処理」がイメージしづらければ、メール送付やGoogleカレンダーへの予定追加を行うものだとお考えください。

イベントトリガーの設定は以下です。editHandler 関数の内容は後述します。イベントの種類は「編集時」です。

イベントトリガーの設定

■コード例

コードの例は以下です。なお、ここでは具体的な自動処理の内容は割愛しています。

function editHandler(e) {
  // 編集されたシートを取得
  const sheet = e.source.getActiveSheet();

  // シート名が"main"でなければ処理を終了
  if (sheet.getSheetName() !== "main") {
    return;
  }

  // 編集されたセル範囲を取得
  const range = e.range;

  // 編集されたセルの列が3列目でなければ処理を終了
  if (range.getColumn() !== 3) {
    return;
  }

  // 編集後の値が"処理"でなければ処理を終了
  if (e.value !== "処理") {
    return;
  }

  // 自動処理を実行


  // 処理状況を"処理済"に変更
  range.setValue("処理済");
}

コードでは、編集されたシート名が "main" で、編集されたセルが3列目で、編集後(更新後)の値が "処理" の場合のみ自動処理を実行しています。それぞれ、source、range、valueといった、編集イベントで取得できる情報を活用しています。これにより、不要な処理や意図しない処理が実行されることを防いでいます。

最後に "処理済" と記入しているので、シート上の結果は以下のようになります。

処理実行後のシート

■オマケ

以下は、Googleカレンダーへの予定追加を例に、エラー処理も実装したものです。なお、実際に動かす場合はGoogleカレンダーのIDは変更ください。

const CALENDAR_ID = "GoogleカレンダーのID";

function editHandler(e) {
  // 編集されたシートを取得
  const sheet = e.source.getActiveSheet();

  // シート名が"main"でなければ処理を終了
  if (sheet.getSheetName() !== "main") {
    return;
  }

  // 編集されたセル範囲を取得
  const range = e.range;

  // 編集された列が3列目でなければ処理を終了
  if (range.getColumn() !== 3) {
    return;
  }

  // 編集後の値が"処理"でなければ処理を終了
  if (e.value !== "処理") {
    return;
  }

  // 編集された行を取得
  const rowData = sheet.getRange(range.getRow(), 1, 1, sheet.getLastColumn()).getValues()[0];

  // 行の先頭の要素(1列目に該当)を取得
  const date = rowData[0];

  // 行の2番目の要素(2列目に該当)を取得
  const description = rowData[1];

  try {
    // Googleカレンダーを取得
    const calendar = CalendarApp.getCalendarById(CALENDAR_ID);

    // Googleカレンダーに予定を追加
    calendar.createAllDayEvent(description, date);

  } catch (error) {
    // 処理状況を"エラー"に変更
    range.setValue("エラー");    

    // エラーをスロー
    throw new Error(`Googleカレンダーの予定追加に失敗しました。${error.message}`);
  }

  // 処理状況を"処理済"に変更
  range.setValue("処理済");
}

ちなみに、中央付近の「編集された行を取得」の記述はGoogleスプレッドシートから行をまとめて取得する際によく使う書き方です。複数のセルの値を取得する場合、1つ1つのセルの値を取得するよりも、行の値をまとめて取得した方が処理が速くなります。
なお、ここでは1行で記述していますが、以下のように分解しても構いません。

// 行番号を取得
const rowIndex = range.getRow();

// 最終列を取得
const lastColumnIndex = sheet.getLastColumn();

// 編集された行範囲の値を取得
const rangeData = sheet.getRange(rowIndex, 1, 1, lastColumnIndex).getValues();

// 行範囲から、1行分を取得
const rowData = rangeData[0];

▍おわりに

編集イベントは、スクリプトの自動実行を制御するのにとても有用な仕組みです。シート編集時の自動実行を実現したい方は、今回ご紹介した例を参考にご自身の環境でも試して見てください!

この記事が、今後Google Apps Scriptで自動化を進める方の参考になれば嬉しいです。


私たちのデジタル技術活用のメモが次のマガジンにあります。よろしければ覗いてみてください!


この記事が気に入ったらサポートをしてみませんか?