スプレッドシートにフォームを埋め込む/スプレッドシートからフォームを開いて入力する
スプレッドシートを共用していると、並びを動かされたり、指定の形式・書式でないものを入力されたり、まあ、そういったことがある。保護とか権限とかあるけどそれはそれとして。で、そういったことが積み重なると「人類が滅びればこの世の問題はほぼ解決する」「愚かな人間は滅ぶしかない」といった憎悪を募らせて精神的に良くないので、仕組みで解決を図る。同僚を土に埋める前に、スプレッドシートにフォームを埋め込もう。
フォームでは、回答の検証を用いれば、バリデーションすることもできる。
なお、このネタは、ノンプロ研のTさんから拝借した。構造化データを守るための方法の一つとして紹介されていた。slackでも質問にお答えいただき、心より感謝申し上げます。ありがとうございます!!!
ノンプロ研に在籍されている方は、20210106GAS初級講座第7期卒業LT大会02の13:00前後の動画およびスライドが参考になります(この情報は一般には非公開です)。
ノンプロ研の回し者ではないのですが、ノンプロ研の紹介をしておきます。紹介制度でアマギフ5000円もらえたりしますので、ご興味のある方はお気軽にお声掛けください。詳細は下記リンクよりどうぞ。
完成形のイメージ
スプレッドシートのメニューからフォームを呼び出して、そのフォームに入力するとスプレッドシートに反映される。
Accessで言うところの、テーブルとは別に、フォームでデータを入れる、みたいな感じ。Access用語だいぶ忘れているので、間違ってたらごめん。
通常のフォームとして、フォーム単独での使用ももちろんできる。
スプレッドシートにフォームを埋め込む手順
簡単なつくり方としては下記の通りかなと思う。
1.フォームを用意する
このnoteでは、例としてテンプレのTシャツ申込書をそのまま使ったが、もちろん自分で空白のフォームから作成しても良い。
2.フォームの回答からスプレッドシート作成
フォームの回答が溜まる先としてのスプレッドシートを作成する。基本的には新しいスプレッドシートを作成でOK。中~上級者は既存のスプレッドシートを選択したりGASしたり、うまいことしてください。
3.GASを書く
スプレッドシート>ツール>スクリプトエディタを開き、下記のコードを貼り付けます。
function myFunction() {
const html = `<iframe src="https://docs.google.com/****************</iframe>`;
// setHeightで縦setWidthで横の大きさを設定
const htmlOutput = HtmlService.createHtmlOutput(html).setHeight(700).setWidth(650);
const ui = SpreadsheetApp.getUi();
ui.showModalDialog(htmlOutput, "***フォーム名称など***");
}
//メニューバーに実行ボタン表示
function onOpen(){
const ui = SpreadsheetApp.getUi();
const menu = ui.createMenu("フォーム入力");
menu.addItem("フォーム入力", "myFunction");
menu.addToUi();
}
なお、私はここでこんなエラーに遭遇した。
スプレッドシートから、フォーム入力のメニュを押して、画面が表示されるのはいいんだけど、意図したフォームが表示されず、フォームのURLが表示される、という状態になってしまった。
うーん?と思っていたら、GASに貼りこむURLのデータはHTMLタグごとのデータだった。ここにフォームを外部に知らせるときのURLを入れてしまっていた。
4.動作確認
初回は権限認証が必要です。慣れない方は「スクリプト実行時の「承認」でびっくりしないために」という下記の解説ブログを参考にされるとよいでしょう。
Tips
スプレッドシートにおいて、私はこうしておくと良いと思う、という独断と偏見のtips。
・交互の背景色を設定しておくと見やすい
・罫線(枠線)はGASで扱えないので使用は勧めない。
・使用しない範囲の行、列は削除しておく。(余計なものは消しておく。意図しない欄外への入力の予防。見た目にもスッキリする)
コードの解説
解説というか、公式リファレンス貼ってるだけ......。なんか間違ったこと言ってたり、変なこと言ってたら教えてください。
スプレッドシートにフォームを表示
function myFunction() {
const html = `<iframe ***</iframe>`;
// setHeightで縦setWidthで横の大きさを設定
const htmlOutput = HtmlService.createHtmlOutput(html).setHeight(700).setWidth(650);
const ui = SpreadsheetApp.getUi();
ui.showModalDialog(htmlOutput, "T シャツ申込書");
}
const html = `<iframe ***</iframe>`;
ここで、表示させるhtmlを定義。
const htmlOutput = HtmlService.createHtmlOutput(html).setHeight(700).setWidth(650);
Class HtmlService の createHtmlOutput メソッドを使って、引数にさきほど定義したhtmlを渡す。要するに、先ほどのhtmlを表示してね!とお願いしている。
const ui = SpreadsheetApp.getUi();
ui.showModalDialog(htmlOutput, "T シャツ申込書");
スプレッドシートのUiを呼び出して、ダイアローグを表示させて、その中にhtmlOutput(つまり、ここではフォームのこと)を「T シャツ申込書」っていうタイトルとともに表示よろしく!とお願いしている。
Class HtmlService
Class Ui
showModalDialog
スプレッドシートに独自メニューの追加
function onOpen(){
const ui = SpreadsheetApp.getUi();
const menu = ui.createMenu("フォーム入力");
menu.addItem("フォーム入力", "myFunction");
menu.addToUi();
}
function onOpen(){
onOpenでシートが開かれたときに処理内容が自動的に動作する。
const ui = SpreadsheetApp.getUi();
スプレッドシートのUiを呼び出して、
const menu = ui.createMenu("フォーム入力");
menu.addItem("フォーム入力", "myFunction");
menu.addToUi();
指定したメニュを追加する。
const menu = ui.createMenu("フォーム入力");
↑この部分が第1階層(でいいのか?)でいちばんはじめに見えるところ。
menu.addItem("フォーム入力", "myFunction");
↑この部分が、クリックしたときに見えるメニュー部分になる。ここをクリックして、myFunctionで記述した処理を実行する。
メニュは今回は1つしかないが、増やすこともできる。
以上。