GAS(GoogleAppsScript) Webアプリ アプリケーション開発

GASの利用 ~新しい生活様式のためのメモ②~

投稿日:2020年6月24日 更新日:

このページの内容

①のページにて入力画面を作成したので、次は表示画面を作成してみたいと思います。

一度にすべてのデータを表示させるとそのうち非常に量が多くなってしまうので、日付(期間)を指定して表示できるようにしてみたいと思います。

読み込ませたのはデータが少ないですが、次のようなスプレッドシートです。

書き込み処理にて書き込まれたスプレッドシート

コーディング(.gs)

//スプレッドシート内のデータを取得する
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でも取得できるのですが、クライアント側で受信できません。
また、期間の比較を今回は文字列で行っているため、フォーマットが全く異なる文字列が取得されることになり、比較をすることができません。

コーディング(view.html)

<!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で返ってくる値だけしか利用できません。
もし、複数の異なる値を受け取りたい場合は、何らかの工夫(配列で取得したり、サーバー側でタグをつけて取得したり等々)が必要になります。

実行結果

実行するとロード完了時に、以下のような画面が表示されます。

PCでの表示結果

また、表示期間を変更すると、その指定した期間の表示に変更されます。

期間を変更すると
指定した期間の表示になる

もし、その都度サーバーとのデータのやり取りをしたくない場合は、サーバー側のデータを一括ですべて読み込み、クライアント側で表示するしないを制御してもいいかもしれません。

メニュー画面のコーディング(menu.html)

<!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”を付加し、別画面で起動するようにするだけです。

サーバー側のコーディング全体(.gs)

最後に、サーバー側のコーディングが、書き込みと読み込みでページを分けて書いてしまっているので、全体がどうなるかを記載しておきます。

//スプレッドシートの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;
}

これで、入力と表示の両方ができるので、何時、何処で、誰に会ったかをメモしていくことが出来ます。

皆様の参考になれば幸いです。
また、このようなことを行わなければいけない事態が早く収束することを願っております。

Follow me!

-GAS(GoogleAppsScript), Webアプリ, アプリケーション開発
-,

執筆者:


comment

メールアドレスが公開されることはありません。

関連記事

no image

【C#】【VBScript】アプリケーションの自動再起動

このページの内容 この機能を作成した理由ソースコード この機能を作成した理由 24H稼働している工場等のクラサバ系のシステムで、サーバー側ソフトが原因不明のハングアップをしてしまい、夜中に呼び出しを受 …

VisualStudio2019でSQLiteを利用する(NuGetパッケージのインストール)

このページでは、VisualStudio2019にてNuGetパッケージのインストールによってSQLiteを利用するための手順を紹介しています。DLLをダウンロードして、参照設定にて利用される方法はこ …

GASの利用 ~スプレッドシートの値が取得できない or 想定と異なる場合~

getValuesでスプレッドシートの値を取得しようとした際に、・値が取得できない・取得した値が想定していたものと違うという状況に遭遇した場合について、このページでは記載しています。 ※このページの …

no image

【VBScript】管理者権限でVBScriptを実行させる

このページの内容 どんな時にこの機能が必要になるかソースコード どんな時にこの機能が必要になるか このページのタイトルにある通りですが、管理者権限が必要になるフォルダ内のファイルの編集などをVBSri …

GASの利用 ~Webアプリの開発をやってみる~

このページでは、Google Apps Scriptを利用してサーバーレスでWebアプリを開発するための初期段階として、Webブラウザで”Hello GAS”と表示させるまでの …

このサイトの管理者について

1980年代生まれ
石川県在住

メーカー2社経験後に退社

1年程度自由に在職中はできなかったことにチャレンジ

その後コロナの影響でなかなか仕事が見つかりませんでしたが、無事就職

現在はシステム会社に勤務中

PAGE TOP