どうも、猫さんです。
今回は9月末にグダグダと決まった会計システム作成の振り返りを題材にしつつAdvent Calendarの12日目を書いていこうと思います。
adventar.org
あらすじ(スキップ可)
9月末のとあるサークルでのMTG
約一か月後に控えた学園祭での出し物について話していた......
そこで使用する会計システム、もしそれを生徒で作るとするならば誰が作るか
先輩は乗り気ではない、それだけは空気で、反応でめんどくさいとわかる。てかめんどいから嫌だとも言われた。
私は迂闊だった。後に装飾にも名乗りを上げてしまい仕事を増やしてしまうなんて思っていなかったからだ。
やろうとしたこと
Googleのスプレッドシートをデータベースとして扱い
GoodleAppsScriptでスプレッドシートへの読み書きやJSON変換で送信
HTMLで取得したデータの表示や入力データの送信
を行わせています。改行の表示とかが残っていますが急いで作ったので許してください。
何故複数人になったか
最初は1人での開発に挑戦していましたがHTMLでの入出力処理や、GASとのデータのやり取りの実装が知識不足によりなかなか出来ず泣く泣く五段先輩に依頼したわけです。
簡単に説明すると...
フロントエンド(HTML)側:五段先輩
バックエンド(GAS及びスプレッドシート)側:猫さん
ということで本番まで残り20日ほどで再スタートとなりました。
今回の記事で書くのはバックエンド側です。
仕様
は商品リスト用と販売履歴用の2つのシートを同じスプレッドシート上に作成しています。
GAS
GASとスプレッドシート間はGoogle Sheets APIで、
GASとフロントエンド側へはJSONに変換してからdoGetとdoPostを利用しています。
doGetでは、modeというパラメータを追加することで2つのモードを実装。
allで商品リスト、fiveで販売履歴5件を最新の5件前から最新までのをJSON形式でそれぞれ返します。
更にWebアプリケーションとして導入することで面倒な「Developer ConsoleでのExecution API設定」等を省いています。
var url = 'スプレッドシートのURL';
var sheetName = '商品リストシート';
var book = SpreadsheetApp.openByUrl(url);
var sheet = book.getSheetByName(sheetName);
function doGet(e){
switch(e.parameter.mode){
case 'all':
var json = convSheet(sheet);
Logger.log(JSON.stringify(json));
return ContentService.createTextOutput(JSON.stringify(json)).setMimeType(ContentService.MimeType.JSON);
break;
case 'five':
var sheetH = book.getSheetByName("販売履歴シート");
var json = GetList(sheetH);
Logger.log(JSON.stringify(json));
return ContentService.createTextOutput(JSON.stringify(json)).setMimeType(ContentService.MimeType.JSON);
break;
default:
return ContentService.createTextOutput("EROOR!");
break;
}
}
function GetList(sheetH){
var LastRow=sheetH.getLastRow();
var FirstRow=LastRow-4;
var column = 1;
var numcolumns =11;
var range = sheetH.getRange(FirstRow, column, 5, numcolumns);
var data =range.getValues();
return data;
}
function convSheet(sheet) {
var colStartIndex = 1;
var rowNum = 1;
var firstRange = sheet.getRange(1, 1, 1, sheet.getLastColumn());
var firstRowValues = firstRange.getValues();
var titleColumns = firstRowValues[0];
var lastRow = sheet.getLastRow();
var rowValues = [];
for(var rowIndex=2; rowIndex<=lastRow; rowIndex++) {
var colStartIndex = 1;
var rowNum = 1;
var range = sheet.getRange(rowIndex, colStartIndex, rowNum, sheet.getLastColumn());
var values = range.getValues();
rowValues.push(values[0]);
}
var jsonArray = [];
for(var i=0; i<rowValues.length; i++) {
var line = rowValues[i];
var json = new Object();
for(var j=0; j<titleColumns.length; j++) {
json[titleColumns[j]] = line[j];
}
jsonArray.push(json);
}
return jsonArray;
}
function doPost(e){
var data = JSON.parse(e.postData.contents);
var Time = new Date;
var Total = data.total;
var Deposit = data.deposit;
var Set = data.set;
var Pudding = data.pudding;
var Jelly = data.jelly;
var Cake = data.cake;
var Coffee = data.coffee;
var Milktea = data.milktea;
var Straighttea = data.straighttea;
var Drpepper = data.drpepper;
var ss = SpreadsheetApp.openByUrl(url);
var sheetH = ss.getSheetByName("販売履歴シート");
sheetH.appendRow([Time, Total, Deposit, Set, Pudding, Jelly, Cake, Coffee, Milktea, Straighttea,Drpepper]);
return ContentService.createTextOutput("POSTFIN!");
}
これは、後に見つかったバグを修正したものです。
当時のやらかし
変数名を変更後に更新できていないとによるエラーを初日にやらかしました。
また、処理はきちんとされているがレスポンスがEroor!を出す問題も2日目に出てきていて当時も直すことができていませんでした。
......が、このブログを書くためにソースコードを見直していると出てきた違和感により発覚したバグ。
>>>break文が抜けている<<<
うわあああああああああああ▂▅▇█▓▒░(’ω’)░▒▓█▇▅▂ああああああああああああああ
先輩方申し訳ありません。これ本当に完成してるのかなとか言われていたのは知っていますが、データの取得はできています。
所詮プログラムもかじった程度の奴が先輩方すら忙しいとか面倒とかで触れなかった大掛かりな物に挑戦しようとして申し訳ありませんでした。
参考にしたもの
【GAS】スプレッドシートのデータをJSON出力する関数をExecution APIで外部のNode.jsから実行する - Qiita
Google Apps Scriptの開発手法まとめ - Qiita
得たもの
今回の開発で得たものについて得たものが沢山ありました。
- doGetやdoPostについて
- レスポンスの重要さ
- 看板方式を体感する事
- 知識がある人を頼る事
- 早めの行動
- 仕事を増やしすぎない
- 弊学の学園祭に過度な期待はしないこと
- GitHubの便利さ
普段からMTGにいる人が仕事できるとは限らない事
今思いつくのはこれだけですがこの件で成長と自分の愚かさの理解ができました。
また、現在基本情報技術者試験の勉強をしていますが経験から用語の意味を理解しやすくなったことを実感しています。
挑戦はいいことだと思いますがリスクマネジメントも大事です。この経験を今後に活かしつつ程よく精神疲労を防いで2年に上がりたいと思います。
さて、次は17日のお楽しみです。
ゆるっと今年の活動を振り返りたいと思います。それでは!(o´・ω・`o)ノシ