メニューを閉じる

テクノデジタルグループ

メニューを開く

2023.02.28

開発環境・ツール

【GAS】GASを触ってみる!〜Forms編〜

目次

  • はじめに
  • 概要
  • 本題
  • 終わりに

はじめに

本ブログをお読みになってくださっている皆様、こんにちは。お久しぶりです。MTです。

皆様はいかがお過ごしでしょうか。私は恵方巻き買おうとしたらなくて長い細巻きを齧ったり、チョコ菓子を自分で作って食べるなどして時節の行事をエンジョイしていました、、、、、

 

気を取り直して、、本題に入りましょう。

今回も前回と同じくGASやってみました記事です!あまり複雑な事はしていないので、ちょっとプログラム触ってみたいなというコーディングの入り口や、少しでもGAS使って楽できないかなという方の助けになれば良いなと思います!

前回記事はこちらです。

概要

 今回触ってみたのは、Google Formsです!
 Formsは簡単にアンケートが作れて、集計や採点までしてくれる便利なツールですよね。
 社内改善に焦点を当てると社内アンケートや、研修後の簡単なテスト作成などで使うことはあるのではないでしょうか。
 そんなFormsをもっと楽に使えないかと思い、焦点を当てたのは、Formの作成に関してです。
全く同じフォーマットで良いのであれば、既存のコピーでなんとかなりますが、ちょっとした変更点がいっぱいあるときなどに、少しでも楽ができたり、わかりやすかったりする方が嬉しいなー、と思いませんか?
また、例えば入力で得た値を規定のフォーマットに従ってスプレッドシートに書き出す。ということもあるかもしれません。
そんな要望をGASで解決しよう!が今回の主題です。
 ただすみません、はじめにお断りさせていただきたいのですが、Formsと言っておきながら結構SpreadSheet多めです、、、

本題

 概要を見て、第一回概要にあった大目標どこに行った?と疑問に思われた方もいらっしゃるかもしれません。
実は、今回のFormsは、「日報データの送信手段」として使えないか、という調査をかねてのお試し記事となっています!
 日報記載の度に、スプレッドシートを開いて、該当のセルを選んで、内容を書いて、、とするのであれば、正直フォーマットを整えたものに記載するのと変わらないですよね。
なので入力を楽にすることができないか、と考えた時、最も単純な方法がGoogle Formsを利用する方法だと考えました。
 Formsであれば、
 「データ登録:ある特定のURLにアクセスして回答をする」
 「データ管理:スプレッドシートに特定のルールで列挙」
とすることができ、もとよりGoogle Workspaceで用意されているものなので、情報が集めやすい。
以上のことから、Formsを使ってみよう!と思い至りました。
 例によって初めからゴールに向かっていくのは難しいのでその前段階として、
「スプレッドシートで管理する情報から、フォームを作成して、そのフォームの回答を集める。」
ものを作成したいと思います。

今回の目標

今回の目標は、「スプレッドシートで管理する情報から、フォームを作成して、そのフォームの回答を集める。」

ということで、以下のような方針で進めたいと思います。

  1. スプレッドシートに、「タイトル、種別、設定値、必須かどうか」を記載
  2. GASでその情報を読み取る
  3. 読み取った情報からフォームを作成する
  4. フォームの回答が、1を記載したスプレッドシートに表示されるよう設定する

それでは始めていきましょう!

1. スプレッドシートの用意

まずはスプレッドシートの用意からです。

用意するべきものは至ってシンプルで、以下の内容のシートを用意すれば問題ありません。

  • 質問のタイトル
  • 回答の種別
  • 設定
  • 必須かどうか(T/F)

本当は、もっと詳細な設定などもあるのですが、ひとまずこれだけで作成していきたいと思います。

 

では、スプレッドシートを開きましょう。

開いた最初のシートの名前を分かりやすい名前に設定します。(ここではQuestionnaireとします。)

このQuestionnaireシートに以下の内容を記載してください。説明に関しては後ほど行います。

Title Category Setting_Sheet Require
チェックボックスグリッド Chbox_G Setting_ChBG TRUE
チェックボックス Chbox Setting_ChB TRUE
時間 Duration TRUE
日付 Date
日付+時刻 DateTime
時刻 Time
ラジオグリッド Radio_G Setting_RG
ラジオ Radio Setting_R
プルダウン List Setting_L
テキストブロック Paragraph
一行テキスト Text TRUE
スケール Scale Setting_S TRUE

今回作成するフォームは、お試しということでほぼ全ての質問形式を網羅してみたいと思い、各質問形式に対応する質問を作成していこうと思います。そのための、設定値群が上表です。これら4項目は以下のような役割を持ちます

  • Title : 質問のタイトル(今回はわかりやすさのため質問形式名をつけています)
  • Category : 質問形式のカテゴリー(GASの分岐処理に使います)
  • Setting_Sheet : 質問内容などの設定について記載しているシート名
  • Require : TRUEまたはFALSEのみ、回答必須にするかを指定

まず、このフォームの質問形式についてざっくりご紹介させていただきます。同時に今回の設定シートに記載している内容についても概説いたします。

  • CheckboxGrid Item
    • チェックボックスの行と列で構成されている質問項目
    • 列 = 小質問項目 行 = 共通の回答(収集対象)
    • 一連のチェックボックスに対し、各行ごとに複数の選択肢を選択できる
    • 設定:列の値、行の値
  • Checkbox Item
    • 複数選択可能なチェックボックスで構成されている質問項目
    • 設定:選択項目の値、その他を選択肢に含むか
  • Duration Item
    • 時間の長さを入力できる質問項目
    • 設定 : なし
  • Date Item
    • 日付を入力できる質問項目
    • 設定 : なし
  • DateTime Item
    • 日付と時刻を入力できる質問項目
    • 設定 : なし
  • Time Item
    • 時刻を入力できる質問項目
    • 設定 : なし
  • Grid Item
    • 行と列で構成されている質問項目
    • 列 = 小質問項目 行 = 共通の回答(収集対象)
    • 一連のラジオボタンに対し、各行につき1つの選択肢を選択できる
    • 設定 : 列の値、行の値
  • MultipleChoice Item
    • ラジオボタンで構成された質問項目
    • 設定:選択項目の値、その他を選択肢に含むか
  • List Item
    • プルダウンリストで構成された質問項目
    • 設定 : 選択項目の値
  • ParagraphText Item
    • 文章入力欄(改行可)で構成された質問項目
    • 設定:なし
  • Text Item
    • 一行テキストで構成された質問項目
    • 設定 : なし
  • Scale Item
    • 番号つきラジオボタンから一つ選択できるように構成された質問項目
    • 設定:数値の最小値(0, 1)、最大値(3〜10)

設定なしの項目の中にも、細かい設定ができるものはありますが、今回は必要最低限に近いものにしています。

今回の各設定シートの構成は、句点区切りで一列に列挙とします。参考にチェックボックスグリッドの設定は以下のような構成になっています。

勿論、シートやタイトルなどの名前に関しては自由なものをつけていただいて大丈夫です。特に日本語であってもGASスクリプト内で扱えるので日本語でも問題ありません。個人的な好みというかおすすめを言うのであれば、セオリー通り適当なアルファベットで扱う癖があった方が不要なトラブルを起こしにくいかな、とは思います。

2. GASでその情報を読み取る

長らくお待たせいたしました!ここからはGASを使っていきましょう。

GASの準備は前回もご紹介いたしましたが、簡単に言うと「ヘッダバー」→「拡張機能」→「Google App Script」で開くことができます。

では、スプレッドシートの情報を読み取る設定をしていきます。この辺りは前回とあまり変わりないので、サクッと解説しますが、ソースコードの添付で、流していきます。なお、デフォルトで最初から記載されている関数を上書きしています。

function createQuestionnaire() {

  // テーブルヘッダは読む必要がないので読み飛ばす
  const START_SETTING_ROW = 2;
  const DIFF_FROM_TOP = START_SETTING_ROW - 1;
  
  // spreadSheetの定義
  const spreadSheet = SpreadsheetApp.getActiveSpreadsheet();
  const queSetting = spreadSheet.getSheetByName('Questionnaire');

  // 設定を読み込む
  const settings = queSetting.getRange(
    START_SETTING_ROW, 1, 
    queSetting.getLastRow()-DIFF_FROM_TOP, 4)
  .getValues();

  // 読み込んだ設定をコンソールに表示する
  settings.forEach((arr, index) => {
    console.log(index, arr)
  });

上記のコードでは、スプレッドシートから、先ほど記載した設定ファイルを読み込んで、一行ずつ表示する。といったことを行っています。ポイントとしては、テーブルのヘッダは、人が読んで分かりやすいように置いているだけなので、読む必要がないため、あらかじめ読み取りから外してしまっていることですね。

読み取りに関してはひとまずこれだけです。設定シートの読み取りがなくて不思議かもしれませんが、フォームの作成に強く関わってくるかなと思いますので、次項で説明したいと思います。

3. 読み取った情報からフォームを作成する。

ここからは、今回の本題、フォームの作成に入りたいと思います。

その前に、一旦状況を整理しましょう。2のコードで取得した情報(変数: settings)についてです。

settingsは、二次元の配列で、それぞれのインデックスが示す内容(配列)は[タイトル, カテゴリー名, 設定ファイル名, TRUEまたはFALSE]ですね。このデータを利用して、フォームのアイテム(質問)を設定していきます。今回は扱うシートが複数になって多少こんがらがってしまうかも知れません、、ですので、変数の持っている値に関してなどはこのようにきちんと確認して進めましょう。

3-1. フォームファイル作成

それでは、まずフォームファイル自体の作成をしていきます。

フォームファイルの作成に関しては以下のメソッドを利用します。

const form = FormApp.create('フォーム名')

左辺のformはこの後、この作成したFormを操作するために指定しておくための変数だと思っていただいて問題ないので、基本的にこのような形で定義することが多いと思います。

このコードが実行されたタイミングで、すぐに指定した名前で空っぽのフォームが作成されていると思います。もし余裕があれば、これだけ記載して確認してみてください。

上記コードにおいて、挿入箇所は大体下コードのように挿入してください。

  // spreadSheetの定義
  const spreadSheet = SpreadsheetApp.getActiveSpreadsheet();
  const queSetting = spreadSheet.getSheetByName('Questionnaire');

  // formの作成
  const form = FormApp.create('テストフォーム')

  // 設定を読み込む

上記のように、すぐ使うわけでもないのに、設定を読み込む前のタイミングで作成している理由としては読みやすさのために、何かを定義するもの、はなるべくまとめておきたいという思いからです。別に使う前に定義さえすれば動きます。

3-2. フォームアイテム(質問)のセット

ここからが今回の内容で、最も重要かつ複雑な箇所になるかと思います。

といってもそんな特殊なことをしているわけではないので、しっかり確認しながら進めていきましょう!

フォームに質問を追加するメソッドは、質問形式ごとに違います。さらに、このメソッドが追加するのは質問形式の箱だけです。つまり、さらにその箱の持つメソッドで選択肢などを追加する必要があります。

その対応を以下にまとめます。今回利用しているものだけに絞っていますので、もっと詳しい説明を見たい方は、公式のドキュメントを確認することをお勧めいたします。

○ CheckboxGrid Item

// フォームに質問を追加
  item = form.addCheckboxGridItem();
// 質問に要素を追加: タイトル、列(小質問)、行(選択肢)、必須かどうか
  item.setTitle('タイトル名')
    .setRows('[列要素]')
    .setColumns('[行要素]')
    .setRequired('T/F');

○ Checkbox Item

// フォームに質問を追加
  item = form.addCheckboxItem();
// 質問に要素を追加: タイトル、選択肢、その他を表示するか、必須かどうか
  item.setTitle('タイトル名')
    .setChoiceValues('[選択肢]')
    .showOtherOption('T/F')
    .setRequired('T/F');

○ Duration Item

// フォームに質問を追加
  item = form.addDurationItem();
// 質問に要素を追加: タイトル、必須かどうか
  item.setTitle('タイトル名')
    .setRequired('T/F');

○ Date Item

// フォームに質問を追加
  item = form.addDateItem();
// 質問に要素を追加: タイトル、必須かどうか
  item.setTitle('タイトル名')
    .setRequired('T/F');

○ DateTime Item

// フォームに質問を追加
  item = form.addDateTimeItem();
// 質問に要素を追加: タイトル、必須かどうか
  item.setTitle('タイトル名')
    .setRequired('T/F');

○ Time Item

// フォームに質問を追加
  item = form.addTimeItem();
// 質問に要素を追加: タイトル、必須かどうか
  item.setTitle('タイトル名')
    .setRequired('T/F');

○ Grid Item

// フォームに質問を追加
  item = form.addGridItem();
// 質問に要素を追加: タイトル、列(小質問)、行(選択肢)、必須かどうか
  item.setTitle('タイトル名')
    .setRows('[列要素]')
    .setColumns('[行要素]')
    .setRequired('T/F');

○ MultipleChoice Item

// フォームに質問を追加
  item = form.addMultipleChoiceItem();
// 質問に要素を追加: タイトル、選択肢、その他を表示するか、必須かどうか
  item.setTitle('タイトル名')
    .setChoiceValues('[選択肢]')
    .showOtherOption('T/F')
    .setRequired('T/F');

○ List Item

// フォームに質問を追加
  item = form.addListItem();
// 質問に要素を追加: タイトル、選択肢、必須かどうか
  item.setTitle('タイトル名')
    .setChoiceValues('[選択肢]')
    .setRequired('T/F');

○ ParagraphText Item

// フォームに質問を追加
  item = form.addParagraphTextItem();
// 質問に要素を追加: タイトル、必須かどうか
  item.setTitle('タイトル名')
    .setRequired('T/F');

○ Text Item

// フォームに質問を追加
  item = form.addTextItem();
// 質問に要素を追加: タイトル、必須かどうか
  item.setTitle('タイトル名')
    .setRequired('T/F');

○ Scale Item

// フォームに質問を追加
  item = form.addScaleItem();
// 質問に要素を追加: タイトル、範囲、必須かどうか
  item.setTitle('タイトル名')
    .setBounds(最小, 最大)
    .setRequired('T/F');

では、これらのメソッドを使って、フォームを設定していきましょう。

セクション2の最後、本セクションの初めの振り返りで確認した、設定シートのデータを使います。

セクション2最後のconsole.logの箇所から、以下のコードに編集します。

  // 読み込んだ設定をコンソールに表示する。=>読み込んだ設定で、シートを更新する
  settings.forEach((arr, index) => {
    console.log(index);
    constructFormItem(spreadSheet, form, arr);
  });

何かよくわからない関数がいますね、、はい、自作関数です。

この処理はちょっと複雑になるので、関数に分けてしまおうと思います。詳しい処理は次に説明しますので、今は引数にスプレッドシート、フォーム、設定値の配列(本セクションはじめに提示したデータ列)を持つことだけわかっていただければと思います。

なお、console.log(index)を残しているのは、処理の進行を可視化するためです。

独自関数constructFormItem(spreadSheet, form, arr)の実装に進みます。

はじめにコードを紹介します。全文書くと長くなるため、ひとまず参考にCheckboxGrid Itemの設定を示します。

function constructFormItem(spreadSheet, form, setting_arr) {
  // 設定シートを取得
  const sheet = spreadSheet.getSheetByName(setting_arr[2]);
  // 質問の種別で分岐
  switch (setting_arr[1]) {
    case 'Chbox_G': 
      if (!sheet) {
        // 設定が必要な場合、設定値が空ならエラーとして処理
        throw new Error('CheckboxGridItem:設定用シートがありませんでした。')
      }
   // itemを作成する
      const item = form.addCheckboxGridItem();
      // 設定の読み込み
      const setting = sheet.getRange(1, 1, sheet.getLastRow(), sheet.getLastColumn()).getValues();
      // 空文字の除去(行列長の差による空文字)
      const rows = setting[0].filter(v => v);
      const cols = setting[1].filter(v => v);
      // 値のセット
      item.setTitle(setting_arr[0])
        .setRows(rows)
        .setColumns(cols)
        .setRequired(Boolean(setting_arr[3]));
      break;
    ・・・
    default: break; 
  }
}

端折りましたが結構長いですね、、それにセットしている配列に関して、setting_arr[0]はタイトル、setting_arr[3]はTRUEまたはFALSEである、ということがパッと見ただけでは分かりづらいです。コメントをつけるにしてもごちゃごちゃしますね。

ここでこの処理の流れを確認してみましょう。

  1. 設定シートを名前(setting_arr[2])から取得
  2. 質問の種類(setting_arr[1])で分岐
  3. 【設定が必要な質問の場合】設定シートが取得できてない(空値)ならエラーとして処理
  4. 質問の種類に対応する質問(item)を作成
  5. 設定シートから設定を読み取る
  6. 読み取ったデータから、空文字を除去する
  7. itemに値のセットを行う

ざっと処理の流れを見ていると、4の処理のあたりからはフォームのitemに関する、また別の処理のように見えませんか?

今まとまっている処理に対し、別の処理の塊として見ることができる部分がある、ではそれを切り出して関数にしてみましょう。

すぐ上のコードの一部を関数呼び出しに書き換えます。では、引数に何を渡すべきでしょうか。

4以降の処理で扱っているのは、以下の要素ですね。

  • formのitem(作成)
  • 設定シート
  • setting_arr

このうち、setting_arrに関しては、必要なデータはタイトルと、必須かどうかのT/Fでしたね。

では、それだけを抜き取って渡せば分かりやすくなるのではないでしょうか。

従って、以下のように分岐内容を編集したいと思います。

// 質問の種別で分岐
  switch (setting_arr[1]) {
    case 'Chbox_G': 
      if (!sheet) {
        // 設定が必要な場合、設定値が空ならエラーとして処理
        throw new Error('CheckboxGridItem:設定用シートがありませんでした。')
      }
      // 設定用の関数を呼び出す
      setCheckboxGridItem(form.addCheckboxGridItem(), sheet, setting_arr[0], Boolean(setting_arr[3]))
      break;

ちょっとこの時点では分かりにくいかも知れませんが、関数定義を確認したときにわかりやすくなり、可読性が増すのではないかなと考えます。正直個人で書く分には好みですし、チームの場合はチームの規約に従うと思うので、難しいですね。

閑話休題。

では関数の定義について紹介します。例によって先にコードを紹介したいと思います。

// CheckboxGridItem: 設定シートは2行で構成、1行目はRowsに相当、2行目はColumnsに相当
function setCheckboxGridItem (item, sheet, title, require) {
  // 設定の読み込み
  const setting = sheet.getRange(1, 1, sheet.getLastRow(), sheet.getLastColumn()).getValues();
  // 空文字の除去(行列長の差による空文字)
  const rows = setting[0].filter(v => v);
  const cols = setting[1].filter(v => v);
  // 値のセット
  item.setTitle(title)
    .setRows(rows)
    .setColumns(cols)
    .setRequired(require);
}

引数はフォームのitem, 設定シート自体を受け取るsheet, setting_arrを受け取るtitle, require をセットします。その変数の用途がはっきりして、先ほどまでの状態よりは読みやすいかなと思います。

処理自体に関しては、流れで説明した通りのことを行っているのですが、一点読み込みに関して補足します。

コメントに記載していますが、必要な設定シートは簡単にするため、各行に1設定値グループの値を列挙している前提で記載しています。この入力もわかりやすくしたいのであれば、入力シートや読み出しにも工夫が必要になるかと思いますので、色々とお試しください。

それでは、サンプルであげたものを含めた2つの関数全体に関して、紹介させていただきます。

もちろん設定の取り出し方、判定などに関して全て共通しているわけではありませんので、注意深く確認していただけたらと思います。なお、備考やコメントで補足説明を加えています。

・constructFormItem
/**
 * 現在の構成
 * spreadSheet 設定シートのあるスプレッドシート
 * form 作成するフォーム
 * setting_arr 設定オブジェクト配列
 *   [0]: タイトル
 *   [1]: アイテムの種別
 *   [2]: 設定用シート(なしの場合空文字)
 *   [3]: 必須項目かどうか(空文字であれば必須でない) 
 */
function constructFormItem(spreadSheet, form, setting_arr) {
  const sheet = spreadSheet.getSheetByName(setting_arr[2]);
  switch (setting_arr[1]) {
    case 'Chbox_G': 
      if (!sheet) {
        throw new Error('CheckboxGridItem:設定用シートがありませんでした。')
      }
      setCheckboxGridItem(form.addCheckboxGridItem(), sheet, setting_arr[0], Boolean(setting_arr[3]))
      break;
    case 'Chbox': 
      if (!sheet) {
        throw new Error('CheckboxItem:設定用シートがありませんでした。')
      }
      setCheckboxItem(form.addCheckboxItem(), sheet, setting_arr[0], Boolean(setting_arr[3]))
      break;
    case 'Duration': 
      form.addDurationItem()
        .setTitle(setting_arr[0])
        .setRequired(Boolean(setting_arr[3]));
      break;
    case 'Date': 
      form.addDateItem()
        .setTitle(setting_arr[0])
        .setRequired(Boolean(setting_arr[3]));
      break;
    case 'DateTime': 
      form.addDateTimeItem()
        .setTitle(setting_arr[0])
        .setRequired(Boolean(setting_arr[3]));
      break;
    case 'Time': 
      form.addTimeItem()
        .setTitle(setting_arr[0])
        .setRequired(Boolean(setting_arr[3]));
      break;
    case 'Radio_G': 
      if (!sheet) {
        throw new Error('GridItem:設定用シートがありませんでした。')
      }
      setGridItem(form.addGridItem(), sheet, setting_arr[0], Boolean(setting_arr[3]))
      break;
    case 'Radio': 
      if (!sheet) {
        throw new Error('MultipleChoiceItem:設定用シートがありませんでした。')
      }
      setMultipleChoiceItem(form.addMultipleChoiceItem(), sheet, setting_arr[0], Boolean(setting_arr[3]))
      break;
    case 'List': 
      if (!sheet) {
        throw new Error('MultipleChiceItem:設定用シートがありませんでした。')
      }
      setListItem(form.addListItem(), sheet, setting_arr[0], Boolean(setting_arr[3]))
      break;
    case 'Paragraph': 
      form.addParagraphTextItem()
        .setTitle(setting_arr[0])
        .setRequired(Boolean(setting_arr[3]));
      break;
    case 'Text': 
      form.addTextItem()
        .setTitle(setting_arr[0])
        .setRequired(Boolean(setting_arr[3]));
      break;
    case 'Scale': 
      if (!sheet) {
        throw new Error('ScaleItem:設定用シートがありませんでした。')
      }
      setScaleItem(form.addScaleItem(), sheet, setting_arr[0], Boolean(setting_arr[3]))
      break;
    default: break; 
  }
}
・set{Category}Item 関数群
// CheckboxGridItem: 設定シートは2行で構成、1行目はRowsに相当、2行目はColumnsに相当
function setCheckboxGridItem (item, sheet, title, require) {
  // 設定の読み込み
  const setting = sheet.getRange(1, 1, sheet.getLastRow(), sheet.getLastColumn()).getValues();
  // 空文字の除去(行列長の差による空文字)
  const rows = setting[0].filter(v => v);
  const cols = setting[1].filter(v => v);
  // 値のセット
  item.setTitle(title)
    .setRows(rows)
    .setColumns(cols)
    .setRequired(require);
}

// CheckboxItem: 設定シートは1,または2行で構成、1行目に設定値、2行目に値があれば「その他」フラグがたつ
function setCheckboxItem (item, sheet, title, require) {
  // 設定の読み込み
  const setting = sheet.getRange(1, 1, sheet.getLastRow(), sheet.getLastColumn()).getValues();
  // 配列の空文字除去(想定外エラー回避)
  const rows = setting[0].filter(v => v);

  // 値のセット
  item.setTitle(title)
    .setChoiceValues(rows)
    .showOtherOption(sheet.getLastRow() != 1)
    .setRequired(require);
}

// GridItem: 設定シートは2行で構成、1行目はRowsに相当、2行目はColumnsに相当
function setGridItem (item, sheet, title, require) {
  // 設定の読み込み
  const setting = sheet.getRange(1, 1, sheet.getLastRow(), sheet.getLastColumn()).getValues();
  // 空文字の除去(行列長の差による空文字)
  const rows = setting[0].filter(v => v);
  const cols = setting[1].filter(v => v);
  // 値のセット
  item.setTitle(title)
    .setRows(rows)
    .setColumns(cols)
    .setRequired(require);
}

// MultipleChoiceItem: 設定シートは1,または2行で構成、1行目に設定値、2行目に値があれば「その他」フラグがたつ
function setMultipleChoiceItem (item, sheet, title, require) {
  // 設定の読み込み
  const setting = sheet.getRange(1, 1, sheet.getLastRow(), sheet.getLastColumn()).getValues();
  // 配列の空文字除去(想定外エラー回避)
  const rows = setting[0].filter(v => v);

  // 値のセット
  item.setTitle(title)
    .setChoiceValues(rows)
    .showOtherOption(sheet.getLastRow() != 1)
    .setRequired(require);
}

// ListItem: 設定シートは1行で構成、1行目に設定値
function setListItem (item, sheet, title, require) {
  // 設定の読み込み
  const setting = sheet.getRange(1, 1, sheet.getLastRow(), sheet.getLastColumn()).getValues();

  // 値のセット
  item.setTitle(title)
    .setChoiceValues(setting[0])
    .setRequired(require);
}

// ScaleItem: 設定シートは1行で構成、A1に下限値、B1に上限値(3~10まで)
function setScaleItem (item, sheet, title, require) {
  // 設定の読み込み
  const min = sheet.getRange('A1').getValue();
  const max = sheet.getRange('B1').getValue();

  // 値のセット
  item.setTitle(title)
    .setBounds(min, max)
    .setRequired(require);
}

駆け足な説明で基本コードの紹介になってしまって、申し訳ございません。しかし、全部解説するとくどくなりすぎるかなと思いますし、紹介させていただいたCheckboxGrid Itemの設定をベースに読んでいただければ、読み解けるのではないかなと思います。

ここまででフォームを完成させることが出来ました!お疲れ様でした!

この状態で、新しく作成したフォームのページにアクセスして回答すると、フォームのデータ収集が可能です。(Google Workspaceでアクセスするほか、作成したフォームへのリンクを作成するform.getPublishedUrl()の返り値をconsole.log()で表示することでアクセスできます。)

しかし、収集したデータだけ別の管理になるのは少し違和感がありますね、、

Google Formsには回答のコピーをスプレッドシートに送る機能があります。その設定を次のセクションで紹介いたします

4. フォームの回答が、1を記載したスプレッドシートに表示されるよう設定する

わざわざセクションを分けましたが、そんなに大変なことはしません。

form.setDestination(type, id)という関数を呼び出すだけで、設定することが可能です。

typeはFormApp.DestinationType.SPREADSHEETのみがデフォルトで設定可能で、idには操作しているスプレッドシートのidを設定します。getId()関数を用いれば簡単に設定できます。

では、createQuestionnaire()関数の一番最後に以下の内容を記載します。

function createQuestionnaire() {
・・・
  settings.forEach((arr, index) => {
    console.log(index)
    constructFormItem(spreadSheet, form, arr);
  });

  //Form回答コピー設定
  form.setDestination(FormApp.DestinationType.SPREADSHEET, spreadSheet.getId());
}

これで、回答の記録がコピーされて、スプレッドシートにも流入するようになります。

この流入先シート名をコードで変えることは出来ないのですが、このシートを対象とするスクリプトを組むことで、収集したデータを加工していくことができますね。

以上で、今回の本題である「スプレッドシートで管理する情報から、フォームを作成して、そのフォームの回答を集める。」に関して完了です!お疲れ様でした!!

ここからフォーム作成のテンプレとすることもできますし、収集データを表に加工することもできますし、活用の仕方は工夫次第でどんどん広がっていくでしょう!ここでは初歩的なことしかしていないので、今すぐは難しいかもしれませんが、是非考えてみてください!!

終わりに

今回の記事は以上になります。ちょっとややこしい記事になり、ソースを見てください!の箇所も多くなってしまってすみません。

今回作ったものは、「特定のこれ」といったものでなく、「汎用的なパーツ」のような機能ですので、別ファイルに関数だけ切り出して、また他のツールを使うときに組み込んでみる、といった使い方もできるのではないかなと思います。

次回もこのような形で、GASのやってみた記事を上げられたらと思っておりますので、よければ目を通していただけると嬉しいです!!

それでは、最後までお付き合いいただき、ありがとうございました!MTでした。


【記事への感想募集中!】

記事への感想・ご意見がありましたら、ぜひフォームからご投稿ください!
  • こんな記事が読んでみたい、こんなことが知りたい、調べてほしい!という意見も募集中!
  • いただいた感想は今後の記事に活かしたいと思います!

感想フォームはこちら


【テクノデジタルではエンジニア/デザイナーを積極採用中です!】

下記項目に1つでも当てはまる方は是非、詳細ページへ!
  • 自分でアプリを作ってみたい
  • ITで世の中にワクワクを生み出したい
  • 使いやすさ、デザインにこだわったWebサイトを開発したい

採用情報の詳細はこちら


Qangaroo(カンガルー)

  • 徹底した見やすさと優れた操作性で、テストの「見える化」を実現。
  • テストの進捗が見える。開発がスマートに進む。
  • クラウド型テスト管理ツール『Qangaroo(カンガルー)』

【テクノデジタルのインフラサービス】

当社では、多数のサービスの開発実績を活かし、
アプリケーションのパフォーマンスを最大限に引き出すインフラ設計・構築を行います。
AWSなどへのクラウド移行、既存インフラの監視・運用保守も承りますので、ぜひご相談ください。
詳細は下記ページをご覧ください。

https://www.tcdigital.jp/infrastructure/

最近の記事