はじめに
本シリーズでは、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つの回答に制限:
setValidation
(requireLimitOneResponsePerColumn
)
となりますのでご注意ください。
チェックボックス(グリッド)
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);
チェックボックス(グリッド)の場合も選択式(グリッド)と同様の注意が必要です。
日付
日付は若干の癖があります。というか、まずはDateItem
とDateTimeItem
がありますが、これはDateTimeItem
を使いましょう。これでないと、時刻を含めた日付項目を実現できません。
また、GoogleのAPI仕様に明確に誤りがありますのでご留意ください。
API仕様においては当該クラスに設定できるメソッドにsetIncludesYear
があります。API仕様には
日付項目に年の設定を含めるかどうかを設定します。新しい日付アイテムのデフォルトは true です。
と記載がありますが、これは明確に誤りです。その誤りを以下で確認しましょう。
年も時刻も含める
const form = FormApp.getActiveForm();
form.addDateTimeItem().setTitle('日付の質問項目')
.setHelpText('日付の質問項目に対する説明文')
.setRequired(true);
年のみを含める
const form = FormApp.getActiveForm();
form.addDateTimeItem().setTitle('日付の質問項目')
.setHelpText('日付の質問項目に対する説明文')
.setIncludesYear(true)
.setRequired(true);
年も時刻も含めない
const form = FormApp.getActiveForm();
form.addDateTimeItem().setTitle('日付の質問項目')
.setHelpText('日付の質問項目に対する説明文')
.setIncludesYear(false)
.setRequired(true);
このようにsetIncludesYear
を呼び出すかどうかで項目の状態が変化しますので、デフォルトがtrue
というわけではなく、
- 年も時刻も含める:
setIncludesYear
を呼び出さない - 年のみを含める:
setIncludesYear(true)
で呼び出す - 年も時刻も含めない:
setIncludesYear(false)
で呼び出す
が正しい利用方法となります。ご留意ください。
時刻
時刻も日付と同様に若干の癖があります。ですが、こちらは追加したい項目に応じて、クラスを分けるだけです。
時刻に対する質問項目
const form = FormApp.getActiveForm();
form.addTimeItem().setTitle('時刻の質問項目_時刻')
.setHelpText('時刻の質問項目に対する説明文')
.setRequired(true);
経過時間に対する質問項目
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上の動画ID、URL、ショート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を楽しんでいきましょう!!
記事を読んで、「良いな」や「今後に期待できる!」と感じて頂けたらいいねやフォロー、コメントいただけると幸いです。それではまた次回をお楽しみに!
ブログではより細かく紹介していますので、ぜひこちらもアクセス!!