コロナウィルスの拡大により、政府から“「新しい生活様式」の実践例”というものが、公開されていることをご存知の方も多いと思います。
その中で、“移動に関する感染対策”という項目の中で、“発症したときのため、誰とどこで会ったかをメモにする”ということが推奨されています。
この活動履歴のメモをGASを利用して、Webアプリ化してみたいと思います。
このページの内容
どんな機能を作成したらよいかを考えてると、「入力画面」
と「閲覧画面」の2つが必要になりそうです。
これは、以下のようにパラメータを指定して、ページ分けを実現しています。
//実行時にwebサービスを実行させる
function doGet(e) {
//パラメータを渡して、読み込ませるhtmlファイルを変更する
var mode = e.parameter["mode"];
var html;
if(mode == 'input'){
//入力画面
html = HtmlService.createTemplateFromFile("input.html");
}else if(mode == 'view'){
//閲覧画面
html = HtmlService.createTemplateFromFile("view.html");
}else{
//メニュー画面
html = HtmlService.createTemplateFromFile("menu.html");
}
return html.evaluate();
}
また、スプレッドシートをデータベースとして利用するので、ある程度、フォーマットを決めてやる必要があります。
今回は、以下のようなフォーマットにしました。
このスプレッドシートに書き込むのは、次のような関数で実行します。
//スプレッドシートにデータを書き込む
function SetSpreadSheet(data){
var ret = false;
try{
//ファイルをIDで指定、シートをシート名で指定
//※spreadsheetIdは共通変数で定義してあります
var sheet = SpreadsheetApp.openById(spreadsheetId).getSheetByName('記録');
//最終行番号取得
var last_row = sheet.getLastRow();
//クライアントから渡された配列は一次元の配列なので、
//そのままsetValuesには入れれないので2次元配列にする
var write_data = new Array();
write_data[0] = data;
//最終行の次の行に追記する
sheet.getRange(last_row + 1, 1, 1, 7).setValues(write_data);
ret = true;
}catch(e){
Logger.log(e);
}
return ret; //書き込み成功or失敗の結果をクライアントに返す
}
これで、サーバー側の書き込み処理は完成です。
次に、クライアント側の処理についてです。
処理の内容はscriptの中にjavascriptで記載しています。
ここでは、
①滞在時間入力のための時間コンボボックスを画面のロードに作成
②サーバー側処理(.gs)で書き込み処理を実行するための処理を実行
③書き込み処理結果を受け取り&フォームの初期化
する処理を記載しています。
その他HTML部分に関しては、移動方法のコンボボックスの作成をオンコーディングで記載しています。
<!DOCTYPE html>
<html>
<script>
function loadingProcess(){
//滞在時間の時刻入力オプションを作成する
setStartEnd('start');
setStartEnd('end');
}
window.addEventListener('load', loadingProcess);
function setStartEnd(start_end){
//時間の選択肢
var hour = document.getElementById(start_end + '_hour');
for(var i = -1; i < 24 ; i++){
var opt = document.createElement('option');
if(i == -1){
opt.setAttribute('value', '');
opt.innerHTML = '';
}else{
opt.setAttribute('value', i);
opt.innerHTML = i;
}
hour.appendChild(opt);
}
//分の選択肢(5分ごとにしておく)
var minute = document.getElementById(start_end + '_min');
for(var i = -1; i < 12; i++){
var opt = document.createElement('option');
if(i == -1){
opt.setAttribute('value', '');
opt.innerHTML = '';
}else{
opt.setAttribute('value', i * 5);
opt.innerHTML = i * 5;
}
minute.appendChild(opt);
}
}
//書き込み処理
function writeSpreadsheet(){
var write_data = new Array(); //書き込みデータ格納用配列
//各情報の値を取得する
var transportation = document.getElementById('transportation').value;
var place = document.getElementById('place').value;
var purpose = document.getElementById('purpose').value;
var start_time = document.getElementById('start_hour').value + ':' + document.getElementById('start_min').value;
var end_time = document.getElementById('end_hour').value + ':' + document.getElementById('end_min').value;
var person = document.getElementById('meet_person').value;
write_data = [FormatDate(), transportation, place, purpose, start_time, end_time, person];
//書き込みを実行して、成功or失敗を取得する
google.script.run.withSuccessHandler(resultMessage).SetSpreadSheet(write_data);
}
//書き込み結果を取得して表示&初期化する
function resultMessage(ret){
//書き込み結果として、メッセージを表示する
if(ret == true){
alert('書き込みました。');
//初期化する
document.getElementById('transportation').selectedIndex = 0;
document.getElementById('place').value = '';
document.getElementById('purpose').value = '';
document.getElementById('start_hour').selectedIndex = 0;
document.getElementById('start_min').selectedIndex = 0;
document.getElementById('end_hour').selectedIndex = 0;
documnet.getElementById('end_min').selectedIndex = 0;
document.getElementById('meet_person').value = '';
}else{
alert('記録に失敗したので、再度登録してください');
}
}
//今日の日付をyyyy-mm-dd形式で返す
function FormatDate(){
var today = new Date();
var year = today.getFullYear();
//getMonthで取得できるのは0~11なので、+1する。
//頭に0をつけて、後ろ2桁を取得してmm表記にする
var month = ("0" + (today.getMonth() + 1)).slice(-2);
var date = ("0" + today.getDate()).slice(-2);
return year + '-' + month + '-' + date; //yyyy-mm-dd形式
}
</script>
<head>
<base target="_top">
</head>
<body>
<label>移動手段</label><br>
<select id="transportation">
<option value=""></option>
<option value="徒歩">徒歩</option>
<option value="自転車">自転車</option>
<option value="車">車</option>
<option value="バス">バス</option>
<option value="電車">電車</option>
<option value="タクシー">タクシー</option>
</select><br>
<p>
<label>場所</label><br>
<input id="place" type="text">
</p>
<p>
<label>目的</label><br>
<input id="purpose" type="text">
</p>
<p>
<label>滞在時刻</label><br>
<select id="start_hour"></select>
<label>:</label>
<select id="start_min"></select>
<label>~</label>
<select id="end_hour"></select>
<label>:</label>
<select id="end_min"></select>
</p>
<p>
<label>会った人/メモ</label><br>
<textarea id="meet_person" rows="8"></textarea><br>
</p>
<input type="button" value="書き込み" onclick="writeSpreadsheet();">
</body>
</html>
記述後、公開の設定を行ってください。
また、スプレッドシートへのアクセス権の設定も実行してください。
その後、公開URLの末尾に”?mode=input“を付加して実行してください。
もしくはここまでの状態であれば、必ずinput.htmlを読み込むようにしておいてもいいかもしれませんね。
スマホでの表示画面は次のようになります。※スマホはXperia XZ3での表示結果です。
パッと見たところ、非常に入力フォームが小さく感じますが、各入力項目をタップすると次のように拡大されるので、問題ないと思います。
では、入力を実際にしてみましょう。
試しに、次のように入力してみます。
書き込みボタンを押下すると、成功したメッセージが表示されます。
スプレッドシートには以下のように書き込まれます。
改行を入れても、そのまま改行が反映されているのが分かります。
これで書き込みまではできるようになりました。
次は表示画面を作成していきます。