LoginSignup
2
3
記事投稿キャンペーン 「2024年!初アウトプットをしよう」

【0からGASを学ぶ】GASを用いたGoogleフォーム内の項目設定チートシート

Posted at

はじめに

本シリーズでは、GASの始め方や便利な使い方、ビジネス活用まで幅広く解説します。シリーズをひと通り読んでいただければ、あなたもきっとGASマスターになれるはずです。

シリーズの対象者

  • そもそもGASってなんだかわからない
  • GASを学びたいけど何から始めればいいかわからない方
  • GASはわかり始めたけど、もっと活用ができないかと模索している方
  • とにかくGoogleが好き! という方

前回記事

GoogleフォームをGASで更新する

では早速始めていきましょう。【0からGASを学ぶ】シリーズの第19回は「GASを用いたGoogleフォーム内の項目設定チートシート」です。今回は、Googleフォームで提供している各種フォーム項目をGASからいじくってみます。あの項目はどうやっていじるんだ?と疑問に思ったときはこのチートシートを活用してください。Googleフォームは単なる質問受付に使えるだけではなく、フォーム自体をテストとして扱い、自動採点やフィードバックを行うこともできる非常に強力なツールです。とはいえ、本チートシートでは主たる用途である質問受付に特化してお伝えします。

事前準備

Googleフォームを作成

今回のいじくり先のフォームを作成していきましょう。項目は空で構いません。GAS側でどんどん項目を追加していきます。

GASエディタを開く

準備したGoogleフォームからコンテナバインド型でGASプログラムを記述していきましょう。Googleフォームからコンテナバインド型のGASを開く場合は、こちらを参考にしてください。では、どんどんいきますよ、ついてきてください。

チートシート開始

チートシートに記載の内容は、以下を併せて確認すると理解が深まります。

フォームそのもの

設定

Googleフォームの設定項目は非常に多いです。「回答者のメールアドレスを収集するか」や「クイズ形式とするか(いわゆるテストモード)」、「回答時の確認メッセージ」「受付をクローズとするか」など、多岐にわたります。チートシートでは代表的な以下の5点を設定する方法をお伝えします。

メソッド名 説明
setTitle(title) フォームのタイトルを設定します。
setDescription(description) フォームの説明を設定します。
setConfirmationMessage(message) フォームの確認メッセージを設定します。
setCustomClosedFormMessage(message) フォームが回答を受け付けていない場合に表示するメッセージを設定します。
setAcceptingResponses(enabled) フォームが現在回答を受け付けているかどうかを設定します。
フォームに対する設定
const form = FormApp.getActiveForm();
form.setTitle('Qiita019_項目の新規作成')
    .setDescription('このフォームはQiita019で項目の新規作成を説明するためのものです。')
    .setConfirmationMessage('Qiita019の回答を受け付けました。')
    .setCustomClosedFormMessage('Qiita019の回答は現在受け付けておりません。')
    .setAcceptingResponses(true);

項目の一括削除

フォーム内の項目を一括削除
const form = FormApp.getActiveForm();
form.getItems().forEach(function(item){
  form.deleteItem(item);
});

項目の一部削除

何をもとに項目を判断するかは任意で決めてよいですが、一般的には項目タイトルがやりやすいと思います。

フォーム内の項目を一部削除
const form = FormApp.getActiveForm();
form.getItems().forEach(function(item){
  if (item.getTitle()=='削除したい項目名') {
    form.deleteItem(item);
  }
});

項目をいじくる

全項目共通

GoogleフォームにGASから項目を追加、更新する場合は、前回もお伝えした通り、addXXXXItem()とするかasXXXXItem()とし、項目を生成します。その際に、全項目に共通して使われるのが以下の3つのメソッドとなります。

メソッド名 説明
setTitle(title) 項目のタイトルを設定します。
setHelpText(text) 項目の説明文を設定します。
setRequired(enabled) 項目が回答必須かどうかを設定します。
※本項目はレイアウト要素(セクションヘッダーや画像項目等)には不要です。

記述式

記述式
const form = FormApp.getActiveForm();
let textValidation_number = FormApp.createTextValidation()
                                   .requireNumber()
                                   .setHelpText('数字で入力してください。')
                                   .build();

form.addTextItem().setTitle('記述式の質問項目')
                  .setHelpText('記述式の質問項目に対する説明文')
                  .setValidation(textValidation_number)
                  .setRequired(true);

記述式の場合には、記載した内容に対する検証を行うことができます。上記の場合はrequireNumberを用いたため数値であるかどうかを判断しています。その他には以下のようなものがあります。

メソッド名 説明
requireNumber() テキスト アイテムは数値にする必要があります。
requireNumberBetween(start, end) テキスト アイテムは、開始から終了までの範囲内の数値(両端を含む)にする必要があります。
requireNumberGreaterThan(number) テキスト アイテムは、指定した値より大きい数値である必要があります。
requireTextIsEmail() テキスト アイテムはメールアドレスである必要があります。
requireTextMatchesPattern(pattern) パターン(正規表現)に一致するレスポンスが必要です。

※全メソッドはこちらをチェック!
https://developers.google.com/apps-script/reference/forms/text-validation-builder?hl=ja

段落

段落
const form = FormApp.getActiveForm();
let paragraphtextValidation_length = FormApp.createParagraphTextValidation()
                                            .requireTextLengthGreaterThanOrEqualTo(100)
                                            .setHelpText('少なくとも100文字以上入力してください。')
                                            .build();

form.addParagraphTextItem().setTitle('段落の質問項目')
                           .setHelpText('段落の質問項目に対する説明文')
                           .setValidation(paragraphtextValidation_length)
                           .setRequired(true);

段落の場合には、記載した内容に対する検証を行うことができます。上記の場合はrequireTextLengthGreaterThanOrEqualToを用いたため最小入力文字数を制限しました。その他には以下のようなものがあります。

メソッド名 説明
requireTextContainsPattern(pattern) パターンを含むレスポンスが必要です。
requireTextDoesNotContainPattern(pattern) パターンが含まれていないレスポンスが必要です。
requireTextDoesNotMatchPattern(pattern) パターンに一致しないレスポンスが必要です。
requireTextLengthGreaterThanOrEqualTo(number) レスポンスの長さはこの値以上である必要があります。
requireTextLengthLessThanOrEqualTo(number) レスポンスの長さは値より短くする必要があります。
requireTextMatchesPattern(pattern) パターンに一致するレスポンスが必要です。

ラジオボタン

ラジオボタン
const form = FormApp.getActiveForm();
form.addMultipleChoiceItem().setTitle('ラジオボタンの質問項目')
                            .setHelpText('ラジオボタンの質問項目に対する説明文')
                            .setChoiceValues(['選択肢1', '選択肢2', '選択肢3'])
                            .showOtherOption(true)
                            .setRequired(true);

ラジオボタンの場合には、showOtherOptionを用いることで 「その他」の選択肢を追加することができます。
また、String配列による選択肢追加のsetChoiceValues とは別にChoice(単一の選択肢をサポート)配列によるsetChoices もあります。これの場合、選択した場合に次セクションを分岐させることも設定次第で実現できるため非常に便利ですが、GASでの組み込みの場合少々複雑になりますので、また別の機会に。

チェックボックス

チェックボックス
const form = FormApp.getActiveForm();
let checkboxValidation_exactly = FormApp.createCheckboxValidation()
                                        .requireSelectExactly(2)
                                        .setHelpText('2つ選択してください。')
                                        .build();

form.addCheckboxItem().setTitle('チェックボックスの質問項目')
                      .setHelpText('チェックボックスの質問項目に対する説明文')
                      .setChoiceValues(['選択肢1', '選択肢2', '選択肢3'])
                      .showOtherOption(true)
                      .setValidation(checkboxValidation_exactly)
                      .setRequired(true);

チェックボックスの場合には、選択した内容に対する検証を行うことができます。上記の場合はrequireSelectExactlyを用いたため選択することのできる個数を制限しました。その他には以下のようなものがあります。

メソッド名 説明
requireSelectAtLeast(number) この数以上の選択肢を選択する必要があります。
requireSelectAtMost(number) 選択する最大数の選択肢が必要です。
requireSelectExactly(number) この数の選択肢を厳密に選択する必要があります。

プルダウン

プルダウン
const form = FormApp.getActiveForm();
form.addListItem().setTitle('プルダウンの質問項目')
                  .setHelpText('プルダウンの質問項目に対する説明文')
                  .setChoiceValues(['選択肢1', '選択肢2', '選択肢3'])
                  .setRequired(true);

プルダウンの場合には、ラジオボタンと同様にChoice(単一の選択肢をサポート)配列によるsetChoices を用いることで選択した場合に次セクションを分岐させることも設定次第で実現できます。

均等目盛

均等目盛
const form = FormApp.getActiveForm();
form.addScaleItem().setTitle('均等目盛の質問項目')
                   .setHelpText('均等目盛の質問項目に対する説明文')
                   .setBounds(0, 10)
                   .setLabels('最悪', '最高')
                   .setRequired(true);

選択式(グリッド)

選択式(グリッド)
const form = FormApp.getActiveForm();
let gridValidation = FormApp.createGridValidation()
                            .requireLimitOneResponsePerColumn()
                            .build();

form.addGridItem().setTitle('選択式(グリッド)の質問項目')
                  .setHelpText('選択式(グリッド)の質問項目に対する説明文')
                  .setRows(['1行目', '2行目', '3行目'])
                  .setColumns(['1列目', '2列目', '3列目'])
                  .setValidation(gridValidation)
                  .setRequired(true);

選択式(グリッド)の場合には、選択内容の制限を行うことができます。なお、

  • 1つの回答を必須にする:setRequired
  • 1につき1つの回答に制限:setValidationrequireLimitOneResponsePerColumn

となりますのでご注意ください。

チェックボックス(グリッド)

チェックボックス(グリッド)
const form = FormApp.getActiveForm();
let checkboxGridValidation = FormApp.createCheckboxGridValidation()
                                    .requireLimitOneResponsePerColumn()
                                    .build();

form.addCheckboxGridItem().setTitle('チェックボックス(グリッド)の質問項目')
                          .setHelpText('チェックボックス(グリッド)の質問項目に対する説明文')
                          .setRows(['1行目', '2行目', '3行目'])
                          .setColumns(['1列目', '2列目', '3列目'])
                          .setValidation(checkboxGridValidation)
                          .setRequired(true);

チェックボックス(グリッド)の場合も選択式(グリッド)と同様の注意が必要です。

日付

日付は若干の癖があります。というか、まずはDateItemDateTimeItemがありますが、これはDateTimeItemを使いましょう。これでないと、時刻を含めた日付項目を実現できません。
また、GoogleのAPI仕様に明確に誤りがありますのでご留意ください。

API仕様においては当該クラスに設定できるメソッドにsetIncludesYearがあります。API仕様には

日付項目に年の設定を含めるかどうかを設定します。新しい日付アイテムのデフォルトは true です。

と記載がありますが、これは明確に誤りです。その誤りを以下で確認しましょう。

年も時刻も含める
日付1
const form = FormApp.getActiveForm();
form.addDateTimeItem().setTitle('日付の質問項目')
                      .setHelpText('日付の質問項目に対する説明文')
                      .setRequired(true);
年のみを含める
日付2
const form = FormApp.getActiveForm();
form.addDateTimeItem().setTitle('日付の質問項目')
                      .setHelpText('日付の質問項目に対する説明文')
                      .setIncludesYear(true)
                      .setRequired(true);
年も時刻も含めない
日付3
const form = FormApp.getActiveForm();
form.addDateTimeItem().setTitle('日付の質問項目')
                      .setHelpText('日付の質問項目に対する説明文')
                      .setIncludesYear(false)
                      .setRequired(true);

このようにsetIncludesYear呼び出すかどうかで項目の状態が変化しますので、デフォルトがtrueというわけではなく、

  • 年も時刻も含める:setIncludesYear呼び出さない
  • 年のみを含める:setIncludesYear(true)で呼び出す
  • 年も時刻も含めない:setIncludesYear(false)で呼び出す

正しい利用方法となります。ご留意ください。

時刻

時刻も日付と同様に若干の癖があります。ですが、こちらは追加したい項目に応じて、クラスを分けるだけです。

時刻に対する質問項目
時刻1
const form = FormApp.getActiveForm();
form.addTimeItem().setTitle('時刻の質問項目_時刻')
                  .setHelpText('時刻の質問項目に対する説明文')
                  .setRequired(true);
経過時間に対する質問項目
時刻2
const form = FormApp.getActiveForm();
form.addDurationItem().setTitle('時刻の質問項目_経過時間')
                      .setHelpText('期間の質問項目に対する説明文')
                      .setRequired(true);

レイアウト要素

タイトルと説明
タイトルと説明
const form = FormApp.getActiveForm();
form.addSectionHeaderItem().setTitle('タイトルと説明を追加')
                           .setHelpText('これは単なるレイアウト要素');
セクション
セクション
const form = FormApp.getActiveForm();
form.addPageBreakItem().setTitle('2ページ目')
                       .setHelpText('レイアウト要素ですが、分岐とかも設定が可能')

「タイトルと説明」に非常によく似ていますが、次にどのセクションへ行くか、ラジオボタンやプルダウン項目と併せてどのセクションから来るかなどを設定することができます。

画像
画像
const form = FormApp.getActiveForm();
form.addImageItem().setTitle('画像の表示項目')
                   .setHelpText('画像の表示項目に対する説明文')
                   .setImage(DriveApp.getFileById('XXXXXXXXXXXXXXXXXX').getBlob())
                   .setAlignment(FormApp.Alignment.CENTER)
                   .setWidth(300);

setImageにはBlob形式で設定する必要がありますので、例えばGoogleドライブ上の画像であれば、getFileByIdで取得したオブジェクトに対してgetBlobを用いて設定しましょう。

動画
動画
const form = FormApp.getActiveForm();
form.addVideoItem().setTitle('動画の表示項目')
                   .setHelpText('動画の表示項目に対する説明文')
                   .setVideoUrl('VyzqHFdzBKg')
                   .setAlignment(FormApp.Alignment.LEFT)
                   .setWidth(300);

setVideoUrlにはYouTube上の動画のみ許容されています。
この時、YouTube上の動画IDURLショートURLどれでも構いません。

例えば
.setVideoUrl('https://www.youtube.com/watch?v=VyzqHFdzBKg')
.setVideoUrl('https://youtu.be/VyzqHFdzBKg')

できないこと

基本的にはGUIでできることはGASから行うことができます。しかしながら、一部は実現不可な箇所がありますので、それを認識しましょう。

各項目の装飾要素をいじる

Googleフォームでは例えば、質問項目タイトルを太字にしたり、説明文の大事な箇所に下線引いたりと、装飾要素も細かに設定ができますが、これをGAS側で行うことはできません。

ファイルのアップロード

Googleフォームでは「ファイルのアップロード」を質問項目として定義し、例えば申し込みに必要な添付書類を受け付けることが可能です。しかしながら、これをGAS側から追加することはできません。

しかしながら

いずれGASがパワーアップし、これらさえできるようになる日が来ると私は信じています。むしろ確信しています。というのも、ファイルのアップロードに関しては、全くできないわけではありません。

ファイルのアップロードを複製
form.getItems().forEach(function(item){
  if (item.getTitle()=='ファイルのアップロード') {
    let uploadItem = item.duplicate();
    uploadItem.setTitle('ファイルのアップロード複製');
  }
});

とすると、item.duplicate()でエラーとなりますが、フォーム内のファイルのアップロード項目の複製されています。例えば、これが

アップロード
item.asFileUploadItem().duplicate();

とかのメソッドがGASに拡充されれば、きっと実現できるはずです!

おわりに

お疲れ様でした。
第19回は「GASを用いたGoogleフォーム内の項目設定チートシート」ということで、Googleフォーム内の項目をGASからいじるための呼び出し方やテクニックを一括でお伝えしました。あとは、これをどう組み合わせるかです。第18回に行ったように回答を受け付けるのに併せてプルダウン内の項目を更新するのもいいでしょうし、各業務の実態ややりたいことに併せて取捨選択していきましょう。皆さんの業務改善に少しでも役に立てることを願っています!引き続き、GASを楽しんでいきましょう!!
記事を読んで、「良いな」や「今後に期待できる!」と感じて頂けたらいいねフォローコメントいただけると幸いです。それではまた次回をお楽しみに!

ブログではより細かく紹介していますので、ぜひこちらもアクセス!!

2
3
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
2
3