kintone｜年度の計算と年度切替時にメンテ不要な絞り込み条件の設定について

先日[kintoneCafé online vol.2](https://www.kintonecafe.com/-/online)に参加した時に私の業務環境で利用している「年度」の扱いについて、懇親会で相談させて頂いた時の📝です。

#### 前提：「年度」は文字列で作成している。
私の業務環境では、年度アプリを作成して、「2019年度」「2020年度」…といったようにマスタ化して、ルックアップ参照することで利用しています。

* * * 

#### 問題：一覧の絞り込み条件に「年度」があることによる弊害
年度でアプリ上のレコードを絞り込むことで、参照性は向上します。
ですが、同時に年度切替時に「年度」を絞り込み条件にしている一覧やルックアップの絞り込み条件など全ての条件の更新が必要になりますので、保守的な観点から考えると「年度」条件を設定している件数が多くなれば多くなるほど地味で面倒な作業が発生します。

* * * 

#### 解決：「年度区分」フィールド/アプリを新規追加する
業務環境では、「年度」を条件に設定している件数が100件近くあったために、年度切替時の作業がとても面倒で、新しく「年度区分」を新設しました。

「年度区分」はルックアップで「年度区分」アプリのレコードを参照します。
「年度区分」アプリには「当年度」「前年度」「翌年度」といったレコードを保持しています。今まで「年度」を条件としていた部分は、すべて「年度区分」=「当年度」に置き換えることで、少なくとも年度切替時に条件の更新が不要となりました。

その代わりに各レコード上の「年度区分」の値のメンテナンスが必要となりましたが、krewDataを契約していたので、年度切替時に値を「当年度」だったレコードの「年度区分」の値を「前年度」にワンクリックで一括切替で対応できたので、作業工数の大幅短縮が出来ました。

* * * 

#### 相談させて頂いた時に提案された解決案について
##### 「日付」フィールドを利用する
「年度」を判断させるフィールドを「文字列」から「日付」に変更するのはどうか？
後は「日付」フィールドから計算式を利用して年度を算出させるというもの。

##### kintone標準機能の計算式を利用して年度を算出する
kintoneの標準機能で自動計算させる場合「文字列」フィールドと「計算」フィールドが利用できます。フィールド名に「計算」が付与されているものは「計算」フィールドで、「文字列」が付与されているものは「文字列」フィールドです。

※↓図のオレンジのラベルがそれぞれ左横の「文字列」「計算」フィールドに設定されている計算式です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536171/ecc3d974-8451-5d18-ed26-4322af9679db.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536171/b259b558-3ae0-f3f4-4bd1-891431b7a1be.png)

↑の図を確認すると年度を求めるためには、「計算」フィールドで予め「年」と「月」を算出する必要があるとわかります。
「文字列」フィールドの場合は、「年度」を求める計算式が元にしているフィールドも「文字列」フィールドのために、計算することができず`#VALUE!`となっています。

「計算」フィールドだけ使えばよいかといえば、そんなことはなく`年度`という文字列も付与したい場合は、「文字列」フィールドで算出した「年度」と文字列結合する必要があります。

「年度_計算_整形」フィールドの計算結果が`#CONVERT!`と表示されているのは、「計算」フィールドなのに文字列である`年度`を文字列結合しようとしたため。

幾つかの計算式を利用することで、「年度_文字列_整形2」フィールドの結果のように年度を算出することができています。（※年度切替を4月としているため、3月は、2021年度ではなく2020年度扱いとなっています。）

##### 一覧の条件式を「日付」フィールドで設定する（１）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536171/b154c61e-df7b-a5a5-54cb-0ef4218de868.png)

「日付」フィールドを絞り込みの条件として利用する場合、`=(等しい)`の選択肢に`前年`と`当年`と`翌年`を選択することができます。そのため「年度区分」=「当年度」としていたように「日付」=（等しい）「当年」と設定します。

##### 一覧画面を見てみる（１）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536171/198c36e9-b281-e137-0504-066c59d78663.png)
目当ての「当年度」による絞り込みができているように見えますが、よく見てみると2行目の明細は、「日付」フィールドの値が「2021-03-01」のレコードも当年対象として表示されています。

「年度_計算」フィールドの値は「2020」となっていますので、正しくは前年の対象となるべきレコードです。

##### 別の「日付」フィールドを絞り込み条件で利用する
JavaScriptカスタマイズで「年度_計算」で算出された値を元に一覧画面などの絞り込み時に利用する新設する「年度判定_日付」フィールドの値を設定します。
JavaScriptで値を設定するため、初期値は空値とします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536171/72168436-22ab-09cc-b220-0634d5a026b5.png)
##### JavaScriptカスタマイズソースコード
```js
(() => {
  'use strict';
  kintone.events.on(
    [
      "app.record.edit.submit",
      "app.record.create.submit"
    ],
    (event) => {

      let record = event['record'];

      // （１）kintone標準機能で算出された「年度_計算」の値を取得
      const NENDO = record['年度_計算'].value;
      
      // （２）「年度_計算」の値を文字列に置き換えて、
      //　固定値「-04-01」を文字列結合した値を「年度判定_日付」フィールドに設定
      record['年度判定_日付'].value =
        (NENDO.toString() + "-04-01");

      return event;
    });
})();
```
新規作成時の保存前イベントと編集時の保存前イベント時に↑のプログラムを発火させます。
年度の絞り込みで重要な部分は`月`や`日`ではないので、年度のみは算出した「年度_計算」の値を利用しますが、`月`と`日`に関しては、kintoneの日付の設定上当年扱いとなる「04/01」を実際の月日はどうであれ固定で設定します。
半分以上固定値で設定しているため、dayjsなどのライブラリも不要です。

##### 編集画面からの保存でJavaScriptカスタマイズの動作確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536171/8c5e9150-fe64-2893-6477-e8230d10a513.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536171/21bb2440-00d1-5149-8ec4-f0a8a48fa3de.png)
「日付」フィールドに「2020-03-31」と設定して「保存」した場合、「年度判定_日付」フィールドに「2019-04-01」と設定されているため、正常に動作していることがわかります。

##### 一覧の条件式を「日付」フィールドで設定する（２）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536171/f5428a36-7785-4c57-ad4e-58fbad131043.png)
絞り込み条件を「日付」から「年度判定_日付」フィールドに変更します。
条件は=(等しい)「当年」のままとします。

##### 一覧画面を見てみる（２）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536171/6d2e8abb-1173-1133-0fd7-7233c2221526.png)
「年度_計算」の結果が「2021」のレコードが「当年」の対象レコードとして抽出されています。さきほど「2020」つまり「前年」対象だったレコードは抽出対象外となり、変わりに、1行目の「日付」フィールドの値が「2022-03-01」のレコードが「当年」対象レコードとして抽出されており、期待通りの挙動となりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536171/b2250624-5eb5-43a0-e5c8-73a82cd0beee.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536171/e147c512-b728-a7b1-fca6-199ff09080af.png)
同じ仕組みで昨年もさくっと条件を「年度判定_日付」=(等しい)「昨年」で作成することができます。`>`や`<`の条件も利用できるため、以降や以前といった絞り込みも可能で且つ年度切替の度に条件の再設定が不要となります。

##### 懸念点
csv/Excel/APIによる取り込み・更新を行う場合、JavaScriptカスタマイズは実行されないので、取り込み以前に「年度判定_日付」に設定する値をcsv/Excel/APIにて設定してあげる必要があります。

##### 所感
「日付」フィールドベースでやればよかったなあ…とやって見て実感してます。
krewData不要になるし年度切替時の手間も不要。現在の業務仕様より工数がかからない。
わざわざ「年度区分」の値を一括して切り替える必要がないのが良い。

ただ私の業務環境では「年度区分」を複数のアプリに利用している適用してしまっているため、提案頂いた「日付」フィールドから求める「年度」に切り替えるのは結構しんどいなあと感じています。

正常に動いているからそれでも良いのでは？とCaféの懇親会でコメントも頂いていて、「年度区分」は「年度区分」で有りかなと思っています。

書き殴りで読みにくいと思いますが、「年度」の取り扱いに悩んでいる方の参考になれば幸いです。