Translate

2021年3月6日

Googleフォームの選択肢をシートのデータで更新する

ゾウでもわかる Google Apps Script

GAS(Google Apps Script)で Googleフォームのプルダウン、チェックボックス、ラジオボタンの選択肢をスプレッドシートの値で更新する方法についての説明です。

同じフォームを長く使っていて、時々フォーム上の選択肢を更新するような場合には、シート上で選択肢の値が管理できるようになるので便利です。

このサンプルコードでできることは、

  • シート上の値で選択肢の内容を更新
  • プルダウン、チェックボックス、ラジオボタンに対応
  • 更新できるの質問は1個(質問番号を指定)

です。


フォームとシートの作成(準備)

プルダウン、チェックボックス、ラジオボタンの選択肢の更新をするので、下記の3つの質問を作成します。選択肢はスプレッドシートから更新するので設定不要です。

  1. 商品名(プルダウン)
  2. 商品名(チェックボックス)
  3. 商品名(ラジオボタン)
Googleフォームのサンプル

次に選択肢をシートで管理するために、シートのA列1行目にタイトルを入れて、2行目からデータを入れます。

Googleスプレッドシート上の選択肢

これで準備は完了です。

次からがGoogle Apps Scriptの例になります。


プルダウンの選択肢を更新する

質問番号を指定して質問の選択肢を更新するという簡単なサンプルです。このサンプルコードはプルダウンの質問項目の選択肢用なので、指定した質問番号がチェックボックス、ラジオボタンの場合にはエラーとなります。

上記フォーム例では、プルダウンは1番目の質問です。

下記サンプルコードをスクリプトエディタのコードに貼り付けてください。

function updateFormList() {
  //フォームの質問番号
  var questionNo = 1
  //フォームID
  var formId  = '1234567890abcdefghijklmnopqrstuvwxyz'
  //シートID
  var sheetId = 'zyxwvutsrqponmlkjihgfedcba0987654321'
  //シート名
  var sheetName = 'List'
  //データ配置列名
  var colName = 'A'
  //データ開始行
  var rowNum = 2
 
  //フォームの取得
  var form = FormApp.openById(formId)
  //全質問項目を取得
  var items = form.getItems()
  //questionNoで指定した質問項目を指定(配列は0から始まるので-1)
  var item = items[questionNo-1]

  //スプレッドシートを取得
  var sheet = SpreadsheetApp.openById(sheetId).getSheetByName(sheetName)
  //シートの最終行を取得
  var lastRow = sheet.getLastRow()

  //リスト内容の取得
  var arrList = sheet.getRange(colName + rowNum + ':' + colName + lastRow).getValues()

  //選択肢をフォームに反映
  item.asListItem().setChoiceValues(arrList)
}

フォームの質問番号

更新する質問番号を3行目の変数(questionNo)に代入します。上記のGoogleフォームの例ではプルダウンの質問は1番目なので1を指定します。

 2.  //更新するフォームの質問番号
 3.  var questionNo = 1

実際には配列として取得されるので1番目の質問項目は、配列の0番目となるので、16行目で questionNo-1 としています。

19.  //questionNoで指定した質問項目を指定(配列は0から始まるので-1)
20.  var item = items[questionNo-1]

フォームIDとシートID

GoogleフォームとGoogleスプレッドシートは、IDで取得しています。

フォームIDについては、象と散歩: GASでGoogleフォームの値を取得する(フォームを指定) でも説明していますが、再掲となります。

Googleフォームの編集URLが下記の場合、フォームIDは、赤字の部分です。

https://docs.google.com/forms/d/1234567890abcdefghijklmnopqrstuvwxyz/edit

シートIDも同様でに赤字の部分となります。

https://docs.google.com/spreadsheets/d/zyxwvutsrqponmlkjihgfedcba0987654321/edit

5行目にシートIDを7行目にシートIDを指定していますが、作成したフォームとスプレッドシートのURLを確認して書き換えてください。

 4.  //フォームID
 5.  var formId = ‘1234567890abcdefghijklmnopqrstuvwxyz'
 6.  //シートID
 7.  var sheetId = 'zyxwvutsrqponmlkjihgfedcba0987654321'

シート名

9行目にスプレッドシートのシート名を指定します。今回のサンプルではシート名をListとしています。

 8.  // シート名
 9.  var sheetName = 'List'

データ開始位置

10-13行目でシートのデータ開始を指定します。例ではA列2行目からが選択肢のデータとなりますので、11行目の colName にAを、13行目の rowNum に2を指定します。

10.  //データ配置列名
11.  var colName = 'A'
12.  //データ開始行
13.  var rowNum = 2

プルダウン選択肢の更新

28行目で、指定したデータ開始位置(A列2行目)からデータがある最終行までを arrList に格納しています。

シート上の 商品A, 商品B, 商品C が、

arrList[0]    商品A
arrList[1]    商品B
arrList[2]    商品C

として格納されます。

そして、31行目で、この配列の値でフォームの質問番号に該当する質問の選択肢(プルダウン)を更新しています。

30. //選択肢を更新する
31. item.asListItem().setChoiceValues(arrList)

asListItem() はプルダウン項目用なので questionNo で指定した質問がプルダウンでない場合にはエラーとなるので注意してください。item.getType() で質問のタイプを確認することができます。プルダウンの質問のタイプは LIST です。

updateFormList を実行します。

スクリプトエディタから実行

ログには実行完了とだけ表示されますが、フォームを参照すると、

Googleフォーム プルダウン形式

シート上のデータでプルダウンの選択肢が更新されています。


チェックボックスの選択肢を更新する

スプレッドシート上にある選択肢を配列に入れて、フォームの選択肢を更新する処理は基本的には同じです。プラダウンのサンプルを実行されたのであれば変更箇所は2箇所だけです。


フォームの質問番号

更新する質問番号を3行目の変数(questionNo)に代入しますが、上記のGoogleフォームの例ではチェックボッククスの質問は2番目なので2を指定します。

 2.  //更新するフォームの質問番号
 3.  var questionNo = 2

チェックボックス選択肢の更新

31行目をチェックボックス項目用の asCheckboxItem() に変更します。またチェックボックスは、選択肢に「その他」を設定できますが、showOtherOption() でその他の有無を指定します。

  • showOtherOption(true)    その他 あり
  • showOtherOption(false)   その他 なし

その他の選択肢を追加する場合の例となります。

30. //選択肢を更新する
31. item.asCheckboxItem( ).setChoiceValues(arrList).showOtherOption(true)

updateFormList を実行すると、商品A ,B,C と その他の選択肢が追加されます。

Googleフォーム チェックボックス形式

チェックボックスを更新するコード全体はこちらです。

function updateFormList() {
  //フォームの質問番号
  var questionNo = 2
  //フォームID
  var formId  = '1234567890abcdefghijklmnopqrstuvwxyz'
  //シートID
  var sheetId = 'zyxwvutsrqponmlkjihgfedcba0987654321'
  //シート名
  var sheetName = 'List'
  //データ配置列名
  var colName = 'A'
  //データ開始行
  var rowNum = 2
 
  //フォームの取得
  var form = FormApp.openById(formId)
  //全質問項目を取得
  var items = form.getItems()
  //questionNoで指定した質問項目を指定(配列は0から始まるので-1)
  var item = items[questionNo-1]

  //スプレッドシートを取得
  var sheet = SpreadsheetApp.openById(sheetId).getSheetByName(sheetName);
  //シートの最終行を取得
  var lastRow = sheet.getLastRow()

  //リスト内容の取得
  var arrList = sheet.getRange(colName + rowNum + ':' + colName + lastRow).getValues()

  //選択肢をフォームに反映
  item.asCheckboxItem( ).setChoiceValues(arrList).showOtherOption(true)
}

ラジオボックスの選択肢を更新する

続いて、ラジオボックの場合となります。こちらも変更箇所は2箇所だけです。


フォームの質問番号

ラジオボックスの質問は3番目なので questionNo に を代入します。

 2.  //更新するフォームの質問番号
 3.  var questionNo = 3

ラジオボックス選択肢の更新

35行目をラジオボックス用の asMultipleChoiceItem() に変更します。今回は、「その他」の選択肢を付けない showOtherOption(false) とします。

30. //選択肢を更新する
31. item.asMultipleChoiceItem().setChoiceValues(arrList).showOtherOption(false)

updateFormList を実行すると、商品A ,B,C がラジオボックの選択肢として追加されます。

Googleフォーム ラジオボタン形式

ラジオボックスを更新するコード全体はこちらです。

function updateFormList() {
  //フォームの質問番号
  var questionNo = 3
  //フォームID
  var formId  = '1234567890abcdefghijklmnopqrstuvwxyz'
  //シートID
  var sheetId = 'zyxwvutsrqponmlkjihgfedcba0987654321'
  //シート名
  var sheetName = 'List'
  //データ配置列名
  var colName = 'A'
  //データ開始行
  var rowNum = 2
 
  //フォームの取得
  var form = FormApp.openById(formId)
  //全質問項目を取得
  var items = form.getItems()
  //questionNoで指定した質問項目を指定(配列は0から始まるので-1)
  var item = items[questionNo-1]

  //スプレッドシートを取得
  var sheet = SpreadsheetApp.openById(sheetId).getSheetByName(sheetName)
  //シートの最終行を取得
  var lastRow = sheet.getLastRow()

  //リスト内容の取得
  var arrList = sheet.getRange(colName + rowNum + ':' + colName + lastRow).getValues()

  //選択肢を更新する
  item.asMultipleChoiceItem().setChoiceValues(arrList).showOtherOption(false)
}

更新する質問のタイプを確認しよう(22.2.11追記)

何件かご質問もいただきましたが、上記のサンプルで実行エラーとなる場合の多くは、質問番号で指定した番号の質問タイプと利用するメソッドが違う場合です。

下記のエラーが出力される場合が、

エラー Exception: Invalid conversion for item type: XXXXX

更新しようとする質問のタイプとメソッドが一致していない場合に出力されるエラーで、type:XXXX には、指定した質問のタイプが表示されます。

Gooleフォームで設問に指定できる項目とタイプについて下表にまとめています。

質問項目タイプ更新に利用するメソッド
プルダウンLISTasListItem()
チェックボックスCHECKBOXasCheckboxItem()
ラジオボタンMULTIPLE_CHOICEasListItem()
記述式TEXT-
段落PARAGRAPH_TEXT-
ファイルのアップロードFILE_UPLOAD-
均等メモリSCALE-
選択式(グリッド)GRID-
チェックボックス(グリッド)CHECKBOX_GRID-
日付DATE-
時刻TIME-
セクションPAGE_BREAK-
タイトルSECTION_HEADER-
画像IMAGE-
動画VIDEO-

セクション、写真、動画なども質問となるので指定する番号に注意してください。


質問タイプを確認するコード

Loggerで指定した質問番号のタイプをログに出力するコードを追加してみてください。

19. //questionNoで指定した質問項目を指定(配列は0から始まるので-1)
20. var item = items[questionNo-1]

下記のコードを21行目以降に追加します。

  Logger.log('質問総数:' + items.length)
  Logger.log('質問番号:' + questionNo)
  Logger.log('タイトル:' + item.getTitle())
  Logger.log('タイプ:' + item.getType())

下記のように、質問総数、指定した質問番号(questionNo)、質問のタイトル、タイプが出力されます。

情報 質問総数:3
情報 質問番号:1
情報 タイトル:商品名(プルダウン)
情報 タイプ:LIST

下記は、更新はせずに、指定した質問番号のタイプを確認するサンプルコードです。

function updateFormList() {
  //フォームの質問番号
  var questionNo = 1
  //フォームID
  var formId  = '1234567890abcdefghijklmnopqrstuvwxyz'
 
  //フォームの取得
  var form = FormApp.openById(formId)
  //全質問項目を取得
  var items = form.getItems()
  //questionNoで指定した質問項目を指定(配列は0から始まるので-1)
  var item = items[questionNo-1]

  Logger.log('質問総数:' + items.length)
  Logger.log('質問番号:' + questionNo)
  Logger.log('タイトル:' + item.getTitle())
  Logger.log('タイプ:' + item.getType())
}

スプレッドシートのメニューから実行する

下記のコードを追加すると、スプレッドシートを開いたときに、メニューに "Form選択肢更新" が追加されます。

スプレッドシートのメニューに追加

”商品名更新” を選択すると updateFormList() がスクリプト エディタを開かなくても実行できます。

function onOpen(){ 
  SpreadsheetApp
    .getActiveSpreadsheet()
    .addMenu('Form選択肢更新', [
      {name: '商品名更新', functionName: 'updateFormList'},
    ]);
}

GASの基礎を学べる参考図書

ある程度プログラミンがわかっていれば、WEBやYoutubeでも十分に調べられると思いますが、初歩的なところからであれば参考図書は有効な学習手段です。

詳解! Google Apps Script完全入門 [第3版]」は、プラグラミング初心者にわかりやすく説明されています。GASを最初に学ぶ一冊として良書です。

8 件のコメント:

  1. 非常に分かりやすく参考にさせていただいております。
    初心者で初歩的な質問かもしれませんが、1点お聞きしたいことがあります。

    コードのコピペで2問目、3問目でチェックボックスやラジオボタンで反映させることが出来たのですが、
    10. //データ配置列名をA列以外に変更するとスプリクトがエラーになってしまいました。

    例えば2問目ではスプレッドシートのデータ配置列をB列に、3問目ではスプレッドシートのデータは一列をC列に変更して反映させることは可能でしょうか?

    返信削除
    返信
    1. ご質問ありがとうございます。それぞれの列で違う質問項目の値を変更することは可能です。単純に let colName = 'B' に変更してうまくいかないのであれば、let questionNo = 2 でしている質問番号と質問の型が一致していない可能性があります。プルダウンであれば、asListItem()を、チェックボックスであれば、asCheckboxItem()をラジオボタンであれば asMultipleChoiceItem() を使ってください。

      削除
    2. ご返信ありがとうございます。
      お返事が遅くなり申し訳ありません。
      質問項目の指定が間違えており、解決できました。
      ありがとうございました!

      削除
  2. 質問失礼します.
    チェックボックスの項目のスクリプトをそのまま(フォームとかのIDは変えてますが)コピペし実行したところ,GASから以下のエラーが返ってきました.

    TypeError: Cannot read property 'asCheckboxItem' of undefined
    updateFormList @ コード.gs:31

    プルダウンのスクリプトに関してはきちんと動作し,フォームに反映されています
    解決方法をご教授お願いします.

    返信削除
    返信
    1. ラジオボックスの例がチェックボックスと間違った記載をしていました。チェックボックスのソースは2番となります。
      2行目の let questionNo = 2
      で指定しているフォームの質問項目(上記だと2)と
      31行目の
      asListItem() プルダウン
      asCheckboxItem() チェックボックス
      asMultipleChoiceItem() ラジオボタン
      がマッチしているかを確認してみてください。

      削除
  3. 質問失礼致します。

    チェックボックスを利用させて頂いておりますが、以下のエラーが出ています。

    Exception: Invalid conversion for item type: PAGE_BREAK.

    updateFormList @ コード.gs:31

    セクションを挟んで2問目ですが、書き方が違うのでしょうか??

    セクションを使用した状態でコードを適応させたいのですが、どうにもうまくいきません。
    ご助言頂ければ幸いです。
    よろしくお願い致します。

    返信削除
    返信
    1. エラーでタイプがPAGE_BREAKと出力されていますので、チェックボックスの更新をしようとしているけど、質問項目はPAGE_BREAKでタイプが違っているというエラーです。PAGE_BREAKとはセクションのことです。ページセクションも質問項目のひとつとなります。質問番号を代入する変数 questionNo には、セクションも含めた数値となります。1問目の質問+セクション+2問目の質問 という構成であれば、2問目の数値を更新する場合には3とすればうまくいくと思います。

      同じようなタイプの不一致でエラーとなられている方も多そうなので、更新しようとしている質問のタイプが何かを確認できるサンプルを追記したいと思います。ご質問ありがとうございました。

      削除
    2. 指定した質問番号のタイプを確認できるサンプルコードを追記しました。参考になれば幸いです。

      削除

アクセス上位(過去7日間)