前回の記事に引き続き、振替伝票作成ファイルの解説です。
↓前回の記事
前回、GASが動いているところはお見せできたんですが、解説はシートの部分までで終わってしまっていました。
今回は残ったGAS部分の解説です。
真剣に読めば、GASを使って色々作りたくなる、かもねw
GASの動作説明
では、GASの動作を説明していきます。
①コード全記載
コードは以下の通りです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
//振替伝票作成 function transferSlipCreation(){ const spreadSheet = SpreadsheetApp.getActiveSpreadsheet(); //当該ファイルを定数spreadSheetに格納 const templateSheet = spreadSheet.getSheetByName("雛形"); //雛形シートを定数templateSheetに格納 const inputSheet = spreadSheet.getSheetByName("入力シート"); //入力シートを定数inputSheetに格納 let data = inputSheet.getRange(7, 1, 1000, 24); //変数dataを宣言し、入力シートの入力範囲を格納 data.sort({column: 2, ascending: true}); //変数dataの範囲を日付順に並び替え let range = inputSheet.getRange(7, 2).getNextDataCell(SpreadsheetApp.Direction.DOWN); //変数rangeに入力シートB列の最終行を格納 let lastRow = range.getRow(); //変数lastRowにrangeの行番号を格納 let d; //変数dを宣言(日付の変更点を判断するための変数) let sheetCopy; //変数sheetCopyを宣言(雛形シートを複製する際に使用する変数) let today; //変数todayを宣言(仕訳の日付を格納するための変数:文字列として取得) let today2; //変数today2を宣言(todayを「年」「月」「日」に分割した配列を格納するための変数) let today3; //変数today3を宣言(仕訳の日付を格納するための変数:日付として取得) let year; //変数yearを宣言(プログラム中で不使用) let month; //変数monthを宣言(振替伝票シートの名前を変更する際に使用) let day; //変数dayを宣言(振替伝票シートの名前を変更する際に使用) let newSheetName; //変数newSheetNameを宣言(振替伝票シートの名前を変更する際に使用) let journalizing; //変数journalizingを宣言(仕訳1行をコピーするために使用) let transferSlip; //変数transferSlipを宣言(現在作成中の振替伝票シートを格納するための変数) let transferSlipLastRow; //変数transferSlipLastRowを宣言(現在作成中の振替伝票シートの最終行を格納するための変数) let targetCell; //変数targetCellを宣言(現在作成中の振替伝票シートの仕訳貼り付け先を格納するための変数) let targetCell2; //変数targetCell2を宣言(現在作成中の振替伝票シートの日付貼り付け先を格納するための変数) for(let lineNumber = 7; lineNumber <= lastRow; lineNumber++) { //変数lineNumberを宣言し、7を代入、lastRowに一致するまで繰り返し処理 d = inputSheet.getRange(lineNumber,8).getValue(); //変数dに入力シートの「H,lineNumber」セルの数値を代入する if (d != 0){ //変数dが0でなければこちらの処理を実行 //雛形シートコピー sheetCopy = templateSheet.copyTo(spreadSheet); //雛形シートを現在のファイルの最終シートに複製し、変数sheetCopyに格納 //シート名変更 today = inputSheet.getRange(lineNumber, 2).getDisplayValue(); //入力シートの現在の仕訳行の日付欄の文字列を取得し、変数todayに格納 today2 = today.split('/'); //変数todayの中身を/で分割し、変数today2に配列の形で格納 year = today2[0]; //today2の1つ目を変数yearに格納 month = today2[1]; //today2の2つ目を変数monthに格納 day = today2[2]; //today2の3つ目を変数dayに格納 newSheetName = `${month}月${day}日`; //変数newSheetNameに「(変数month)月(変数day)日」の文字列を格納 sheetCopy.setName(newSheetName); //変数sheetCopy(に格納しているコピー済み雛形シート)のシート名を、変数newSheetNameの中身に変更 //仕訳と日付をコピペ journalizing = inputSheet.getRange(lineNumber, 3, 1, 5); //変数journalizingに、入力シートの現在のlineNumberの行の仕訳データを格納 transferSlip = spreadSheet.getSheetByName(newSheetName); //変数transferSlipに、作成中の振替伝票シートを格納(変数sheetCopyを使っても動いたかも) transferSlipLastRow = transferSlip.getRange(4, 5).getNextDataCell(SpreadsheetApp.Direction.DOWN).getRow(); //作成中の伝票シートのE列最終行の行番号を取得し、変数transferSlipLastRowに格納 targetCell = transferSlip.getRange(transferSlipLastRow+1, 3); //振替伝票シートの最終行の次の行のC列セルを、貼り付け先セルとして取得し、変数targetCellに格納 journalizing.copyTo(targetCell); //変数targetCellに、変数journalizingの内容を貼り付け today3 = inputSheet.getRange(lineNumber, 2); //入力シートの現在の行の日付を取得し、変数today3に格納 targetCell2 = transferSlip.getRange(2,4); //作成中の伝票シートの日付セルを取得し、変数targetCell2に格納 today3.copyTo(targetCell2, {contentsOnly:true}); //変数targetCell2に、today3の内容を貼り付け }else{ //仕訳をコピペ journalizing = inputSheet.getRange(lineNumber, 3, 1, 5); //変数journalizingに、入力シートの現在のlineNumberの行の仕訳データを格納 transferSlip = spreadSheet.getSheetByName(newSheetName); //変数transferSlipに、作成中の振替伝票シートを格納 transferSlipLastRow = transferSlip.getRange(4, 5).getNextDataCell(SpreadsheetApp.Direction.DOWN).getRow(); //作成中の伝票シートのE列最終行の行番号を取得し、変数transferSlipLastRowに格納 targetCell = transferSlip.getRange(transferSlipLastRow+1, 3); //振替伝票シートの最終行の次の行のC列セルを、貼り付け先セルとして取得し、変数targetCellに格納 journalizing.copyTo(targetCell); //変数targetCellに、変数journalizingの内容を貼り付け } } } |
②変数・定数宣言部分
3〜6行目と、9〜24行目は、変数及び定数の宣言をしています。一部、宣言と同時に値を代入しているものもあります。
例1 定数「spreadSheet」…スプレッドシート本体を代入しています。
例2 定数「templateSheet」…雛形シートを代入しています。
その他、各行のオレンジ色の部分(「//」より後)がその行の解説文なので、興味があれば見てみてください。
③仕訳データ並び替え部分
6,7行目で、入力シートの仕訳データを日付順に並び替えています。
6行目で、入力シートの仕訳データがある範囲を読み取って、7行目で日付順に並び替えています。
④繰り返し処理部分
26行目以降で、変数「lineNumber」を使用して繰り返し処理をさせています。59行目までが繰り返し処理の内容になります。
「lineNumber」を入力シートの行番号として、1行ずつデータを読みに行きます。
そして1回処理を回すごとに、「lineNumber」を1ずつ増やし、これを最終行まで繰り返す、という記述になっています。
④−1 日付が変わるかどうかの判定
27行目では、日付が変わるかどうかの判定のため、「入力シートの現在の行のH列の値」を変数dに代入しています。
④−2 日付が変わっている場合の処理
変数dの値が0ではない場合、日付が変わっていると判定し、その場合の処理をしていきます。28行目がその条件式です。
日付が変わる場合の処理1 雛形シート複製
1つ目の処理として、定数templateSheetを利用して、雛形シートを複製します。
この処理は30行目で記述しています。
定数「templateSheet」には、4行目の宣言時点であらかじめ「雛形」シートが代入されています。
copyToメソッドで、変数「templateSheet」を複製(ファイルの一番右に複製)し、それをそのまま変数「sheetCopy」に代入する形ですね。
日付が変わる場合の処理2 複製したシートの名前変更
処理2つ目として、複製したシートの名前を「◯月△日」の形に変更します。
入力シートのB列から日付を読み取って、それを「年、月、日」に分割してそれぞれ変数「year」「month」「day」に代入、そのうち「month」「day」を使ってシート名を作っています。
なので変数「year」は設定してるのに使ってないですw
37行目で、「month」「day」を使ったシート名を作り、「newSheetName」に代入しています。
変数「sheetCopy」にsetNameメソッドを使用し、変数「newSheetName」を引数に設定することで、シート名を変更できます。
日付が変わる場合の処理3 日付と仕訳コピペ
処理3つ目では、◯月△日シートの日付を変更し、仕訳データをコピペしています。
写真では43行目の右側が見切れていますが、上の「コード全記載」の部分でなら左右スクロールができますので、見たい方はそちらで確認してください。
41〜45行で仕訳データのコピペ、46〜48行で日付コピペをしています。
④−3 日付が変わっていない場合の処理
変数dの値が0なら、日付が変わっていないと判定し、仕訳データのコピペのみを実施します。
ここまでの処理を、入力シートの最終行まで繰り返しています。
すべての行について、「//」以降に説明を記載していますので、動作の詳細に興味がある方は読んでみてください。
補助的な機能
追加して、「作った振替伝票シートを削除する機能」「入力シートをクリアする機能」も作成しています。
振替伝票削除機能 全コード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
//削除除外シートor末尾のシート1つを残して、すべてのシートを削除する関数 function deleteALLSheets() { //あらかじめ削除したくないシート名を記載してください。例「["シート1","シート5","シート10"]」 const notDelSheet = ["入力シート","火災保険料把握","車両・備品等償却","雛形"]; // 現在アクティブなスプレッドシートを取得 let mySheet = SpreadsheetApp.getActiveSpreadsheet(); //取得したスプレッドシートにある全てのシートを配列として取得 let sheetData = mySheet.getSheets(); //末尾のシートを削除するかを決めるフラグ let flag =0; //forループでシートを削除する削除を行う for(i=0;i<sheetData.length;i++){ //削除したくないシート存在しない場合、末尾のシートは削除せずスキップする if(flag ==0 && i == sheetData.length-1){ break; } //削除対象から除外するシートにヒットした場合は、削除処理は行わず、フラグを立てる if(notDelSheet.indexOf(sheetData[i].getSheetName()) != -1){ flag = 1; } //削除除外シートではない場合は、削除処理を実行する else{ mySheet.deleteSheet(sheetData[i]); } } } |
これは、作り方がよくわからなかったので、こちらのサイトから拾ってきてそのまま使用しています(4行目だけ修正しましたが)。
入力シートクリア機能 全コード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
//入力データクリア及び順番初期化 function inputSheetClear(){ const spreadSheet = SpreadsheetApp.getActiveSpreadsheet(); const inputSheet = spreadSheet.getSheetByName("入力シート"); let range = inputSheet.getRange(7, 2).getNextDataCell(SpreadsheetApp.Direction.DOWN); let lastRow = range.getRow(); inputSheet.getRange(7,2,lastRow-6,6).clearContent(); inputSheet.getRange(7,11,lastRow-6,1).clearContent(); inputSheet.getRange(7,16,lastRow-6,1).clearContent(); inputSheet.getRange(7,21,lastRow-6,1).clearContent(); //シート内でソートしたいセル範囲をgetrangeで指定する(行番号, 列番号, 行数, 列数) let data = inputSheet.getRange(7, 1, lastRow-7, 24); //列Bを基準に昇順でソートする data.sort({column: 1, ascending: true}); } |
こちらは一応自力で作りましたw
機能をボタンに配置
作成した機能は、それぞれ入力シート上のボタンに配置しています。
これらのボタンを押すことで、プログラムを動作させられます。
プログラムをボタンに配置するやり方は、この辺のサイトが参考になると思います。
スプレッドシート上の図形描画したボタンでGoogle Apps Script(GAS)を実行する方法
(出典:AutoWorker)
作成したことで得られた効果
この作業を終えたことで、以下の効果がありました。
・ちょっとだけGASを使えるようになって、忌避感が減った
・色々自動化してみたい気持ちが出てきてちょっとワクワクしてきたw
・Microsoft365を解約して、年16,500円節約できた(超重要w)
今後の課題
1.会計ソフト「マネーフォワード」への入力を自動化したい
今の状態だと、振替伝票の作成までは自動化できたんですが、それを会計ソフトであるマネーフォワードへ入力するのは手入力のままです。
これを最終的には自動化したいと思っています。
人の代わりにブラウザを操作して入力するってのはなかなか難しそうなんですが、仕訳を記録したCSVファイルを読み込む機能はマネーフォワード側にあるようです。
「仕訳帳」のインポート方法 (出典:マネーフォワード)
マネーフォワード側でサンプルフォーマットを用意してくれているので、入力した仕訳データをこのフォーマットの形に整理できれば、クリック一発で帳簿入力を完了できるようにできるかなー、と思っているところです。
2.振替伝票に連番を入力したい
こちらは必要があればって感じですが、せっかく振替伝票シートに番号入力欄を作っているので、連番を取るようにしたいなー、と。
でもめんどくさがりなので結局やらないかもですw
まとめ
というわけで、前回・今回と、スプレッドシートで作成した振替伝票作成ファイルについて解説してきました。
同じくスプレッドシートで何かファイルを作ろうとしている方の参考になれば幸いです。
実際使ってみたい方は、こちらからダウンロードしてみてください。
ちなみに、僕はこちらの書籍「詳解! Google Apps Script完全入門」を、勉強しようと思って買いました。
しかし、同時にプロゲートのJavaScriptコース初めてしまいまして、ほとんどそっちのみで勉強した感じです(プロゲート9:書籍1くらいの割合)
Progate | プログラミングの入門なら基礎から学べるProgate
まあ、今後何か新しいものを作るときには、書籍の方も使えるかなー、と自分を慰めておりますw
編集後記
半年ほど前から、朝起きると左足だけ足の裏が痛い、という症状が出ておりました。
朝イチだけ痛くて、ちょっと動いていると痛くなくなってくる、という感じです。
で、話は飛びますが、随分前にリベ大で紹介されていたこの本を購入していたんです。
買ってからしばらく本棚に放置していたのを発見しまして、
そーいえば、これ読んでなかったなー
と思って読み始めたんですよ。
この本、元プロレスラーの松永光弘さんという方が、プロレスラーの傍らステーキハウス経営に乗り出して、数々の失敗と試練を乗り越えながら人気店に成長させていく実体験を綴った本で、読めばめっちゃ元気になります。
でも飲食店経営だけはやめとこうとも思えますw
リベ大で松永さんの本を紹介している動画はこちらです。
で、この本に出てくる苦労話のなかに、
「足底筋膜炎がひどくて立つことも歩くこともできなくなって、でも店は閉められないから、膝立ちでステーキを焼いていた」
って話が出てくるんです。
そこで「足底筋膜炎とはなんぞや?」と気になりまして、調べてみたわけですよ。
そしたら、こんな記述が見つかりました。
「 朝起きてから、あるいはしばらく休んでからの第一歩目など、安静後の始動時に痛みが出やすいという点が特徴として挙げられます。」
やべっ…
これ今の俺の症状じゃねーかw
というわけで、膝立ちはイヤなので、今絶賛整骨院で治療中です。
治療を進める中で判明したのが、どうやら一昨年ふくらはぎの肉離れをやっちゃった後遺症らしいということです。
肉離れで一回断裂しちゃった部分が固くなって動きが悪くなっちゃってて、それで足底筋膜に無理がかかって炎症が起きているんじゃないか、ということです。
なのでその部分を一生懸命ほぐすと、足の裏の痛みが軽減される、という感じになっています。
いきなり整骨院行っちゃったもんで、現在自費で治療中なのですが、先に整形外科に行ってたら整骨院も含めて保険効いたかも…とちょっと後悔しているところですw
ではまた