01_WEBアプリ基本

【01_WEBアプリ基本】”テーブル形式フォーム”で「どこでも帳簿」を作ろう〔2/2〕

記事概要

前回の記事ではWEBアプリの手始めとしてテーブル形式のフォームを使ってスプレッドシートを読み書きする「どこでも帳簿」の機能と、アプリの機能であるGooglスプレッドシートの読み書きのための、スクリプトテンプレートをについてご紹介しました。

この記事では、アプリの機能を実装するためのスクリプトテンプレートにコードを書いて、アプリを作成する方法を説明します。

(コードの内容は別の記事で説明予定です)

 

 

 

スプレッドシートの用意とIDのメモ

 まずは前の記事で作成したスプレッドシートをご用意ください。これがデータベースとなります。(新規のスプレッドシートを作る方法は前の記事をご参照ください)

シート名と打ち込む内容は以下の様にします。

【シート名】支出

【データ】以下の様にしてください。(「累計」のところは適当な関数で)

画像5
スプレッドシートの名前は何でもかまいません。Windowsでのファイル名と異なり、Googleドライブではファイル名ではなく固有のID番号によってファイルを特定しているので(ファイル名を利用したプログラムでない限り)プログラム作成面であまり大きな意味はありません。

ここで、スプレッドシートのIDを確認しておきます。

プラウザーの上の方、URLが表示されているところを見てください。

画像6

シートのIDはURLの中の以下太字の部分になります。

HTTPs://docs.google.com/spreadsheets/d/★この範囲がシートID★/edit・・・

 

 

スクリプトとテンプレートのコード

以上の準備をして頂いた上で、GoogleAppsScriptのコードを記述します。

まず適当なスプレッドシートの「ツール」メニューで新しいプロジェクトを作成してください。

Google Apps Script は、スプレッドシートのメニューから作成、またはGoogleドライブ上で単独で作成します。この場合は、Google上で「新規」→「その他」→「GoogleAppsScript」と選択すると作成できます

 

続いて、以下の要領で「スクリプト」と「テンプレート」のコードを記述ください。

まず「スクリプト」です。コード.gsとあるスクリプトファイルをクリックして以下の様に変えてください。

【ファイル名】:ウェブ表示.gs(今回はファイル名は何でもかまいません)

そして、以下のコードを打ち込みます。

//★★★★doGet関数はURLから呼び出された時に実行する関数|1つだけ定義できます★★★★
function doGet(e) {

 //アプリケーションを取得|スプレッドシートのIDは各自のものを記入
 var myApp = SpreadsheetApp.openById('★スプレッドシートのID★');

 //対象シートをシートの名前を指定して取得
 var mySheet = myApp.getSheetByName('支出');
 
 //データ記録範囲として、行数と列数を記載
 var nRow=11;
 var nCol=6;

 //データ記録範囲を指定して範囲を取得
 var myCells = mySheet.getRange(1,1,nRow,nCol);

 //HTMLファイルのテンプレートをファイル名を指定して取得
 var myHTML = HtmlService.createTemplateFromFile('INDEX');
 
 //★★テンプレートに埋め込む変数値を指定する★★  
 myHTML.myMSG ='ボタンをクリックしてください';   
 myHTML.myCells = myCells.getValues();
 myHTML.myRows = nRow;
 myHTML.myCols = nCol;
 
 //HTMLファイルをホスティング|メタタグを指定してスマホ表示に対応
 return myHTML.evaluate().addMetaTag("viewport", "width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=10.0");
}


//★★★★HTMLから呼び出されて実行する関数★★★★

//HTMLテーブルの値myCellsをシートに書き込む関数
function SetSheet(myCells, myRows, myCols){

 //アプリケーションを取得|スプレッドシートのIDは各自のものを記入
 var myApp = SpreadsheetApp.openById('★スプレッドシートのID★');

 //対象シートをシートの名前を指定して取得
 var mySheet = myApp.getSheetByName('支出');

 //データ記録範囲として、行数と列数を記載
 var nRow = myRows;
 var nCol = myCols;

 //スプレッドシートにmyCellsの値を書き込み 
  for (var iRow = 0 ; iRow < nRow; iRow++) {
     for (var iCol = 0 ; iCol < nCol; iCol++) {

       //見出し部分は除外して書き込み 
        if(!(iRow == 0 || iCol == 0 || iCol == 5)){
        mySheet.getRange(iRow + 1,iCol + 1,1,1).setValue(myCells[iRow][iCol]);
	     }
     }
   }
 

//返り値の変数を定義 
var myTotal = new Array(2) ;

 myTotal[0] = 0 ;
 myTotal = 0 ;
 
 //ループを回して6列目を取得(シートの列数は0から始まるので数字は5) 
 for (var iRow = 2; iRow <= nRow ;iRow++){

     //値が数字なら実行) 
    if(typeof mySheet.getRange(iRow,5,1,1).getValue() == 'number'){
       //個数カウント 
       myTotal[0]++;

     //合計計算 
       myTotal+= mySheet.getRange(iRow,5,1,1).getValue();
    }
 }
 //結果を返す 
 return myTotal;

}

次に「テンプレート」を編集します。プロジェクトで新規ファイル作成を示す「+」のアイコンから「HTML」を選んでファイルを以下の様に作成し・・・

・・・ファイル名とコードを以下の様にしてください。

【ファイル名】:INDEX.html(こちらは名前を変えないでください)

<!DOCTYPE html>
<html>
<head>
<!---著作:particlemethod------------>
<!---無断複製・転載・配布を禁じます---->
<base target="_top">

<!---スタイル【↓ここから】---->
<style>
   tr th { border:#aaa solid 1px; padding:5px; 
        background-color:#999; color:white; }
   tr td { border:#aaa solid 1px; padding:5px; }
<!---スタイル【↑ここまで】---->
</style>

</head>
<body>

<!---- Bodyタグの間にコード記入--【↓ここから】-->

<p>簡単データベース<a href= "https://gas-de-app.info/tableform1/" >説明はこちら</a></p>

<!---★★★★★★★★ 【テンプレートに渡された変数値からテーブルを表示】 ★★★★★★★★--->

<!---- テーブルタグとID名称宣言----->
<table id="TableBody">

<!---- JavaScriptのインライン記述-【↓ここから】---->
<? 

// GsValuesの各行 iRow に対して実行。myCellsはGASから渡される。
for(var iRow in myCells) {

  // 各行を Row に代入
  var Row = myCells[iRow]; 

  // 行頭タグ 「tr」|タグは ?>・・・<?で挟む
  ?><tr><?

  // カレント行の 各列 iCol に対して実行
  for(var iCol in Row) {

     // 該当行の 各列 iCol をCellに代入
     var Cell = Row[iCol];

     // 見出しや末尾の列の場合はthタグ記述
     if (iRow == 0 || iCol == 0 || iCol == 5) { 
              ?><th><?=Cell ?></th><?
              
     // 他の場合tdタグ記述
     } else {  
          if (iCol == 1 || iCol == 4) { 
               ?><td contenteditable="true" inputmode="numeric"><?=Cell ?></td><?            
          } else {
              ?><td contenteditable="true" inputmode="text"><?=Cell ?></td><?            
          }
       } 
   } 
  ?></tr><?
}
?>
<!---- JavaScriptのインライン記述-【↑ここまで】---->
</table>


<!---★★★★★★★★ 【テーブルの値を取得してGASに渡す】 ★★★★★★★★--->
<!---- JavaScriptの記述-【↓ここから】---->
<script>
//関数の宣言
function doWriteSheet(myRows, myCols){

  //テーブルの取得
  var myTable = document.getElementById('TableBody');
  
  //テーブルの行数、列数の宣言
  var nRow = myRows;
  var nCol = myCols;
 
  //テーブルの行数だけ要素のある配列を宣言
  var myCells = new Array(nRow);
  
  //テーブルの列数だけ子要素を宣言
  for (var iRow = 0; iRow < nRow; iRow++){
    myCells[iRow] = new Array(nCol);
  }
  

  //テーブルのrowsコレクションで行数を取得| 各行でループ
  for (var iRow = 0 ; iRow < myTable.rows.length; iRow++) {
  
	  //iRow行のcellsコレクションで列数を取得| 各列でループ
	  for (var iCol=0 ; iCol < myTable.rows[iRow].cells.length; iCol++) {
     
	 	//iRow行目のiCol列目のセルのテキスト値を取得
		myCells[iRow][iCol] = myTable.rows[iRow].cells[iCol].textContent;
	  }
   }
  //★★テーブルのセルの値をGASのSetSheet 関数に渡し、成功したらonSuccessを実行★★
  google.script.run.withSuccessHandler(onSuccess).SetSheet(myCells, nRow, nCol);
}

//GASの関数が成功したら実行する
function onSuccess(res){

     //メッセージのテキストを取得する
     var msg = document.getElementById("msg");
     
     //メッセージのテキストの中身を変更する
     msg.textContent = '書き込みました。現在、購入数:' + res[0] + '個、合計金額:' + res+ '円 です。';
}
</script>
<!---- JavaScriptの記述-【↑ここまで】----> 

<!---- コメント|変数値はdoGET関数からの渡し値---->
<p id="msg"><?=myMSG ?></p>

<!---- ボタンの表記---->
<button onclick="doWriteSheet(<?=myRows ?>, <?=myCols ?>)">書込み</button>


</body>
</html>

 プロジェクトの画面には、以下の様にファイルが見えていますか。

画像7

コードを保存したらデプロイしてブラウザから実行してみてください。

デプロイとは、プログラムにURLを紐づけしてブラウザから実行できる様にすることです。方法は次の記事で説明していきます

こんなフォームの形で表示されましたでしょうか。

上記のフォームに何かを入力し「書き込み」ボタンを押すと、コードに記載したスプレッドシートの該当シートに、内容がそっくり書き込まれます。そうです、WEBページでPCからでも、スマートフォンからでも入力できるようになりました!

うまく書き込めない場合は、プログラムのミスの他、セキュリティ上の問題の可能性があります。コードでスプレッドシートのIDを再確認の上、スプレッドシートを公開してみてください。
スプレッドシートに外部のWEBページからアクセスするには、一般的にはAPIという仕組みを組み込む必要があります。しかし、この方法であればそうした手続きは不要です!

続く記事では、コードの解説やデプロイの方法やをしていきます。

にほんブログ村 科学ブログ 技術・工学へ
にほんブログ村