0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【GAS】手動コピペはもう卒業!Googleフォームの回答別に処理を自動仕分け

0
Last updated at Posted at 2026-03-24

今までの記事一覧

  1. GASでGoogleForm回答を取得するなら lastRow?(e)?試してみた
  2. onFormSubmit(e)を手動実行でデバッグする方法
  3. どっちを使う?onFormSubmit(e)の values と namedValues の違いと使い分け
  4. onFormSubmit(e) の e.values 配列順のしくみ
  5. Googleフォームで質問を変えても壊れない!cleanFormData(e)でnamedValues防御力をアップ
  6. Googleフォームの質問変更に負けない!「部分一致」と「秘密の暗号」でcleanFormData(e)の防御力を鉄壁に
  7. 手動コピペはもう卒業!Googleフォームの回答別に処理を自動仕分け <この記事
  8. Googleフォームで同時に大量送信されても踏ん張る!LockServiceで順番制御!try - catch - finally でバトンを繋げ!
  9. LockServiceでは順番は守れない?受付番号で順序を保証する方法

前提

この記事は、フォーム回答を保存している スプレッドシート側のGAS を前提にしています。
トリガーは以下を設定しています。

  • スプレッドシートから
  • フォーム送信時

おさらい

前回はフォームの質問文に暗号を仕込むことで、質問文を変更してもGASコードを変えることなく回答を取得できるようにしました。

でも、実際の仕事、ログを取っておしまい…ではないですよね?

実際は回答内容によっていろいろな処理をしなきゃいけないはず。
今回は、前回手に入れた「最強のデータ取得法」を使って、届いた瞬間に適切な部署のシートへ自動で放り込む 「自動仕分け機」 を作りましょう。
手動でコピペはもう卒業です!

今回のタスク

  • 「問い合わせ先」に応じて、対応するシートへ転記する

image.png

スプレッドシートには、フォーム内容が自動で入る「フォームの回答」シートのほかに
「総務部シート」「経理部シート」「営業部シート」「製造部シート」「その他のシート」があります。
image.png

ユーティリティ関数 cleanFormData(e)

では前回同様、ユーティリティ関数を作ります。
質問文の暗号は|name|等を使いましょう。

function cleanFormData(e) {
  const namedValues = e.namedValues;
  const data = {};

  // 全ての質問項目をループ
  for (let key in namedValues) {
    const value = namedValues[key][0];
    
    // もし質問の中に|mail|が入ってたら、一律で mail に入れる
    if (key.includes("|mail|")) {
      data.mail = value;   

    // もし|name|が入ってたら name に入れる
    } else if (key.includes("|name|")) {
      data.name = value;
    
    // もし|dept|が入ってたら dept に入れる
    } else if (key.includes("|dept|")) {
      data.dept = value;
    
    // もし|inq|が入ってたら inq に入れる
    } else if (key.includes("|inq|")) {
      data.inq = value;
    }

    // 質問文そのままでも呼び出せるように保存
    data[key] = value;
  }

  return data;
}

これで「メールアドレス」「お名前」「問い合わせ先」「問い合わせ内容」に
それぞれ「mail」「name」「dept」「inq」というニックネームが付きました。
ニックネームが付いていないものは質問文そのもので呼び出せます。

メイン関数 onFormSubmit(e)

ここからはメイン関数です。

function onFormSubmit(e) {

  // ユーティリティ関数 cleanFormData でフォームからのデータを整形
  const formData = cleanFormData(e);

  // 日付データ(スプレッドシート書き込み用)
  const timestamp = new Date(formData["タイムスタンプ"]);

  // 振り分け先のシートを決める
  let targetSheetName = "その他のシート"; // デフォルト(見つからない時用)

  // 問い合わせ先部署によってシートをかえる分岐処理
  if (formData.dept == "総務部"){
    targetSheetName = "総務部シート";
  } else if (formData.dept == "経理部"){
    targetSheetName = "経理部シート";
  } else if (formData.dept == "営業部"){
    targetSheetName = "営業部シート";
  } else if (formData.dept == "製造部"){
    targetSheetName = "製造部シート";
  }
  // スプレッドシートへの書き込み
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const sheet = ss.getSheetByName(targetSheetName);

  if (sheet){
    sheet.appendRow([timestamp,formData.mail,formData.name,formData.inq]);

  // シート名が見つからなかったらログを出す
  } else {
    Logger.log("エラー:シート「" + targetSheetName + "」が見つかりませんでした。");
  }
}

ユーティリティ関数で整形されたデータが変数formDataに入ります。
formData.deptに問い合わせ先が入っているので、その内容によってif文を使って条件分岐し
書き込み先のシート名を決めていきます。
万が一、フォーム作成担当者が勝手に「社長室」なんてのを追加した場合に備えて、
「総務部」「経理部」「営業部」「製造部」以外の回答がきたら「その他のシート」に行くように
let targetSheetName = "その他のシート"; これを入れておきましょう。

あとはスプレッドシートに書き込むだけ。
sheet.appendRow は、指定したシートの最終行に1行追加するメソッドです。
timestamp フォームのタイムスタンプ  ※注
formData.mail フォームの「メールアドレス」
formData.name フォームの「お名前」
formData.inq フォームの「問い合わせ内容」
これらを[ ]の中に入れてappendRowに渡します。

ここでも万が一、誰かがシート名を変えてしまったときにエラーで止まらないように、

  } else {
    Logger.log("エラー:シート「" + targetSheetName + "」が見つかりませんでした。");
  }

でログを残しておくと安心です。


※注 "タイムスタンプ"は環境によって"Timestamp"になっていることがあります。
もし実行してみて日付がうまく取得できない場合は、スプレッドシートの「フォームの回答」シートの1行目を確認してください。


では、実験してみましょう。

フォームの内容はこれ。
image.png

こちらは「フォームの回答」シート
image.png

そして該当部署のシート
image.png

一瞬で転記されました!
これで手動コピペから卒業です。

おまけ1:手動デバッグ方法

全パターンの振り分けをテストするために、何度もフォーム画面から送信するのは面倒なので、以下のダミーデータを使ったテスト用関数を使うのもアリです。
エディタでtest_onFormSubmitを選択して実行すると、このnamedValuesの内容でonFormSubmit(e)が走ります。

function test_onFormSubmit() {
  const dummyEvent = {
    namedValues: {
      "メールアドレス|mail|": ["abc@mail.com"],
      "お名前|name|": ["ほげ山 ほげ太郎"],
      "問い合わせ先|dept|": ["総務部"], // ここを書き換えて各シートへ飛ぶかテスト!
      "問い合わせ内容|inq|": ["テスト問い合わせ"],
      "タイムスタンプ": ["2026/03/01 12:00:00"]
    }
  };
  onFormSubmit(dummyEvent);
}

おまけ2:if文をスッキリ書く方法(上級編)

if文が増えてくるとコードが長くなるため、実務ではこんなふうに対応表(オブジェクト)で書く方法もあります。

  • 元のコード
  let targetSheetName = "その他のシート"; // デフォルト(見つからない時用)
  
  if (formData.dept == "総務部"){
    targetSheetName = "総務部シート";
  } else if (formData.dept == "経理部"){
    targetSheetName = "経理部シート";
  } else if (formData.dept == "営業部"){
    targetSheetName = "営業部シート";
  } else if (formData.dept == "製造部"){
    targetSheetName = "製造部シート";
  }
  • オブジェクト化したコード
const sheetMap = {
  "総務部": "総務部シート",
  "経理部": "経理部シート",
  "営業部": "営業部シート",
  "製造部": "製造部シート"
};
const targetSheetName = sheetMap[formData.dept] || "その他のシート";

慣れてきたら、こちらの書き方もぜひ試してみてください。

応用:担当ごとにメールする

今回はシートに記入するだけでしたが、例えばこんなふうにメールアドレスを入れると

function onFormSubmit(e) {

  // ユーティリティ関数 cleanFormData でフォームからのデータを整形
  const formData = cleanFormData(e);

  // 日付データ(スプレッドシート書き込み用)
  const timestamp = new Date(formData["タイムスタンプ"]);

  // 振り分け先のシートを決める
  let targetSheetName = "その他のシート"; // デフォルト(見つからない時用)
  
 // メールアドレス
  let mailAddress = "my_mail@mail.com";// ★ここを追加

  // 問い合わせ先部署によってシートを換える分岐処理
  if (formData.dept == "総務部"){
    targetSheetName = "総務部シート";
    mailAddress = "soumu@mail.com";// ★ここを追加
  } else if (formData.dept == "経理部"){
    targetSheetName = "経理部シート";
    mailAddress = "keiri@mail.com";// ★ここを追加
  } else if (formData.dept == "営業部"){
    targetSheetName = "営業部シート";
    mailAddress = "eigyo@mail.com";// ★ここを追加
  } else if (formData.dept == "製造部"){
    targetSheetName = "製造部シート";
    mailAddress = "seizo@mail.com";// ★ここを追加
  }
  // 日付データを 2026/04/01 12:25:36 等の形式にする
  const formattedDate = Utilities.formatDate(timestamp, "JST", "yyyy/MM/dd HH:mm:ss");
  
  // メール本文
  const mailbody = `
   ご担当者様
   
   以下のとおりフォームで問い合わせがありました。
   
   日時:${formattedDate}
   氏名:${formData.name}
   メール:${formData.mail}
   担当部署:${formData.dept}
   質問内容:${formData.inq}
   `
  GmailApp.sendEmail(mailAddress,"問い合わせ内容",mailbody);

  //以下略
  

それぞれの部署あてにメールを送信することもできます。

まとめ

今回はフォームで届いた回答を、内容に応じて処理分岐し、スプレッドシートへの転記や担当者へメールする 「自動仕分け機」 を作りました。

ところが、この便利な仕分け機にも一つだけ弱点が。
もし、イベントの申し込みなどで 「全く同じ瞬間に2人が送信ボタンを押したら」 どうなるでしょう?

そんなわけで、次回はLockServiceを使って同時実行対策をしましょう。

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?