-----
・追記(2022-4-30)
コードを一部修正しました。
-----
単体でも便利なGoogle フォームですが、GAS(Google Apps Script)を使うことで、いっそう便利になります。
例えば、スプレッドシートを連携することで、選択肢を動的に変更することができます。
ということで、スプレッドシートと連携して、動的に在庫の反映などをしてくれる「注文フォーム」を作ってみました。
追加で、確認メールの自動送信機能も付けました。
▼ Google フォームの準備
まずは、元となるフォームを作成します。
項目は以下の通りです。商品タイトル、及び各項目の選択肢は、後ほど、GASで入力します。
1) 商品 [プルダウン] ※1~複数個
2) お名前 [記述式](必須)
3) メールアドレス [記述式](必須)
4) お電話番号 [記述式]
5) 住所(都道府県) [プルダウン](必須)
6) 住所(続き) [記述式](必須)
7) お支払い方法 [ラジオボタン](必須)
8) アンケート [チェックリスト]
メールアドレスは、回答の検証を付けておいた方がいいですね。
▼ スプレッドシートの準備
フォームの回答先として、スプレッドシートを作成します。
回答先のシートの他に、「item」「pref」「paym」「ques」という4つのシートを作成します。
回答先のシート名はデフォルト(「フォームの回答 1」)でも問題ありませんが、今回は「form」という名前に変更しています。
各シートの役割は以下の通りです。シートそれぞれの書き方は → こちらを参考にしてください。
・「item」 → 1) 商品のデータ
商品名、価格、在庫数が記載された商品データを入力しておきます。商品数はいくつでも大丈夫です(フォームの商品項目の数を合わせます)。
注文を受けると、在庫が減っていきます。
・「pref」 → 5)住所(都道府県)のデータと対応する送料のデータ
47都道府県の一覧と、対応する送料のデータを入力しておきます。
・「paym」 → 7) お支払い方法のデータ
お支払い方法の一覧を入力しておきます。
・「ques」 → 8) アンケートのデータ
チェックリスト方式のアンケートを入力しておきます。
この項目は、スクリプトの例として、チェックリストを含めたかったために作ったので、不要であれば削除してください。
▼ スクリプトの作成
フォームより、スクリプトを作成します。フォームから作ることで、トリガー作成時に、イベントのソースとしてフォームを選択することができます。
スクリプトは2つ、スプレッドシートの内容に応じて選択肢を動的に入力するための「set-form.gs」と、在庫の計算と確認メールを送信をするための「order.gs」になります。
「set-form.gs」
function setForm() {
const sp = SpreadsheetApp.openById("スプレッドシートID");
const itemList = sp.getSheetByName("item");
const prefList = sp.getSheetByName("pref");
const paymList = sp.getSheetByName("paym");
const quesList = sp.getSheetByName("ques");
let itemNum = itemList.getLastColumn() - 1;
const form = FormApp.openById("フォームID");
const ques = form.getItems();
//商品(プルダウン)
for(let i = 0; i < itemNum; i++) {
let que_item = ques[i];
let itemName = itemList.getRange(1,i + 2).getValue();
let itemAmt = itemList.getRange(2,i + 2).getValue();
let stock = itemList.getRange(3,i + 2).getValue();
let que_itemList = [];
for(let x = 1; x <= stock; x++) {
que_itemList.push(x);
}
que_item.asListItem().setTitle(itemName + " / ¥" + itemAmt).setChoiceValues(Array.prototype.concat.apply([], que_itemList));
}
//都道府県(プルダウン)
const que_pref = ques[itemNum + 3];
let pref_lastRow = prefList.getLastRow() - 1;
let que_prefList = prefList.getRange(2,1,pref_lastRow,1).getValues();
que_pref.asListItem().setChoiceValues(Array.prototype.concat.apply([], que_prefList));
//支払い方法(ラジオボタン)
const que_paym = ques[itemNum + 5];
let paym_lastRow = paymList.getLastRow() - 1;
let paym_prefList = paymList.getRange(2,1,paym_lastRow,1).getValues();
que_paym.asMultipleChoiceItem().setChoiceValues(Array.prototype.concat.apply([], paym_prefList));
//アンケート(チェックボックス)
const que_ques = ques[itemNum + 6];
let ques_lastRow = quesList.getLastRow() - 1;
let que_quesList = quesList.getRange(2,1,ques_lastRow,1).getValues();
que_ques.asCheckboxItem().setChoiceValues(Array.prototype.concat.apply([], que_quesList));
que_ques.asCheckboxItem().showOtherOption(true);
}
書き換えが必要な箇所は以下の通りです。
・4行目「スプレッドシートID」
スプレッドシートURLの下記部分です。
https://docs.google.com/spreadsheets/d/ここの値をコピペ/edit#gid=0
・12行目「フォームID」
フォーム(編集画面)URLの下記部分です。
https://docs.google.com/forms/d/ここの値をコピペ/edit
アンケートの項目が不要な場合は、8行目、及び41〜46行目を削除してください。
「order.gs」
function submitForm(e) {
let quesResp = e.response.getItemResponses();
const sp = SpreadsheetApp.openById("スプレッドシートID");
const itemList = sp.getSheetByName("item");
const prefList = sp.getSheetByName("pref");
let itemNum = itemList.getLastColumn() - 1;
//在庫再計算
for(let i = 0; i < itemNum; i++) {
let stock = itemList.getRange(3,i + 2).getValue() - quesResp[i].getResponse();
itemList.getRange(3,i + 2).setValue(stock);
}
//メール
//内容の作成
let order = [];
let total = 0;
for(let i =0; i < itemNum; i++) {
if(quesResp[i].getResponse() != null) {
order.push(itemList.getRange(1,i + 2).getValue() + " 数量:" + quesResp[i].getResponse() + " ¥" + itemList.getRange(2,i + 2).getValue() * quesResp[i].getResponse() + "\n");
total += itemList.getRange(2,i + 2).getValue() * quesResp[i].getResponse();
}
}
let prefFinder = prefList.getRange("A2:A").createTextFinder(quesResp[itemNum + 3].getResponse()).findAll();
let pstg = prefList.getRange(prefFinder[0].getRow(),2).getValue();
total += pstg;
let content = quesResp[itemNum].getResponse() + ' 様\n\n以下の内容でご注文を承りました。ご確認ください。\n\n-----\n' + order.join("") + '送料 ¥' + pstg + '\n\n合計 ¥' + total + '\n-----\n\nお支払い方法:' + quesResp[itemNum + 5].getResponse();
//送信
GmailApp.sendEmail(
quesResp[itemNum + 1].getResponse(),
'ご注文を承りました。',
content,
{
from: '送信元メールアドレス',
name: '送信者名'
}
);
//在庫をフォームに反映
setForm();
}
書き換えが必要な箇所は以下の通りです。
・4行目「スプレッドシートID」
「set-form.gs」のスプレッドシートIDと同じです。
・37行目「送信元メールアドレス」
・38行目「送信者名」
送信元メールアドレスは、Google アカウントのGmail、もしくはエイリアスとして追加しているメールアドレスを指定できます。送信者名は、自由に指定。
GASによるメールの扱いは「Gmailで定期的にメールを自動送信する。」をご参照ください。
▼ トリガー設定
・「order.gs」のトリガー
「実行する関数を選択」→ submitForm
「実行するデプロイを選択」→ Head
「イベントのソースを選択」→ フォームから
「イベントの種類を選択」→ フォーム送信時
「エラー通知設定」→ 今すぐ通知を受け取る
▼ 自動送信される確認メール
ということで、一通りできました。
![詳解! Google Apps Script完全入門 [第3版]](https://m.media-amazon.com/images/I/51Ave84HXfS._SL160_.jpg)
詳解! Google Apps Script完全入門 [第3版]
by SimpleImageLink
***
あとは、決済部分ですね。
-----
・追記(2023-11-14)
フォームから決済までつなげてしまうならオンライン決済サービスの導入が必要になります。
それでも、フォームに直接は繋がらないので、メール等を介してワンクッションは必要になります。
・追記(2023-11-24)
-----
BASE等、簡単にネットショップを作ることができ、細かい便利機能もいろいろあるECサービスですが、結局、肝となるのは決済部分かと思います。
しかし、最近は、ネット銀行や送金アプリもとても便利なので、自前で用意可能な決済方法でも、それほど障壁にはならない(決済手段によって購入をやめてしまうことが少ない)のではないか、という気がするのですよね。
であれば、このくらいのざっくり自作フォームでも、ECをまかなえてしまうパターンが多々あるのではなかろうかと思います。
そんな仮説を立ててみたので、8年(内7年くらいは開店休業)使っていたBASEを、昨日退会しました。
そういえば、Googleがpringを買収したので今後の展開に期待しています。
Twitter(@nkkmd)日々更新中です。

