みなさん、こんにちは!
タカハシ(@ntakahashi0505)です。
GASでGoogleフォームを一気に作成するツールを作成しています。
前回の記事はコチラです。
プルダウンリストの質問を追加する方法をお伝えしました。
さて、そのプルダウンですが「お住まいの都道府県は?」という質問にしたいんですね。
てことは、選択肢が47あります。
スクリプト内に配列要素をベタ打ちするの、ちょっと面倒ですね。
ということで、今回はGoogleフォームの質問の選択肢をスプレッドシートのデータから生成するGAS関数の作り方です。
では、行ってみましょう!
前回までのおさらい
前回までに作成したスクリプトはコチラです。
function createEventForm(){ const ss = SpreadsheetApp.getActiveSpreadsheet() const values = ss.getSheetByName('イベント概要').getDataRange().getValues(); const formTitle = values[0][1]; //タイトル const formDescription = values[1][1]; //概要 const form = FormApp.create(formTitle); const id = PropertiesService.getScriptProperties().getProperty('FOLDER_ID'); const formFile = DriveApp.getFileById(form.getId()); DriveApp.getFolderById(id).addFile(formFile); DriveApp.getRootFolder().removeFile(formFile); form.setDescription(formDescription); form.addTextItem().setTitle('氏名').setRequired(true); form.addTextItem().setTitle('会社名'); const validationEmail = FormApp.createTextValidation().requireTextIsEmail().build(); form.addTextItem().setTitle('メールアドレス').setRequired(true).setValidation(validationEmail); form.addMultipleChoiceItem() .setTitle('お持ちのPCのOSは?') .setChoiceValues(['Windows', 'Mac']) .setRequired(true); form.addCheckboxItem() .setTitle('興味があるプログラム言語は?') .setChoiceValues(['VBA', 'Google Apps Script', 'Python']) .showOtherOption(true) .setRequired(true); form.addListItem() .setTitle('お住まいの都道府県は?') .setChoiceValues(prefValues) .setRequired(true); }
だいぶ長くなりましたね。
35行目のsetChoiceValuesメソッドですが、まだ引数として渡す変数prefValuesの定義ができていません。
この変数には、「お住いの都道府県は?」の回答の選択肢の配列をセットする必要がありますね。
47都道府県をスクリプトベタ打ちは大変ですので、スプレッドシートの入力値から配列を生成をしていきたいと思います。
また、それと合わせて、24行目のラジオボタン、29行目のチェックボックスも、スプレッドシートの入力値から配列を生成しますね。
スプレッドシートに選択肢のデータを準備
まず、スプレッドシートに以下のようなシートを追加で用意します。
「項目データ」というシート名で
- A列:OS
- B列:プログラム言語
- C列:都道府県
のデータを列挙したものです。
それぞれの列に存在するデータを、対応するフォームの質問の選択肢として使用していきます。
シートの項目データから選択肢の配列を生成する
まず、以下のスクリプトにより、「項目データ」シートのデータを二次元配列として格納します。
const dataValues = ss.getSheetByName('項目データ').getDataRange().getValues(); dataValues.shift()
shiftメソッドはdataValuesから見出し行を表す先頭の要素を削除するための処理です。
そして、この二次元配列dataValuesと、列数を渡すことで、その列のデータを一次元配列に格納する関数generateArrayを作りました。
コチラです。
/** * シート全体の値を取得した二次元配列から、指定の列のデータを抜き出し一次元配列を構成する * * @param {Object[][]} シートのデータを二次元配列化した配列 * @param {number} 配列の列数(0以上のインデックス) * @return {Object[]} 指定の列(見出しを除く)のデータによる一次元配列 */ function generateArray(values, column){ return values.map(record => record[column]).filter(value => value); }
columnには0以上のインデックス値を渡します。
例えば、以下のようにすれば、A列のデータで構成される一次元配列が得られます。
generateArray(dataValues, 0); //OS
2つのメソッドを使っていますので解説していきます。
mapメソッドで配列から要素を取り出す
まず、mapメソッドですが、二次元配列valuesに含まれる要素(つまり行を表す一次元配列ですが)から、特定のインデックスを取り出して、一次元配列を生成するということをしています。
そもそも、mapメソッドは、対象の配列のすべての要素に対して何らかの処理をした要素で新たな配列を生成するメソッドです。
mapメソッドの引数は関数を渡します(引数に渡す関数をコールバック関数といいますね)。
コールバック関数のパラメーターは以下の3つで、indexとarrayは使わない場合は省略可能です。
- value: 現在処理中の要素
- index: 現在処理中の要素のインデックス
- array: 対象となる配列
今回のmapメソッドは以下でした。
values.map(record => record[column])
二次元配列valuesに含まれる一次元配列について、変数columnで指定したインデックスの要素をreturnして、新たな配列を生成するというものです。
filterメソッドで配列から特定の要素だけ抽出する
mapメソッドの結果として生成される配列は、場合によっては空文字が含まれてしまいます。列によって入っているデータの数が違うからです。
ですから、空文字の要素を取り除くためにfilterメソッドを使っています。
filterメソッドは、対象の配列のすべての要素のうち条件式がtrueの要素だけで新たな配列を生成するメソッドです。
filterメソッドの引数もコールバック関数で、パラメーターとその種類はmap関数のものと同様です。
今回は以下のような使い方で、value自体を条件式としてreturnしています。
map関数の結果の配列.filter(value => value)
空文字は条件式の判定でfalseとみなされますので、生成された配列から除外されるというわけです。
フォームの選択肢の生成を関数化したスクリプト
以上を踏まえて、各質問についてスプレッドシートから選択肢を取得するように、スクリプトを修正してみました。
こちらです。
function createEventForm(){ const ss = SpreadsheetApp.getActiveSpreadsheet() const dataValues = ss.getSheetByName('項目データ').getDataRange().getValues(); dataValues.shift() const values = ss.getSheetByName('イベント概要').getDataRange().getValues(); const formTitle = values[0][1]; //タイトル const formDescription = values[1][1]; //概要 const form = FormApp.create(formTitle); const id = PropertiesService.getScriptProperties().getProperty('FOLDER_ID'); const formFile = DriveApp.getFileById(form.getId()); DriveApp.getFolderById(id).addFile(formFile); DriveApp.getRootFolder().removeFile(formFile); form.setDescription(formDescription); form.addTextItem().setTitle('氏名').setRequired(true); form.addTextItem().setTitle('会社名'); const validationEmail = FormApp.createTextValidation().requireTextIsEmail().build(); form.addTextItem().setTitle('メールアドレス').setRequired(true).setValidation(validationEmail); form.addMultipleChoiceItem() .setTitle('お持ちのPCのOSは?') .setChoiceValues(generateArray(dataValues, 0)) .setRequired(true); form.addCheckboxItem() .setTitle('興味があるプログラム言語は?') .setChoiceValues(generateArray(dataValues, 1)) .showOtherOption(true) .setRequired(true); form.addListItem() .setTitle('お住まいの都道府県は?') .setChoiceValues(generateArray(dataValues, 2)) .setRequired(true); }
4行目で「項目データ」シートのデータを二次元配列getValuesとして取得しています。
25,30,36行目でそれぞれの該当のインデックスを渡して、二次元配列getValuesから該当の一次元配列を取り出し、それをsetChoiceValuesメソッドの引数に渡しています。
上記スクリプトを実行すると、以下のようなフォームが作成されます。
ラジオボタン、チェックボックスの項目も反映されていますね。
プルダウンをクリックすると、以下のように全ての都道府県の選択肢が含まれていることが確認できます。
まとめ
以上、GASでGoogleフォームの質問の選択肢をスプレッドシートのデータから構成する方法をお伝えしました。
質問とその選択肢が増えても、ちょちょっとスクリプトに追加すればOKですね。
あ、今回紹介したのは、あくまで新規フォームの作成時の選択肢の取得ですからね。既に作成してあるフォームの選択肢を変更したいのであれば、スクリプトの作り方もちょっと変わります。
次回ですが、フォームで作れる質問の種類についてまとめています。
どうぞお楽しみに!
連載目次:GASでGoogleフォームを一発で作成するツールを作る
イベントの申し込みやアンケートにとっても便利なGoogleフォーム。スプレッドシートの入力内容をもとに、一発でフォームを作成するツールを作っていきます。- GASでGoogleフォームを作成する最も簡単なスクリプト
- GASで作成したGoogleフォームを指定のフォルダに移動する方法
- GASでGoogleフォームに記述式の質問を追加する方法
- GASでGoogleフォームにメールアドレスの入力欄とバリデーションを追加する方法
- GASでGoogleフォームにラジオボタンの質問を追加する方法
- GASでGoogleフォームにチェックボックス形式の質問を追加する方法
- GASでGoogleフォームにプルダウンリストの質問を追加する方法
- Googleフォームの質問の選択肢をスプレッドシートのデータから生成するGAS関数の作り方
- GASでGoogleフォームに追加できる質問の種類とそのメソッドまとめ