このページの内容
①のページにて入力画面を作成したので、次は表示画面を作成してみたいと思います。
一度にすべてのデータを表示させるとそのうち非常に量が多くなってしまうので、日付(期間)を指定して表示できるようにしてみたいと思います。
読み込ませたのはデータが少ないですが、次のようなスプレッドシートです。
//スプレッドシート内のデータを取得する
function GetSpreadsheet(term_from, term_to){
//操作するスプレッドシートIDとシート名を指定して開く
//spreadsheetIdは共通変数として定義しています。
var sheet = SpreadsheetApp.openById(spreadsheetId).getSheetByName('記録');
//最終列は判明しているので、最終行だけを取得する
var last_row = sheet.getLastRow(); //最終行取得
//1行目はヘッダーなので、2行目以降のデータを一旦すべて取得する
var values = sheet.getRange(2, 1, last_row - 1, 7).getDisplayValues();
//すべてのデータをクライアント側に送信する必要はないので、送信する分のデータ配列を定義する
var sendData = new Array();
var cnt = 0; //配列のカウンタ
for(var i = 0; i< values.length; i++){
//登録日が表示期間内に入っているものだけを送信配列に渡す
if(values[i][0] >= term_from && values[i][0] <= term_to){
sendData[cnt] = values[i];
cnt++;
}
}
return sendData;
}
ここで気を付けたいのが、“getValues”ではなく、”getDisplayValues”を使っている点です。
こちらのページでも書いていますが、日付の項目などを利用する場合、値だけであればgetValuesでも取得できるのですが、クライアント側で受信できません。
また、期間の比較を今回は文字列で行っているため、フォーマットが全く異なる文字列が取得されることになり、比較をすることができません。
<!DOCTYPE html>
<html>
<script>
function loadingProcess() {
//期間指定のterm_toを当日に設定しておく
var today = new Date();
var year = today.getFullYear();
var month = ("0" + (today.getMonth() + 1)).slice(-2);
var date = ("0" + today.getDate()).slice(-2);
document.getElementById("term_to").value = year + '-' + month + '-' + date;
//潜伏期間が最大2週間と言われているので、まずは2週間分を表示させる
var twoWeeks = new Date(today.getFullYear(), today.getMonth(), today.getDate() -14);
year = twoWeeks.getFullYear();
month = ("0" + (twoWeeks.getMonth() + 1)).slice(-2);
date = ("0" + twoWeeks.getDate()).slice(-2);
document.getElementById("term_from").value = year + '-' + month + '-' + date;
getDispData();
}
window.addEventListener('load', loadingProcess);
function getDispData(){
var term_from = document.getElementById("term_from").value;
var term_to = document.getElementById("term_to").value;
if(term_to < term_from){
alert('期間の開始と終了を確認してください。');
return;
}
google.script.run.withSuccessHandler(dispSpreadsheet).GetSpreadsheet(term_from, term_to);
}
//取得したデータを表示する
function dispSpreadsheet(spreadsheet_data){
var htmlTable = '<table id="tableSSData" border=1>';
//項目行を設定
htmlTable += '<tr><th>日付</th><th>時間帯</th><th>移動手段</th><th>場所(目的)</th><th>会った人/メモ</th></tr>';
for(var row = 0; row < spreadsheet_data.length; row++){
htmlTable += '<tr>';
//日付
htmlTable += '<td>' + spreadsheet_data[row][0] + '</td>';
//時間
htmlTable += '<td>';
if(spreadsheet_data[row][4] != ':'){
htmlTable += spreadsheet_data[row][4];
//開始時間、終了時間ともに入力されている場合だけ、'~'を入れる
if(spreadsheet_data[row][5] != ':'){
htmlTable += '~';
}
}
if(spreadsheet_data[row][5] != ':'){
htmlTable += spreadsheet_data[row][5];
}
htmlTable += '</td>';
//移動手段
htmlTable += '<td>' + spreadsheet_data[row][1] + '</td>';
//場所(目的)
htmlTable += '<td>';
htmlTable += spreadsheet_data[row][2];
if(spreadsheet_data[row][3] != ''){
htmlTable += '<br>' //見やすくするために、改行して表示
htmlTable += '(' + spreadsheet_data[row][3] + ')';
}
htmlTable += '</td>';
//会った人/メモ
htmlTable += '<td>' + spreadsheet_data[row][6] + '</td>';
htmlTable += '</tr>';
}
htmlTable += '</table>';
document.getElementById("dispArea").innerHTML = htmlTable;
}
</script>
<head>
<base target="_top">
</head>
<body>
<label>表示期間</label><br>
<!-- min属性だけは記録を開始した日なので、設定しておくといいでしょう -->
<input id="term_from" type="date" min="2020-05-01" onchange="getDispData();">
<label>~</label>
<input id="term_to" type="date" onchange="getDispData();"><br>
<div id="dispArea">
</div>
</body>
</html>
ここでは、日付の指定を変更するとonchangeイベントが発生し、その都度スプレッドシートのデータを取得するようにしています。
また、google.sript.runでサーバー側の関数を実行する際の引数は複数渡すことができますが、受け取って実行する関数は言うまでもないですが、returnで返ってくる値だけしか利用できません。
もし、複数の異なる値を受け取りたい場合は、何らかの工夫(配列で取得したり、サーバー側でタグをつけて取得したり等々)が必要になります。
実行するとロード完了時に、以下のような画面が表示されます。
また、表示期間を変更すると、その指定した期間の表示に変更されます。
もし、その都度サーバーとのデータのやり取りをしたくない場合は、サーバー側のデータを一括ですべて読み込み、クライアント側で表示するしないを制御してもいいかもしれません。
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<!-- ********** 部分は各自の環境に合わせてください -->
<a href="https://script.google.com/macros/s/AKf********************Uba/exec?mode=input" target="_blank">入力画面</a><br>
<a href="https://script.google.com/macros/s/AKf********************Uba/exec?mode=view" target="_blank">確認画面</a>
</body>
</html>
ここはこれだけです。
一度公開設定を実行した際に表示されるURLをコピーし、末尾にパラメータの設定として、”?mode=input”もしくは”?mode=view”を付加し、別画面で起動するようにするだけです。
最後に、サーバー側のコーディングが、書き込みと読み込みでページを分けて書いてしまっているので、全体がどうなるかを記載しておきます。
//スプレッドシートのID(スプレッドシートを開いた時のURLの https://docs.google.com/spreadsheets/d/*****************/edit#gid=########### の**の部分)
var spreadsheetId = '10R**************************************PcQ';
//実行時にwebサービスを実行させる
function doGet(e) {
var mode = e.parameter["mode"];
//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で指定、シートをシート名で指定
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;
}
//スプレッドシート内のデータを取得する
function GetSpreadsheet(term_from, term_to){
var sendData = new Array();
//操作するスプレッドシートIDとシート名を指定して開く
var sheet = SpreadsheetApp.openById(spreadsheetId).getSheetByName('記録');
//最終列は判明しているので、最終行を取得する
var last_row = sheet.getLastRow(); //最終行取得
//1行目はヘッダーなので、2行目以降のデータを一旦すべて取得する
var values = sheet.getRange(2, 1, last_row - 1, 7).getDisplayValues();
//すべてのデータをクライアント側に送信する必要はないので、送信する分のデータ配列を定義する
var cnt = 0; //配列のカウンタ
for(var i = 0; i< values.length; i++){
//登録日が表示期間内に入っているものだけを送信配列に渡す
if(values[i][0] >= term_from && values[i][0] <= term_to){
sendData[cnt] = values[i];
cnt++;
}
}
return sendData;
}
これで、入力と表示の両方ができるので、何時、何処で、誰に会ったかをメモしていくことが出来ます。
皆様の参考になれば幸いです。
また、このようなことを行わなければいけない事態が早く収束することを願っております。