Googleフォームで在庫の限られている商品の配布が可能かどうか調べてみました。
例えば限られた枚数の無料チケットが手元にあったとして、「先着順で希望枚数を配布し、在庫が尽きたら終了」とする運用を、なるべく手間なくやりたいというのが目的です。
以下、具体的なスクリプトコードなどは(検索すればいくらでも出てきますので)明記しませんがポイントだけ記載しておきます。
【申し込み方法はGoogleフォーム】
申し込みフォームはGoogleフォームを使うことが前提です。簡単に作れて社員にのみ公開できる点が理由です。
【申し込み結果はGoogleスプレッドシート】
必要事項をフォームに書き込んでもらって、送信結果をスプレッドシートに書き出し、あとで処理(発送等)します。
【排他処理】
まず最初の問題は「排他処理」ができるか?ということです。同時に複数の申し込みがあった場合に抜けなく処理する必要があるからです。
ロックの種類は3種類。
・ドキュメントロック
LockService.getDocumentLock()
同一ドキュメントに対するスクリプトの実施をロックする。
・ユーザーロック
LockService.getUserLock()
同一ユーザによるスクリプトの実施をロックする。
・スクリプトロック
LockService.getScriptLock()
同一スクリプトの実施に対してロックする。
ロック方法は2種類。違いや使い方は検索してください。
・tryLock(ミリ秒)
・waitLock(ミリ秒)
【トリガー】
スクリプトをフォーム側に置くかスプレッドシート側に置くかはトリガーがかかわってきます。
・フォームのスクリプトのトリガーは以下の2つ。「起動時」はユーザーがフォームを開いた時ではなく管理者が編集画面を開いた時を開いた時なので使いどころがないように思えます。「フォーム送信時」は実際には「フォーム送信後」と考えた方が良さそうです。
①起動時
②フォーム送信時
・スプレッドシートのスクリプトのトリガーは以下の4つ。「起動時」はシートを開いた時、「編集時」はセル内容を編集した時、「変更時」は行・列の追加・削除など、「フォーム送信時」は文字通りフォームと紐づいているときにフォームに回答があった時。
①起動時
②編集時
③変更時
④フォーム送信時
【在庫管理】
在庫数はスプレッドシートに書き込みます。1人1枚でしたらフォームから書き出すスプレッドシートの行数で在庫数を管理できますが、1人複数枚の場合はどうしても「在庫」セルが必要となります。フォームから書き出すスプレッドシートと兼用でも別でもかまいません。
ということは在庫数を管理するスプレッドシートあるいは在庫数を読み書きするスクリプトをロックすれば良いことがわかります。
【受注の可否はメールで報告】
フォームを開いた時に在庫があっても送信時には在庫が無いかもしれません。この場合においても、スクリプトが「フォーム送信時」に実行されたときに初めて在庫がないことが判明します。その時には既にフォームの送信は「完了」しているのでユーザーには受注可否がわかりません。ですのでフォームの完了画面には「結果はメールで確認してください」とし、実際の受注可否はメールで送信することになります。
【在庫ゼロの時にフォームを閉じる】
既に在庫が無いのにフォームを開けておくのは不親切です。フォームを閉じる関数がちゃんと用意されていますので、在庫を書き換える際にフォームを閉じる作業も行います。
setAcceptingResponses(false)
【在庫数に応じて選択できる購入数を変化させる】
例えばフォームの購入数を1,2,3,4のプルダウンにして選択させている(最大購入数を4に設定している)状況で在庫が2になったとします。その時にはプルダウンも1,2だけにしてやると親切だと思います。一例として以下のようにするとフォームの設定(回答の選択肢)を変更可能です。
質問を取得
FormApp.getActiveForm().getItems
選択肢をリストに入れる
arrList = [];
選択肢をセット
asListItem().setChoiceValues(arrList)
以上によって目的はほぼ満たせることがわかりました。「ほぼ」としているのはフォームの「送信」ボタンを押すと次の画面で「受注しました」あるいは「受注できませんでした」と表示されるのが理想なのですが、後でメールを見ないとわからない点が難点だからです。
排他処理の失敗によるダブルブッキングが心配なのですが、今のところは不具合は発生していません。申し込みが殺到するような状況でないからかもしれませんが。
0 件のコメント:
コメントを投稿