GAS(Google Apps Script)で Googleフォームのプルダウン、チェックボックス、ラジオボタンの選択肢をスプレッドシートの値で更新する方法についての説明です。
同じフォームを長く使っていて、時々フォーム上の選択肢を更新するような場合には、シート上で選択肢の値が管理できるようになるので便利です。
このサンプルコードでできることは、
- シート上の値で選択肢の内容を更新
- プルダウン、チェックボックス、ラジオボタンに対応
- 更新できるの質問は1個(質問番号を指定)
です。
フォームとシートの作成(準備)
プルダウン、チェックボックス、ラジオボタンの選択肢の更新をするので、下記の3つの質問を作成します。選択肢はスプレッドシートから更新するので設定不要です。
- 商品名(プルダウン)
- 商品名(チェックボックス)
- 商品名(ラジオボタン)
次に選択肢をシートで管理するために、シートのA列1行目にタイトルを入れて、2行目からデータを入れます。
これで準備は完了です。
次からが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を指定します。
3. var questionNo = 1
実際には配列として取得されるので1番目の質問項目は、配列の0番目となるので、16行目で questionNo-1 としています。
20. var item = items[questionNo-1]
フォームIDとシートID
GoogleフォームとGoogleスプレッドシートは、IDで取得しています。
フォームIDについては、象と散歩: GASでGoogleフォームの値を取得する(フォームを指定) でも説明していますが、再掲となります。
Googleフォームの編集URLが下記の場合、フォームIDは、赤字の部分です。
シートIDも同様でに赤字の部分となります。
5行目にシートIDを7行目にシートIDを指定していますが、作成したフォームとスプレッドシートのURLを確認して書き換えてください。
5. var formId = ‘1234567890abcdefghijklmnopqrstuvwxyz'
6. //シートID
7. var sheetId = 'zyxwvutsrqponmlkjihgfedcba0987654321'
シート名
9行目にスプレッドシートのシート名を指定します。今回のサンプルではシート名をListとしています。
9. var sheetName = 'List'
データ開始位置
10-13行目でシートのデータ開始を指定します。例ではA列2行目からが選択肢のデータとなりますので、11行目の colName にAを、13行目の rowNum に2を指定します。
11. var colName = 'A'
12. //データ開始行
13. var rowNum = 2
プルダウン選択肢の更新
28行目で、指定したデータ開始位置(A列2行目)からデータがある最終行までを arrList に格納しています。
シート上の 商品A, 商品B, 商品C が、
として格納されます。
そして、31行目で、この配列の値でフォームの質問番号に該当する質問の選択肢(プルダウン)を更新しています。
31. item.asListItem().setChoiceValues(arrList)
asListItem() はプルダウン項目用なので questionNo で指定した質問がプルダウンでない場合にはエラーとなるので注意してください。item.getType() で質問のタイプを確認することができます。プルダウンの質問のタイプは LIST です。
updateFormList を実行します。
ログには実行完了とだけ表示されますが、フォームを参照すると、
シート上のデータでプルダウンの選択肢が更新されています。
チェックボックスの選択肢を更新する
スプレッドシート上にある選択肢を配列に入れて、フォームの選択肢を更新する処理は基本的には同じです。プラダウンのサンプルを実行されたのであれば変更箇所は2箇所だけです。
フォームの質問番号
更新する質問番号を3行目の変数(questionNo)に代入しますが、上記のGoogleフォームの例ではチェックボッククスの質問は2番目なので2を指定します。
3. var questionNo = 2
チェックボックス選択肢の更新
31行目をチェックボックス項目用の asCheckboxItem() に変更します。またチェックボックスは、選択肢に「その他」を設定できますが、showOtherOption() でその他の有無を指定します。
- showOtherOption(true) その他 あり
- showOtherOption(false) その他 なし
その他の選択肢を追加する場合の例となります。
31. item.asCheckboxItem( ).setChoiceValues(arrList).showOtherOption(true)
updateFormList を実行すると、商品A ,B,C と その他の選択肢が追加されます。
チェックボックスを更新するコード全体はこちらです。
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 に 3 を代入します。
3. var questionNo = 3
ラジオボックス選択肢の更新
35行目をラジオボックス用の asMultipleChoiceItem() に変更します。今回は、「その他」の選択肢を付けない showOtherOption(false) とします。
31. item.asMultipleChoiceItem().setChoiceValues(arrList).showOtherOption(false)
updateFormList を実行すると、商品A ,B,C がラジオボックの選択肢として追加されます。
ラジオボックスを更新するコード全体はこちらです。
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追記)
何件かご質問もいただきましたが、上記のサンプルで実行エラーとなる場合の多くは、質問番号で指定した番号の質問タイプと利用するメソッドが違う場合です。
下記のエラーが出力される場合が、
更新しようとする質問のタイプとメソッドが一致していない場合に出力されるエラーで、type:XXXX には、指定した質問のタイプが表示されます。
Gooleフォームで設問に指定できる項目とタイプについて下表にまとめています。
質問項目 | タイプ | 更新に利用するメソッド |
---|---|---|
プルダウン | LIST | asListItem() |
チェックボックス | CHECKBOX | asCheckboxItem() |
ラジオボタン | MULTIPLE_CHOICE | asListItem() |
記述式 | TEXT | - |
段落 | PARAGRAPH_TEXT | - |
ファイルのアップロード | FILE_UPLOAD | - |
均等メモリ | SCALE | - |
選択式(グリッド) | GRID | - |
チェックボックス(グリッド) | CHECKBOX_GRID | - |
日付 | DATE | - |
時刻 | TIME | - |
セクション | PAGE_BREAK | - |
タイトル | SECTION_HEADER | - |
画像 | IMAGE | - |
動画 | VIDEO | - |
セクション、写真、動画なども質問となるので指定する番号に注意してください。
質問タイプを確認するコード
Loggerで指定した質問番号のタイプをログに出力するコードを追加してみてください。
20. var item = items[questionNo-1]
下記のコードを21行目以降に追加します。
Logger.log('質問総数:' + items.length) Logger.log('質問番号:' + questionNo) Logger.log('タイトル:' + item.getTitle()) Logger.log('タイプ:' + item.getType())
下記のように、質問総数、指定した質問番号(questionNo)、質問のタイトル、タイプが出力されます。
情報 質問番号: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を最初に学ぶ一冊として良書です。
Udemy オススメ講座
【新IDE対応】Google Apps Script(GAS)の基礎を完全習得
講師:事務職たらこ
印象に残りやすい手書き風スライドを用いGASの基本的なプログラミングを気軽に学ぶことができる。本講座でGASを活用した自動化ができるレベルにはなれないが、基礎としては十分。
非常に分かりやすく参考にさせていただいております。
返信削除初心者で初歩的な質問かもしれませんが、1点お聞きしたいことがあります。
コードのコピペで2問目、3問目でチェックボックスやラジオボタンで反映させることが出来たのですが、
10. //データ配置列名をA列以外に変更するとスプリクトがエラーになってしまいました。
例えば2問目ではスプレッドシートのデータ配置列をB列に、3問目ではスプレッドシートのデータは一列をC列に変更して反映させることは可能でしょうか?
ご質問ありがとうございます。それぞれの列で違う質問項目の値を変更することは可能です。単純に let colName = 'B' に変更してうまくいかないのであれば、let questionNo = 2 でしている質問番号と質問の型が一致していない可能性があります。プルダウンであれば、asListItem()を、チェックボックスであれば、asCheckboxItem()をラジオボタンであれば asMultipleChoiceItem() を使ってください。
削除ご返信ありがとうございます。
削除お返事が遅くなり申し訳ありません。
質問項目の指定が間違えており、解決できました。
ありがとうございました!
質問失礼します.
返信削除チェックボックスの項目のスクリプトをそのまま(フォームとかのIDは変えてますが)コピペし実行したところ,GASから以下のエラーが返ってきました.
TypeError: Cannot read property 'asCheckboxItem' of undefined
updateFormList @ コード.gs:31
プルダウンのスクリプトに関してはきちんと動作し,フォームに反映されています
解決方法をご教授お願いします.
ラジオボックスの例がチェックボックスと間違った記載をしていました。チェックボックスのソースは2番となります。
削除2行目の let questionNo = 2
で指定しているフォームの質問項目(上記だと2)と
31行目の
asListItem() プルダウン
asCheckboxItem() チェックボックス
asMultipleChoiceItem() ラジオボタン
がマッチしているかを確認してみてください。
質問失礼致します。
返信削除チェックボックスを利用させて頂いておりますが、以下のエラーが出ています。
Exception: Invalid conversion for item type: PAGE_BREAK.
updateFormList @ コード.gs:31
セクションを挟んで2問目ですが、書き方が違うのでしょうか??
セクションを使用した状態でコードを適応させたいのですが、どうにもうまくいきません。
ご助言頂ければ幸いです。
よろしくお願い致します。
エラーでタイプがPAGE_BREAKと出力されていますので、チェックボックスの更新をしようとしているけど、質問項目はPAGE_BREAKでタイプが違っているというエラーです。PAGE_BREAKとはセクションのことです。ページセクションも質問項目のひとつとなります。質問番号を代入する変数 questionNo には、セクションも含めた数値となります。1問目の質問+セクション+2問目の質問 という構成であれば、2問目の数値を更新する場合には3とすればうまくいくと思います。
削除同じようなタイプの不一致でエラーとなられている方も多そうなので、更新しようとしている質問のタイプが何かを確認できるサンプルを追記したいと思います。ご質問ありがとうございました。
指定した質問番号のタイプを確認できるサンプルコードを追記しました。参考になれば幸いです。
削除