10
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Googleフォームのテキスト入力で、すでに登録済みの文字列に警告を出す

Last updated at Posted at 2020-05-30

#背景と目的

  • 大学で担当している授業で、Google アプリをあれこれ利用している。
  • Googleフォームを使って、ハンドルネームを登録してもらうことにした。
  • ハンドルネームの 重複を避けたい
  • Googleフォームの 回答の検証 機能を利用して実現したい。

#もくろみ

  • Googleフォームの送信時に発火するトリガーを仕掛け、すでに送信されたハンドルネームのリスト作って、これらに一致するハンドルネームの送信を拒否するようにする。
  • 回答の検証は決まった数種類しかなく、関数を書いてカスタムの検証を設定することはできない。
    • もっとも自由なのは正規表現。正規表現でなんとかするしかない。
  • 正規表現で既存のハンドルネームに一致しないような回答の検証を設定できればいいはず。
  • これを、Google Apps Script(GAS)で実装する。

#Googleフォームで使える正規表現

  • いろいろ試行錯誤した結果、Googleフォームの回答の検証では、正規表現の否定的先読み ?!(foo|bar) は使えないことがわかった。
  • 代わりに、正規表現パターンに一致しない条件での検証が可能。

#GASの実装

  • Googleフォームを編集して、右上の〔⁝〕からプルダウンメニューを引きだし、クリプトエディタを呼びだす。
  • 以下のようにスクリプトを書いて保存する。

スクリプトエディタを開く.png

コード.gs
function setHandlenameValidation() {

  var thisForm = FormApp.getActiveForm();
    
  // 既存の回答を全部引っ張ってきて、ハンドルネームを取りだす。ハンドルネームは2番目のItemに格納されている。
  // エスケープした既存ハンドルネームのリスト escapedHandlenameList を作成
  var escapedHandlenameList = []
  var responseList = thisForm.getResponses();
  for ( var i = 0; i < responseList.length; i++ ){
    escapedHandlenameList.push( 
      responseList[i].getItemResponses()[1]
        .getResponse().replace(/[\\^$.*+?()[\]{}|\ ]/g, '\\$&')
    );
  }

  // 正規表現のパターン文字列 validationExpression を生成
  var validationExpression = escapedHandlenameList.map(element => `${element}`).join('|')
  validationExpression = "^(" + validationExpression + ")$";

  // TextValidation オブジェクト textValidation を作成
  // requireTextDoesNotMatchPattern() で、正規表現パターンに一致「しない」ことを検証の条件にできる。
  var textValidation = FormApp.createTextValidation()
    .setHelpText('すでに使われているハンドルネームです。')
    .requireTextDoesNotMatchPattern( validationExpression )
    .build();

  // textValidation を2番目の Item に登録
  var formItems = thisForm. getItems()[1]
    .asTextItem().setValidation( textValidation );
}
  • メニューの 実行関数を実行 から書いた関数を実行して、正しく動作することを確認する。
    • 正しく動作すると、フォームの該当するテキスト入力アイテムに回答の検証が生成される。すでに存在していた場合には、現在の状況に応じた内容に上書きされる。
      スクリーンショット 2020-05-31 12.05.40.png

#トリガーの設定

  • メニューの 編集現在のプロジェクトのトリガー をクリック。
  • トリガーを追加をクリック。
    • イベントのソースを選択:フォームから
    • イベントの種類を選択:フォーム送信時
      スクリーンショット 2020-05-31 11.30.24.png

動作状況の確認

  • GASダッシュボード上のプロジェクト名からのプルダウンメニューで実行数をクリックすると、トリガーの実行状況を確認できる。実行に失敗した場合、ステータス欄に失敗しましたと表示される。
    • ダッシュボード左側のナビゲータ内にある 実行数 からは、すべてのトリガーの実行状況がわかる。
      スクリーンショット 2020-05-31 11.38.40.png

#問題点

  • 回答の検証の内容はフォームを開く際に確定する。そのため、ユーザーがwebブラウザでフォームを開いてから送信するまでの間に他のユーザーが送信したハンドルネームとの重複は検証できない。
  • サーバ側では検証は行われないので、こうした状況が発生すると、重複するハンドルネームが登録されてしまう。
  • GASでこれを回避するのはおそらく難しい。
    • 重複が発生した場合にハンドルネームの末尾に適当な文字列を付加するなどして重複を避け、GmailApp を使ってそのことをユーザーに知らせるくらいが限界か。
  • 筆者のケースは、大学の授業で履修者はおよそ250人で、人数が増えることもなく、アクセス頻度や登録数もさほどではないので、重複に関してはマニュアル対応することにしている(発生頻度はとても低いと考えられるので)。
10
11
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
10
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?