GASでspread sheetからデータを取得して月末にメール送信するマクロ in 1 hour



##概要
同居人と生活費を割り勘しているので、共有の家計簿をGoogle spreadsheetで作ってるのですが、月末に自動でサマリーを自分と同居人へメール送信できるようにしたくなりました。

手入力ではなくてgoogle formに入力すると自動でspreadsheetに入る仕組みにしています。
（それに関しては以下の記事のようなことをしています。わかりやすいのでリンク貼らせてもらう）
[GoogleフォームとGoogleスプレッドシートを使って家計簿をつける話](https://kamitsuru.hatenablog.jp/entry/2019/11/29/143201)


そういうわけで、実際の家計簿spreadsheetを開くことはあんまりありません。
ただ、そうすると月末の家計簿見直しとか忘れそうだなーと思ったのと、リマインダーついでにトータルコスト教えてくれたら「うっ！」ってなって家計簿見直す気持ちになるかなーと思ってめっちゃ簡単なマクロを作りました。



###面倒だったところ
- GASのタイマーが月末指定がなかったので、毎日起動にして月末チェックを入れたこと
- スプレッドシートの操作を思い出すこと・・・（元ExcelVBAerなので慣れている方だけど）

###良かったところ
- 環境構築いらない。tools->script editor開くだけ
- スクリプト実行のキックが色々だし設定楽ちん
- ほぼJavaScript

##作成手順
1.Google spreadsheetをからscript editorを開く
<img width="245" alt="Screen Shot 2020-06-27 at 15.52.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/66957/7885957b-fab7-d83c-0019-b3e36241a444.png">

2.Scriptを作成する
以下の実際のScriptからぺたり。JSなのでとっつきやすくて安心。
フロッピーディスクっぽいボタンからSaveします（フロッピーはもう絶滅したのかな）
色々ハードコーディングなのでメールアドレスとかspreadsheetのファイル名とかソースコードのコメント参考によしなに変更してください。
<img width="841" alt="Screen Shot 2020-06-27 at 15.51.13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/66957/152d99a6-cacd-7990-7728-307a814b43a3.png">

3.Triggerを設定する
タイマーのようなボタンからこの画面に飛べるので、[Add trigger]をクリックします。
<img width="1195" alt="Screen Shot 2020-06-27 at 15.50.19.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/66957/94420a8c-0416-df99-dbcd-c5f0c21d4315.png">

毎晩実行したいので（ホントは月末の夜起動したかったけど、月末という設定ができなかった。毎月だと月末が２８日・３０日・３１日のパターンに対応できない）以下のような感じで設定
<img width="753" alt="Screen Shot 2020-06-27 at 15.49.38.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/66957/294d85f1-46c1-29f9-22ad-b265da6ed9f7.png">

4.以上
Scriptを手動実行で挙動を確認したいところですが、月末判定によって月末以外は動かしても何も起こりません。




##実際のScript
```javascript

function sendEmails() {
  
  //Check if today is the last day of this month.
  const today = new Date();
  const lastDayOfMonth = new Date(today.getFullYear(), today.getMonth() + 1, 0);
  if(today.getDate() !== lastDayOfMonth.getDate()) return; 
  
  console.log(lastDayOfMonth.getDate()+"is the last day of this month!");
  
  //ここを自分のメールアドレスにします
  const emailAddressMiki = 'sample_email@sample.com' 
  //家計簿スプレッドシートは2020/6のようなシート名を持っているので、今月のシート名を生成しておきます
  const currentYearMonthSheet = Utilities.formatDate(today,'JST', 'yyyy/M'); 
  
  
  //Look for a google spread sheet file I want to use
  //ここではGoogleスプレッドシートのスター付きファイル(条件：starred = true)に
  //限定して探しています
  //自分の環境に合わせて条件変えてみてください
  const files = DriveApp.searchFiles(
    'starred = true and mimeType = "' + MimeType.GOOGLE_SHEETS + '"'); 
  //each file
  while (files.hasNext()) {
    const spreadsheet = SpreadsheetApp.open(files.next());
    const sheets = spreadsheet.getSheets();
    
    //Check file name
    //私はExpenseというスプレッドシート名ですが
    //適宜自分の取得したいファイル名に変えてください
    if(spreadsheet.getName() !== "家計簿") continue;
    //each sheet
    for(let i = 0 ;i < sheets.length; i++){
      // 今月のシート名かチェックします
      if(currentYearMonthSheet === sheets[i].getName()){
        //私の場合はC9カラムが送信したい値なのでそこを取得。
        const totalAmount = Math.floor(sheets[i].getRange("C9").getValues()[0]);
        const subject = 'Monthly expense report ('+Utilities.formatDate(today, 'JST', 'yyyy, MMM')+")";
        const headerMessage = "Hi! I'll send you " + subject + "\nTotal amount is ¥"+totalAmount+"\n\n";
        MailApp.sendEmail(emailAddressMiki, subject, headerMessage);
      }
    }
  }
}
```

##もうちょっとやりたいこと

- サマリーメールと言いつつ月の支出の合計出してるだけなので、もうちょっと凝ったサマリーにしたい

- ハードコード部分を外だしして汎用的なメソッドにしたい