前の記事まででスプレッドシートの値をテーブルに表す方法を説明しました。しかしテンプレート上に表示させたセルの値は編集可能であるものの、ブラウザを閉じると消えてしまいます。
編集結果を残すには、WEBのページ上の値をサーバに送って、スプレッドシートに保存する必要があります。しかし、クライアントPC(ユーザーのPC)からサーバへのデータ送信はなかなか厄介で、WEBアプリを開発するハードルの一つになっています。
ところが、GAS(Google Apps Script)ならたった1行のコードでできてしまいます。
目次
WEB画面上のテーブルの編集結果は、ブラウザを閉じると消えてしまう
テンプレート上に表示させたテーブルのセルは、<td contenteditable=”true”>というタグにすることで編集可能になっていますので参照だけでなく、編集も可能です。
例えば、下の様なテーブルを編集して・・・
テーブルは、各ユーザーのブラウザ上でのみ存在しているので、ブラウザを閉じると編集データは消えてしまいます。
編集結果を残すには、元のスプレッドシートへのデータの保存が必要です。その為には、現時点でのクライアントPCで表示されているテーブル上のデータを収集して、サーバー側に引き渡す必要があります。
Google.script.run 関数・・・POST処理など実装不要、GASならたった1行のコードでサーバにデータ送信できる
クライアントPC上にあるデータをサーバに引き渡す時によく使用されるのがPOST処理と呼ばれる方法です。GASではこれに代わる方法としてGoogle.script.runという関数(メソッド)が用意されています。
大変簡単で便利です。
まずテーブル上の最新データを取得して配列に保存する
プログラムの実装では、テーブル上のデータをスプレッドシートに送る前準備として、テーブル上の最新データを取得して配列に保存します。
この処理はテンプレート内に書いた<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);
}
</script>
・
プログラムのキーになるところは以下です。
var テーブル配列 = document.getElementById(‘テーブルのID‘);
セルの値を保存する配列の用意(forループで行x列だけ指定)
var セル配列 = new Array(必要行数);
varセル配列[各行]= new Array(必要列数);
セルの値を配列に保存(forループで行x列だけ指定)
配列[行][列] = テーブル配列.rows[iRow].cells[iCol].textContent;
google .script .run. スクリプト内関数(引数)の使い方 ~クライアントPCからサーバへのデータの引き渡しと、サーバからの返り値の取得
google.script.run.withSuccessHandler(onSuccess).SetSheet(myCells, nRow, nCol);
・
テンプレート側で発動させた関数によって、スプレッドシートにアクセスする
ここからの説明は、スクリプトファイルになります。(プロジェクトでスクリプトの方を選択してください)
次に、テンプレート側からのgoogle.script.run関数で発動するスクリプト側のSetSheet関数ですが、以下の様になります。
//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 ;
<・・・中略myTotalにデータを代入・・・>
//結果を返す
return myTotal;
}
・
こちらのプログラムで、キーとなる部分は以下となります。
シートオブジェクト.getRange(行番号,列番号,1).setValue(配列データ[行番号][列番号]);
テンプレート側に値を返す
return 変数 又は 配列
<button onclick=”doWriteSheet(<?=myRows ?>, <?=myCols ?>)”>書込み</button>
・・
画面上では以下の様に見えます。
・ああああああああ
サーバで発動させた関数の返り値のテンプレートでの処理
最後に帰ってきた返り値の処理は、以下となります。
//GASの関数が成功したら実行する
function onSuccess(res){
・
//メッセージのテキストを取得する
var msg = document.getElementById(“msg”);//メッセージのテキストの中身を変更する
msg.textContent = ‘書き込みました。現在、購入数:’ + res[0] + ‘個、合計金額:’ + res+ ‘円 です。’;
}
</script>
・
こちらのキーポイントは以下です。
function 成功時関数(res){ 処理 }
res:返り値
テキストのオブジェクト.textContent = ‘書き込むテキスト’
以下の様なテキストが・・・
こんな風になっています。
スプレッドシートが更新された事を確認してみよう
それでは、GASのリンクを開いて実行させ、テーブルを以下の様に編集してみましょう。表の下のボタンを押すと・・・
元はこんなスプレッドシートが・・・
処理後はこんな風に更新されています!
見事!結果が反映されました!
結び
お疲れ様でした。ここで解説記事を終わります。
スプレッドシートのデータを、テーブル形式のフォームを使ってWEBサイトとして表示させ、編集結果を再びスプレッドシートにもどす方法について、まとまった情報があまり見当たらなかったので、書いてみました。
実際に何かに使う場合は、スプレッドシートやGASを公開した上で、セキュリティー対策や、不注意による上書きエラー対策などが必要になります。
GASの素晴らしいところは、特別にサーバやAPIを用意せずに、サーバとユーザーPCとの間でインタラクティブなWEBページが作れるところです。また、処理の一部をスプレッドシートの関数に行わせることでプログラム側の負担を軽減できる点も素晴らしい点です。
こうしたインタラクティブなWEBページはWEBアプリといわれ、特別なインストール作業なしにリンクを開くだけで使えるソフトウェアとして、現在様々なところで活躍しています。
コード全体はこちらの記事の末尾に記載しておりますので、宜しければスプレッドシートをご用意した上で、コピーして試してみてください。(ただし著作権は放棄していません。この記事の紹介のためのリンクは自由ですが、コードそのものの転載や配布はしないでください。)