【第7部】Googleフォームが2種類でも安心!異なるフォーム回答を1シートにまとめるApps Script活用術

イベントや学会演題登録でよくあるのが、「日本語フォーム」と「英語併記フォーム」を使い分けたいケース。

  • Form1(完全日本語フォーム)
  • Form2(英語のみや、英語+日本語併記フォーム。ただし文字数制限がForm1と異なる。)

でも、最終的には**1つのシートで管理したい!**というのが本音ですよね。

今回は、そんな要望に対応するGoogle Apps Scriptと、その注意点を丁寧に紹介します。


ゴール

  • 回答は Form1 の「フォームの回答 1」シートにすべて集約
  • Form2 の回答は「フォームの回答 2」に集約した後、 Form1 に自動的に追記
  • Form2 からコピーされた行には “フォーム2_英語” という印を付けて由来を明示

最終的な「フォームの回答 1」シートのイメージ:

タイムスタンプ演題タイトルフォーム由来
2025/04/10山田花子ABC…
2025/04/12JohnSmithDEF…Form2_英語

使用スクリプト(コピペOK)

function copyNewForm2RowsToForm1WithOriginColumn() {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const sheetA = ss.getSheetByName("フォームの回答 1");
  const sheetB = ss.getSheetByName("フォームの回答 2");

  const dataA = sheetA.getDataRange().getValues();
  const dataB = sheetB.getDataRange().getValues();

  const headerA = dataA[0];
  const headerB = dataB[0];
  const rowsA = dataA.slice(1);
  const rowsB = dataB.slice(1);

  // 「フォーム由来」列の確認と追加(無ければ作成)
  let originColIndex = headerA.findIndex(col => col === "フォーム由来");
  if (originColIndex === -1) {
    sheetA.getRange(1, headerA.length + 1).setValue("フォーム由来");
    originColIndex = headerA.length;
  }

  const tsIndexA = headerA.findIndex(col => col.includes("タイムスタンプ"));
  const tsIndexB = headerB.findIndex(col => col.includes("タイムスタンプ"));
  if (tsIndexA === -1 || tsIndexB === -1) return;

  const existingTimestamps = new Set(rowsA.map(row => new Date(row[tsIndexA]).toISOString()));

  const newRows = [];

  for (const rowB of rowsB) {
    const ts = rowB[tsIndexB];
    if (!ts) continue;
    const tsISO = new Date(ts).toISOString();
    if (!existingTimestamps.has(tsISO)) {
      const paddedRow = [...rowB];
      while (paddedRow.length < originColIndex) paddedRow.push("");
      paddedRow[originColIndex] = "フォーム2_英語";
      newRows.push(paddedRow);
    }
  }

  if (newRows.length > 0) {
    newRows.forEach(row => sheetA.appendRow(row));
  }
}

この方法のメリット

ポイント内容
Form1 への回答一元化管理が楽・出力処理もシンプルに
Form1とForm2で文字数制限を変更可能2つのGoogle formを準備するため、制限文字数の変更が可能に
上書きなし・破壊なし既存回答・手動編集を壊さない
フォーム種別が分かる“フォーム由来” 列で出力判別可能
トリガーはそのまま使える以前の mainOnSubmit() などの自動処理も Form1基準で継続利用可能

重要な注意点(事前にチェック!)

フォーム2はフォーム1をコピーして作ればOK!質問を英訳するだけで準備完了

異なる言語(例:英語)で同じ質問構成のフォームを作りたいとき、1つずつ手入力する必要はありません。 Googleフォームには「質問のインポート」機能があり、フォーム1の構成を丸ごとコピーしてフォーム2を作ることができます。

操作手順(Form1をもとにForm2を作成)

  1. Googleフォームで「空白のフォーム」を新規作成
  2. メニューから「質問をインポート」をクリック(📄→のアイコン)
  3. コピー元となる Form1 を選択
  4. すべての質問を選択し「インポート」
  5. 各質問文を、日本語+英語併記または英語のみに書き換える
  6. もし必要なら、文字数制限の設定をForm1とForm2では変更が可能。
  7. *Google formでは半角と全角の区別がないため、日本語100文字なら英語200文字に相当するか。

例:質問文の書き換え例

  • Form1:演題タイトルを入力してください
  • Form2:Please enter the title. 演題タイトルを入力してください

こうすることで、意味は同じ、列名も対応するので、列の順番さえ揃っていればスクリプトで問題なく処理できます。

メリット

  • フォーム構成が一発で揃う(列のずれなし)
  • スプレッドシートの列も同様に揃う
  • 翻訳だけで多言語対応フォームが完成

スプレッドシートの列の順番は、あとから手で揃えてもOK!

  • Googleフォームから自動生成されたスプレッドシートの列の順番がずれてしまっていても、 列見出し(A〜Z列)をドラッグして並び替えることで対応できます。

操作手順:

  1. 「フォームの回答 2」のシートを開く
  2. 1行目の列見出し(A〜Z)を見ながら、Form1 と同じ順にドラッグで並び替え
  3. これで列の順番が一致し、スクリプトが正しく動作します

質問数や列数が異なる場合の動作

ケース挙動
Form1 にだけある列空白で埋められる(問題なし)
「フォーム由来」列Form2 由来のみ “フォーム2_英語” と記録される(Form1は空欄)

応用ステップ

このスクリプトで Form2 → Form1 の統合が完了したら、以前にご紹介した以下のような自動化処理と連携できます:

  • 演題番号の付与(【第3部】で紹介)
  • 抄録整形 → Google Docs(【第4部】で紹介)
  • メール送信 + PDF出力(【第5部】で紹介)
  • 自動トリガーによる実行(【第6部】で紹介)

※今回紹介したスクリプトは、【第6部】で紹介したトリガー時に動作させる関数:既存の mainOnSubmit() にそのまま組み込めます!


まとめ

  • Googleフォームを2種類に分けても、回答を1シートにまとめて管理できる!
  • 質問文が異なっていても、意味が同じであれば列を揃えることで対応可能
  • スクリプトでは「列の順序と数」が一致していれば正しく動作します
  • 必要に応じて列順を手で整えれば、フォームの構成を変えずに済む柔軟な運用ができます

コメント

タイトルとURLをコピーしました