見出し画像

#19 Google フォームで日付を自動入力したい

いろいろな場面で便利な Google フォーム。
基本的に、Google フォームに回答してもらおうとすると、下図のような画面になっているかと思います。注目して欲しいのは、「どの項目も空欄からはじまっている」というところです。

Google フォームで回答してもらうときのイメージ

回答するために画面を表示したとき、一般的に選択されるであろう内容が入力/選択されていたら便利だと思いませんか? 特に、今日の日付がはじめから入力されていたら便利ではないですか?
このあたりを解決できないかを調べてみました。

※2022/02/26 に、Google フォームの初期値を設定する UI が実装されていることが確認できたので、内容を修正しました。

初期値を指定する方法

Google フォームの編集画面では、テストとして動作させるときの「解答」が指定できたり、「回答の検証」といった入力される値のチェックは行えるものの、初期値を設定する UI(ユーザーインターフェース)は用意されていない。 ※2022/02/15 時点
、初期値を設定する UI も用意されていました。この辺りの操作は、以下の URL をご覧ください。

この方法で得られるリンクは、回答用の URL の末尾にパラメータを追加してやることで、初期値として選択された状態にできるもののようです。

回答用の URL の末尾にパラメータを追加
選択された状態で表示される

しかしながら、この方法を利用しても「日付」の初期値を「今日」とは指定できません。今日の日付をパラメータとして与えた URL を、毎日用意して提供すればいいのかもしれませんが、ちょっと面倒な感じ…

スクリプトはいつ実行される?

そもそも、Google フォームを利用する場合、GAS のスクリプトはいつ実行されるのかを確認してみました。
実行されるタイミングとしては、次のような感じになるでしょう。

  1. Google フォームが「編集モード」で開かれたとき → onOpen(e)

  2. Google フォームで回答が送信されたとき(Google フォーム側) → Google Forms events

  3. Google フォームで回答が送信されたとき(Google スプレッドシート側) → Google Sheets events

  4. 指定された時間にトリガーを設定しておいて実行する

今回の目的を実現することを考えると、上記の 1. や 4. のタイミングは適切ではない感じ。また、2. や 3. は回答された後に実行されるので、タイミングとしては遅い。

考え方を変えて…

前述までのように、回答者が回答しようとしたタイミングでは「日付」に今日の日付が指定された状態にすることは、現状ではできないみたい。 ※2022/02/15時点(今後、実装される期待を込めて、日付を書いておく)

そこで、編集画面で「説明」に下図のような文章を追加しておき、日付が入力されなかった場合には、今日の日付が入力されたものとして扱うプログラムを作ってみることにした。

「説明」を追加

では、上流と思われる 2. の方から試してみます。

Google フォームで回答が送信されたとき
(Google フォーム側) → できない

Google Forms events でフォームが送信されたときに発生するトリガーで、GAS のプログラム(関数)を実行させた場合、関数の引数として渡されるパラメータの中には、次の 4つが格納されている。

  • authMode
    ScriptApp.AuthMode 列挙型からの値。

  • response
    FormResponseフォーム全体に対するユーザーの応答を表すオブジェクト。

  • source
    スクリプトがバインドされているGoogleフォームファイルを表すFormオブジェクト。

  • triggerUid
    このイベントを生成したトリガーのID。

これらの中で response を利用すれば、回答の内容は確認できる。しかしながら、単純にこの response 以下の内容を使っただけでは、getItemResponses() で回答を得たとしても、得られた ItemResponse[] には回答を変更するための関数(命令)は用意されていない。

それぞれの回答について確認するだけなら、以下のようなプログラムを記述すれば大丈夫なのですが、その回答を変更・再編集するような関数(命令)は用意されていないようなのです。
その回答を特定するための ID を取得できたりもしますが、その ID を使っても得られるものは FormResponse でしかなく、回答された内容を編集することはできないようです。
確かに、現状では Google フォームの UI でも回答は編集できませんもんね。

ちなみに、Logger.log( ) は GAS のプログラムがどのように動作したのかをログに記録するためのものです。console.log( ) だと、トリガーとして実行されたときの表示が確認できないので、Logger.log( ) を使います。

Google フォームで回答が送信されたとき
(Google スプレッドシート側)

Google フォーム側では対応できないので、Google スプレッドシート側での対応を考えてみます。
Google Sheets events でフォームが送信されたときに発生するトリガーで、GAS のプログラム(関数)を実行させた場合、関数の引数として渡されるパラメータの中には、次の 4つが格納されています。

  • authMode
    ScriptApp.AuthMode 列挙型からの値。

  • namedValues
    フォーム送信からの質問の名前と値を含むオブジェクト。

  • range
    Range 編集されたセルまたはセルの範囲を表すオブジェクト。

  • triggerUid
    このイベントを生成したトリガーのID。

  • values
    スプレッドシートに表示されるのと同じ順序の値を持つ配列。

その回答内容だけを用いた処理であれば、上記のデータで対応できそうですが、省略された日付をスプレッドシートに書き戻すことを考えると、スプレッドシート本体にもアクセスしなければいけなさそうです。

簡単に作ってみたのが、以下のプログラムです。冒頭のような Google フォームで動作することを想定しているので、e.values  には以下のようなデータが入力されてくる場合の処理です。

  • e.values[ 0 ]  : タイムスタンプ

  • e.values[ 1 ]  : 「日付を入力します」の回答内容 ←これが日付!

  • e.values[ 2 ]  : 「気分は?」の回答内容

  • e.values[ 3 ]  : 「連絡事項」の回答内容

25行分の短いプログラムですが、どのような処理をしているのか、簡単に説明します。

  • スプレッドシートへの書き戻しを行うために、3行目でスプレッドシートへのアクセスに必要な Class Sheet を取得しています。

  • 6行目で、そのシートのデータをすべて取得しています。実際に使用しているのは、最新であろう最後の行だけなのですが、すべてのデータを取得しています。

  • 8 ~ 11行目は、プログラムの動作には影響がない処理です。得られた回答の内容を、質問の内容とともにログに書き込んでいるだけの処理です。

  • 14行目が、日付の入力が省略されているかを判断している部分です。日付が入力されておらず、この条件を満たしていれば、15 ~ 23行目の処理が実行されます。

  • 18 ~ 20行目では、入力された値と実際のスプレッドシートの値が一致しているかをチェックしています。この処理が必要かどうかは微妙なところなのかもしれませんが、念のために行っている処理です。

  • 22行目が、実際にスプレッドシートにデータを書き戻している部分です。

最後に

いろいろと試してみて、何とか日付入力されなかったときに、今日の日付が入力されたことにはできたような感じ。やはり、GAS でも思うように処理できない部分があるな、と感じました。

しかし、今日の日付を自動で入力するくらいなら、入力させなければいいんじゃないか、と思ったり…
シートの列 A には、タイムスタンプが設定されてくるので、それによって日付が入力されたと判断できないでもないだろうし、以下のように先頭 10文字分を切り取れば、入力されたようなデータも得られる。

=LEFT(A34,10)

何よりも、入力しなくてもよい情報は入力させないような UI を作るべきなんだろうな、と思います。


この記事が気に入ったらサポートをしてみませんか?