GASで給料日に引き出す金額を表示させるアプリを作った話 #3

今回は登録画面をふんわり解説しようと思います。
2年前くらいに書いていたので若干記憶が薄れてます。。
参考記事:
Google Apps ScriptでWEBアプリをつくってみたHazime Style 様)
Google Apps ScriptでWebアプリケーションにスプレッドシートの値を出力するいつも隣にITのお仕事 様)

処理の流れ

  1. 入力用の画面(record.html)のinputタグに金額を入力

  2. 登録ボタンを押すとjs.htmlで登録ボタンを押したときの処理を実行

  3. コード.gsでごにょごにょ計算してスプレッドシートに転記

  4. 計算結果を別画面から確認できるようにする

1.入力用の画面(record.html)のコード

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <meta charset="utf-8">
    <meta name="description" content="入力画面">
    <link rel="stylesheet" href="https://unpkg.com/ress/dist/ress.min.css">
    <?!= HtmlService.createHtmlOutputFromFile('css').getContent(); ?>
  </head>
  <body>
    <div class="wrapper">
      <header class="page-header">
        <h1><a href="<?= getAppUrl() ?>?pg=index"><img class="logo" src="https://drive.google.com/uc?id=<画像のid>" alt="home_moneyホーム"></a></h1>
        <nav>
          <ul class="main-nav">
            <li><a href="<?= getAppUrl() ?>?pg=record">登録</a></li>
            <li><a href="<?= getAppUrl() ?>?pg=past">過去履歴</a></li>
            <li><a href="<?= getAppUrl() ?>?pg=master">マスター</a></li>
          </ul>
        </nav>
      </header>
      <div id="record" class="main-wrapper">
          <div class="title-content">
            <h2 class="page-title">Record</h2>
          </div>
      </div>
      <section class="record-edit">
          <form name='record' class="list">
            <p>
              <?
              //現在の年月をデフォルトで表示させる。
              const ym = yearmonth();
              const year = ym[0];
              const month = ym[1];
              output.append('<input type="text" pattern="[12]\d{3}" value="' + year + '" inputmode="numeric" id="year" required>年');
              output.append('<input type="text" pattern="([1-9]|1[0-2])" value="' + month + '" inputmode="numeric" id="month" required>月分');
              ?>              
            </p>
            <table>
              <tr><td class="td-header">収入</td>
              <td><input type="text" pattern="\d{1,}" inputmode="numeric" id="income">円<input type="checkbox" name="update" value="upIncome">更新</td></tr>
              <tr><td class="td-header">その他収入</td>
              <td><input type="text" pattern="\d{1,}" value="0" inputmode="numeric" id="other_income">円<input type="checkbox" name="update" value="upOtherIncome">更新</td></tr>
              <tr><td class="td-header">経費</td>
              <td><input type="text" pattern="\d{1,}" inputmode="numeric" id="cost">円<input type="checkbox" name="update" value="upCost">更新</td></tr>
              <tr><td class="td-header">クレジットカード</td><td><input type="checkbox" name="update" value="upCredit">更新</td></tr>
              <div class="credit-detail">
                <?
                //クレジット会社分の記入欄を追加
                //スプレッドシートを開く
                const spredsheetId = "スプレッドシートのID";
                var sheet = SpreadsheetApp.openById(spredsheetId).getSheetByName('credit');
                //最終行の値を取得
                var last_row = sheet.getLastRow();
                //値を取得
                var credit_ms = sheet.getRange(1,1,last_row,1).getValues();
                //取得した値を利用してinputを生成(1行目はヘッダーのためiは1から開始)
                var cnt = 0;
                for(var i=1; i<credit_ms.length; i++){
                  output.append('<tr><td class="td-header">' + credit_ms[i][0] + '</td>');
                  output.append('<td><input type="text" pattern="\d{1,}" inputmode="numeric" id="credit' + i + '">円</td></tr>');
                  cnt = i;
                }
                output.append('<input type="hidden"  value="' + cnt + '"id="cnt">');
                ?>
              </div>
              <tr><td class="td-header">その他支出(手元分)</td>
              <td><input type="text" pattern="\d{1,}" value="0" inputmode="numeric" id="other_ah">円<input type="checkbox" name="update" value="upOtherAh">更新</td></tr>
              <tr><td class="td-header">その他支出(みずほ分)</td>
              <td><input type="text" pattern="\d{1,}" value="0" inputmode="numeric" id="other_mizuho">円<input type="checkbox" name="update" value="upOterMizuho">更新</td></tr>
              <tr><td class="td-header">その他支出(UFJ分)</td>
              <td><input type="text" pattern="\d{1,}" value="10000" inputmode="numeric" id="other_ufj">円<input type="checkbox" name="update" value="upOtherUfj">更新</td></tr>
            </table>
            <div class="btn-grp">
              <div class="button">
                <input type="button" onclick="addNewRcdBtnClick()" value="登録">
              </div>
              <div class="button">
                <input type="button" onclick="addUpRcdBtnClick()" value="更新">
              </div>
            </div>
          </form>
      </section>
    </div>
    <?!= HtmlService.createHtmlOutputFromFile('js').getContent(); ?>
  </body>
</html>
登録画面
こうしてみるとクレカの種類が多い、、

2.登録ボタンをおしたときに実行するJavaScript
登録するかを聞いてOKを押したらフォームの内容を取得してコード.gsにあるaddData関数に値を渡しています。

//record.html--------------------------------
  //登録ボタンをクリックしたときの動作
  function addNewRcdBtnClick() {
    const checkAddFlg = window.confirm('登録しますか?');
    if(checkAddFlg) {//OKをクリックしたとき
    //フォームの内容を取得
    const year = document.getElementById('year').value;
    const month = document.getElementById('month').value;
    const income = document.getElementById('income').value;
    const other_income = document.getElementById('other_income').value;
    const cost = document.getElementById('cost').value;
    const cnt = document.getElementById('cnt').value;
    //creditの配列を取得する。
    let credit = [];
    for(let i=1; i<=cnt; i++){
      credit.push(document.getElementById('credit' + i).value);
    }
    const other_ah = document.getElementById('other_ah').value;
    const other_mizuho = document.getElementById('other_mizuho').value;
    const other_ufj = document.getElementById('other_ufj').value;
    google.script.run.withSuccessHandler(function(smg){
      //成功したときの処理
      alert(smg);
    }).withFailureHandler(function(){
      //失敗したときの処理
      failMsg('登録')
    }).addData(year,month,income,other_income,cost,credit,other_ah,other_mizuho,other_ufj);
    }else {
      alert('登録をキャンセルしました。');
    }

  }

3.コード.gsでごにょごにょ計算
ここは計算だけなので省略しちゃいます!
工夫した点としてはそのままスプレッドシートにデータを登録していくと最新が下になってしまうのでソート。(関数:sheetSort(sheetName))
column:1が年、column:2が月で両方降順にしています。
SpreadsheetApp.openById(スプシのID).getSheetByName(シート名).sort([{column:1,ascending:false},{column:2,ascending:false}])

クレジットカードの入力値を保管するシート
計算結果を保管するシート

4.計算結果画面のコード
過去2ヶ月分を見れるようにしていたのですが年をまたぐときの考慮不足を見つけてしまいました、、、
今見ると年月のところはもうちょっと何とかできそうなのでいじりたい(希望)

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <meta charset="utf-8">
    <meta name="description" content="収支確認ホーム">
    <link rel="stylesheet" href="https://unpkg.com/ress/dist/ress.min.css">
    <?!= HtmlService.createHtmlOutputFromFile('css').getContent(); ?>
  </head>
  <body>
    <div class="wrapper">
      <header class="page-header">
        <h1><a href="<?= getAppUrl() ?>?pg=index"><img class="logo" src="https://drive.google.com/uc?id=<画像id>" alt="home_moneyホーム"></a></h1>
        <nav>
          <ul class="main-nav">
            <li><a href="<?= getAppUrl() ?>?pg=record">登録</a></li>
            <li><a href="<?= getAppUrl() ?>?pg=past">過去履歴</a></li>
            <li><a href="<?= getAppUrl() ?>?pg=master">マスター</a></li>
          </ul>
        </nav>
      </header>
      <div id="twomonthago" class="main-wrapper">
          <div class="title-content">
            <h2 class="page-title">
            <?
              //計算結果を表示する月を表示 ※年をまたぐことを考慮に入れてないぞ、、、
              const ym = yearmonth();
              const year = ym[0];
              const month = ym[1] - 2;
              output.append(year + '年' + month + '月');
            ?>
          </h2>
          </div>
      </div>
      <section class="list">
        <div class="right-list">
          <h3><a href="<?= getAppUrl() ?>?pg=lastMonth">
            <?
              //翌月を表示させる
              let nm = month + 1
              output.append(nm + '月' + '>>');
            ?>
          </a></h3>
        </div>
        <div class="list-detail">
          <?
            //計算結果の内容を表示
            let result = resultView(year,month);
            let data = result[0];
            for(let i=1; i<result.length; i++){
             data += result[i];
            }
            output.append(data);
          ?>
        </div>
      </section>
      
    </div>
    <?!= HtmlService.createHtmlOutputFromFile('js').getContent(); ?>
  </body>
</html>
計算結果を確認する画面

次回はBI編!

いいなと思ったら応援しよう!