エンジニアリング･トライアル

# はじめに
こんにちは。はじめて記事を書きます@tsugumiriです。
私は日々[審査の業務](https://qiita.com/sanshi/items/c7b16779e77c858afe7d)に従事していますが、今年は縁あって、エンジニアリング･トライアルの取り組みに参画いたしました。今回は取り組みで得られた知見を紹介させていただければと思います。

# エンジニアリング･トライアルとは?

エンジニアリング･トライアルは、その名の通りではありますが、メインの業務と並行し、部署内の自動化の手法を[エンジニアさん](https://qiita.com/omomukumamani_piroshi)に学ぶ取り組みです。私は今回Google Apps Script (以降GASと記載します)でのツール作成を題材に、プログラミングの基礎と応用を学びました。

GASはGoogleアカウントをお持ちであれば誰でも始められるプログラミング言語です。
独学で学び始めた方も多いのではないでしょうか?

GASを用いた自動化は業務の劇的な効率化が図れる一方で、独学で学び始めるとプログラミングの基礎知識を学ぶ機会が得づらい側面があると感じていました。
今回の取り組みでは、ツールの設計方法やスクリプトを要所要所でレビューいただき、エンジニアリングの観点でアドバイスをいただくことで、自身の作成方法が妥当であるかを確認する機会をいただきました。
また、その過程で、プログラミングの基礎知識やどのような構造で制作するかなど、基本設計を十分に考慮することの重要さに気づきました。

# とある制作依頼

早速ですが、実際の制作依頼を例に、取り組みの中で得られた知見をご紹介できればと思います。この夏、取り組みの1つとして、以下条件に該当する内容のチャットツールへの通知制作を承りました。

- 申請に関する情報を記録しステータス管理を行っているGoogle スプレッドシートにおける未完了情報を通知したい
- 週2回、指定の曜日に通知したい
 上記が祝日にあたる場合は、基本翌日に通知したい

おそらく、詳細に差はありながらも、比較的よくある要件かと思います。自分自身でもGoogle スプレッドシートの内容を通知するスクリプトは制作の経験があったため｢これは!｣と思い制作に当たりました。
が･･･すすめるにあたり、2点目の条件指定が、日本語での表現としては非常に簡潔でありながら、いざコードを書くとなると、思った以上に難しい要件でした。

独学で学んだ範囲で

- 曜日の判定はできる
- 休日･祝日の判定はできる
- 2つがあいまったときに、if文でどのように分岐し設計すべきか･･･

考えられるとすると

- 当日の曜日、祝日の判定
- 前日が祝日であったかの判定
- 前日が指定曜日であったかの判定
･
･
･

果たして要件はこれだけでよいのか、全てif文で分岐させればよいか･･･相当悩みました。

# アドバイスをいただく

自作のif文を繰り返すコードに限界を感じ、正直にどのように制作すべきか、[エンジニアさん](https://qiita.com/omomukumamani_piroshi)に相談しました。自身の実力を過信し無理をして事故を起こすよりは相談です。その際以下アドバイスをいただきました。

- 要件の過不足の確認については･･･
分岐図を用い、条件を書き出してみることで、要件不足がないかを｢見える化｣してはどうか

- 制作にあたっては･･･
判定のデータ、特に｢祝日且つ指定曜日であった場合｣の記録を一時的に保管する方法を用いてはどうか

コードの制作方法とともにいただいた前述アドバイスについて、分岐図に起こすと以下のようになりました。

![Qiita_20221214_001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985757/d81731ca-1ec9-0576-6fb0-6f1d158662ab.png)

｢未送信フラグの記録｣を用いない場合、都度、当日だけではなく前日の日付を取得し、祝日、且つ送信対象日であるかの判定が必要と考えていました。当初私はこの条件をif文でのみ制作しようと試みており、うまく処理する方法が検討できませんでした。
また、アドバイスいただいた方法であれば日付を扱うのは当日のみでよく、見通しのよい設計とすることができました。

# 最終的なコード
最終的にGASで制作を行ったコードは以下のようになりました。

``` js
function main()
{  
  var activeSheet = SpreadsheetApp.getActiveSpreadsheet();

  //送信フラグを記録するスプレッドシートを定義する
  var BOT_CONFIG_MAIN_SHEET_NAME = ' *** ';
  var sht = activeSheet.getSheetByName(BOT_CONFIG_MAIN_SHEET_NAME);

  //未送信フラグを記録するスプレッドシートのセルを指定する
  var CELL_OF_NO_SEND_DATE = " *** ";

  //実行日を取得する
  var today = new Date()

  //土日判定を行う 
  if(!isWeekDay(today)) {
    return;
  }

  //送信フラグを作る 送信対象曜日の場合true
  var send = isDayOfWeek(today);
  
  //祝日判定を行う
  if(isHoliday(today)) {
    //送信フラグの判定を行う
    if(send == true) {
      //未送信フラグとして当日の日付を記録し終了する
      sht.getRange(CELL_OF_NO_SEND_DATE).setValue(today);
    }
    return;
  }
  //未送信フラグ 読み込む
  var no_send_date = sht.getRange(CELL_OF_NO_SEND_DATE).getValue();
  
  //記録がある場合は実行するため送信フラグをtrueとする
  if(no_send_date) {
    send = true; 
  }

  //送信フラグがfalseの場合は実行しない
  if(send == false) {
    return;
  }

  /* 実行内容は今回省略 */

  //未送信フラグを削除する
  sht.getRange(CELL_OF_NO_SEND_DATE).clear();
}
```

# トライアルで得られた知見

今まで自分自身でスクリプトを制作する場合は、業務視点で課題感を感じた｢やりたいこと｣に目が向いてしまい、それに向けて自身の知識を総動員することで｢どのようなスクリプトを書くか｣を考えてしまいがちでした。

今回私は、当初ひたすらif文を繰り返すことで要件の実現を目指しましたが、行き詰まりました。無理をして解決することができた可能性もありますが、｢判定データの記録｣を行う方法をアドバイスいただいたことで、後々、自分以外がメンテナンスすることになったとしても､見通しがよく、処理が理解しやすいスクリプトを制作することができたのではないかと思います。

GASはGoogle スプレッドシートを併用することが容易であるため、今回私が気づくことができなかった｢未送信フラグの記録｣ のような一時的なデータの保管を行う方法は、他の用途でも活用できるのではないかと考えています。

また、分岐図に要件や処理を書き起こすことでやるべきことが整理され、スクリプトの製作中状況が確認しやすくなりました。基本的なことではありますが、複雑さや難しさを感じたときこそ、焦らずに、状況や要件を書き出し整理したり、相談できる立場の方に意見をいただくことの大切さを改めて認識しました。

# さいごに
まだまだ半人前にも程遠いエンジニアリングスキルですが、いただいたトライアルの機会で知識を深め、来年も独学ではできなかった方法を学び、業務に活かせればと考えています。

最後までお読みいただきありがとうございました。