見出し画像

スプレッドシートにフォームを埋め込む/スプレッドシートからフォームを開いて入力する

スプレッドシートを共用していると、並びを動かされたり、指定の形式・書式でないものを入力されたり、まあ、そういったことがある。保護とか権限とかあるけどそれはそれとして。で、そういったことが積み重なると「人類が滅びればこの世の問題はほぼ解決する」「愚かな人間は滅ぶしかない」といった憎悪を募らせて精神的に良くないので、仕組みで解決を図る。同僚を土に埋める前に、スプレッドシートにフォームを埋め込もう。

フォームでは、回答の検証を用いれば、バリデーションすることもできる。

画像8

なお、このネタは、ノンプロ研のTさんから拝借した。構造化データを守るための方法の一つとして紹介されていた。slackでも質問にお答えいただき、心より感謝申し上げます。ありがとうございます!!!

ノンプロ研に在籍されている方は、20210106GAS初級講座第7期卒業LT大会02の13:00前後の動画およびスライドが参考になります(この情報は一般には非公開です)。

ノンプロ研の回し者ではないのですが、ノンプロ研の紹介をしておきます。紹介制度でアマギフ5000円もらえたりしますので、ご興味のある方はお気軽にお声掛けください。詳細は下記リンクよりどうぞ。


完成形のイメージ

画像7

スプレッドシートのメニューからフォームを呼び出して、そのフォームに入力するとスプレッドシートに反映される。

Accessで言うところの、テーブルとは別に、フォームでデータを入れる、みたいな感じ。Access用語だいぶ忘れているので、間違ってたらごめん。

通常のフォームとして、フォーム単独での使用ももちろんできる。


スプレッドシートにフォームを埋め込む手順

簡単なつくり方としては下記の通りかなと思う。

1.フォームを用意する

このnoteでは、例としてテンプレのTシャツ申込書をそのまま使ったが、もちろん自分で空白のフォームから作成しても良い。

画像1

2.フォームの回答からスプレッドシート作成

フォームの回答が溜まる先としてのスプレッドシートを作成する。基本的には新しいスプレッドシートを作成でOK。中~上級者は既存のスプレッドシートを選択したりGASしたり、うまいことしてください。

画像2


画像3

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();
}

なお、私はここでこんなエラーに遭遇した。

画像5

スプレッドシートから、フォーム入力のメニュを押して、画面が表示されるのはいいんだけど、意図したフォームが表示されず、フォームのURLが表示される、という状態になってしまった。

うーん?と思っていたら、GASに貼りこむURLのデータはHTMLタグごとのデータだった。ここにフォームを外部に知らせるときのURLを入れてしまっていた。

画像6


4.動作確認

初回は権限認証が必要です。慣れない方は「スクリプト実行時の「承認」でびっくりしないために」という下記の解説ブログを参考にされるとよいでしょう。



Tips

スプレッドシートにおいて、私はこうしておくと良いと思う、という独断と偏見のtips。

・交互の背景色を設定しておくと見やすい
・罫線(枠線)はGASで扱えないので使用は勧めない。
・使用しない範囲の行、列は削除しておく。(余計なものは消しておく。意図しない欄外への入力の予防。見た目にもスッキリする)

画像4


コードの解説

解説というか、公式リファレンス貼ってるだけ......。なんか間違ったこと言ってたり、変なこと言ってたら教えてください。

スプレッドシートにフォームを表示

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つしかないが、増やすこともできる。

以上。

いただいたサポートで、書籍代や勉強費用にしたり、美味しいもの食べたりします!