} 7.家計簿の時間起動による自動入力化の学習


●家計簿には新聞代や電気代等ほぼ決まっていで人間が入力しなくても自動入力出来る物も有ります、そこで時間起動の機能を使った自動化の学習をします。
●まず最初に現状を調査し、どのようなプログラムとすれば良いか検討します。新聞代毎月27日前後3000円、電気代毎月12日前後ほぼ2万円、水道代2か月おき25日前後にほぼ2万円、火災保険12月28日前後3万円等が有ります。これでどのような物か整理します。
☆自動登録しようとしているデータは内容と年月日と金額です。まずキーは内容で良さそうなので家計簿内容実表に追加すれば良い事になります。
☆新たな項目として必要な物を検討します。
☆間隔を見ると毎月、2か月おき、12月と有るのでこの間隔を情報として持つ必要があます。どのような表現するかは色々考えられますが、今回はその月は月をそのまま書き、以外は先頭にMを付けて間隔を数値1文字で表現する方法としてみます。この方法で表現すると、毎月="M1"、2か月おき="M2"(1月を起点),12月="12"と成ります。
☆金額は決まった額の物と、決まっていない物があるので、決まっていない物は近い値を設定し、仮設定している旨の表示が必要と思われるので、仮設定を設け仮設定の時は"仮"、以外は空白とする事にします。
☆年月日は1回の自動登録の範囲に関係するので自動登録のタイミングを決める必要があります。今回は月末に翌月分を登録する事とします、よって年月日の年月は不要で日が必要と成ります。尚、日は前後となって居ますが、殆どが日を決めその日が銀行の休日の場合は前にずらす方法が多いのでこの方法を取りますが、銀行単位のカレンダーを作るのも大変ですので、インストールで提供されているカレンダーの稼働日を使って計算する事にします。 ここで1点問題が有るので注意が必要です、例えば日が1日とした場合1日が休日であると当然前は前月になってしまいます。このシステムでは内容はその月に1個と決めたので、毎月登録している場合は同じ月に同じ内容を作成しようとしてしまい、作成出来ない問題が発生します、この問題に対処する事も当然可能ですが、プログラムが結構複雑に成るので、今回は7日以前の物は日を前では無く後にずらす事で対応とします。
☆検討の結果、間隔、日、仮設定、金額を新たに家計簿内容実表に作成する必要があるとなりました。
■テーブル名=ZZZYAA_家計簿内容実表(追加項目)
■列名1=家計簿_間隔 CHAR(2) (""=自動化対象外,"M1"=毎月、"M2"=1月から2カ月おき,"12"=その月のみ)
■列名2=家計簿_日 DECIMAL(2,0) (1から31まで)
■列名3=家計簿_仮設定 NCHAR(2)(仮設定は"仮"以外は空白とする)
■列名4=家計簿_金額(既に設定済)

(1.1)データ辞書に間隔、日、仮設定を作成します。(金額は設定済みなので不要です)

(1.2)家計簿内容実表に間隔、日、仮設定、金額を追加します。

(1.3)家計簿内容更新プログラムに間隔、日、仮設定、金額のデータを作成します。
◆1010 =IF{_DATA=}SET{.家計簿_日=0,.家計簿_仮設定=}
◆1020 = EXIT{.家計簿_金額};
★.家計簿_間隔が空白の場合は時間起動は不要なので、.家計簿_日と.家計簿_仮設定を空白にしてEXIT{.家計簿_金額}で最後の金額の入力に行きます。
★I言語ではデータの最後の入力項目を解析し、その項目で'Enter'が押された場合更新処理に行くように設計されているので、必ず最後の入力項目で入力できるようにプログラムを作って下さい。
★「DATA={}.?.DATA&家計簿_日?]で宣言されている物のデータ名は「DATA={}」と「?.DATA&」と最後の「?」を除いた「.」と「家計簿_日」を合わせた「.家計簿_日」と成ります。

(1.4)該当データを登録した所です。

(2.1)ZZZZ010222で時間起動プログラムを作成します。
★3行目に「{LINE 1(1)/2 3/2}{2,,9}{(08,17),(50,79),(81,99)}」と表示されています、ポイントは3番目の{(08,17),(50,79),(81,99)}です、これがCHECK1で設定された内容を表示しているので入力出来る範囲を示しています。

(2.2)3番目の最初08から17までの時間が時間起動出来る範囲で、これは混在テーブルに時間起動の開始時間(ZZZZZZ_TIME_START,08:30)と終了時間(ZZZZZZ_TIME_LIMIT、17:30)が設定されているのを使って制限しています。開始時間をこれ以外早く又は遅くしたい場合は混在テーブルを変更する必要があります。

(2.3)時の08と入れると35から55までの5分おきのリストボックスが表示されます。ZZZZZZ_TIME_STARTで指定された08:30にその日の起動予約をするようになって居るので時間起動は余裕を見て5分後から起動出来るようになっています、取りあえず08:55起動とします。

(2.4)M1は3行目が{(50,79),(81,99)}となっているので80ヲを除く50から99までを使用します、00から40まではメニュー起動ジョブが使い41から49まではメニュ-のCOPYで呼び出して使用します。今回は50と01を使用します。

(2.5)ここで起動するタイミングを指定します。色々なタイミングが考えられますは今回は毎月の稼働末日で翌月の登録とします。毎月はタイミングはMで稼働末日は 始末が"-"で何日を"01"とします。

(2.6)時間起動情報作成後"0"(選択)を押してメニュー作成画面行きます。

(2.7)M0、M1、M2は時間起動で設定いた値と同じ物を使いM3で複数のジョブを連続して起動出来るようになっています。今回はM3が"01"の1個のジョブで対応します。

(2.8)時間起動プログラムはPROGRAM=もSET=もDATA=も使えません。=で始まるセクションとして手入力で対応します。
◆ 100 =SET{WC.TODAY=_TODAY,W0.Y=WC.TODAY[1;4],W0.M=WC.TODAY[5;2]};
★今日の日から年と月を抜き出します。
◆ 200 =COMPUTE{W0.M+=1};IF{W0.M>12}SET{W0.M=1}COMPUTE{W0.Y+=1};
★月に1を足して12以上になった場合は月を1にして年に1を加え翌月の年と月を計算しています。
◆ 300 =COMPUTE{W0=W0.M%2};
★月を2で割った余りを計算しています。
◆ 400 =IF{W0=1}SET{WC.M2=',''M2'''}JUMP{};SET{WC.M2=};
★余りが1の時は奇数月でM2が対象となんるので「,'M2'」を以外は対象とならないので空白を設定しています。
◆ 500 =IF{W0.M@LENGTH=1}SET{WC.MM='0'+W0.M}JUMP{};SET{WC.MM=W0.M};
★年が1桁の場合は先頭に0を付けて全てを2桁にしています。
◆ 600 =SQL1{SELECT 家計簿_内容,家計簿_日,家計簿_仮設定,家計簿_金額
◆ 700 =  FROM ?_MM?_家計簿内容実表
◆ 800 =  WHERE 家計簿_間隔 IN('M1'?WC.M2?,'?W0.M?') ORDER BY 1};
★毎月「M1」か奇数月「?WC.M2?」か同じ月「?W0.M?」の間隔のデータを抜き出すSQLを実行します。
◆ 900 =SQL1_NEXT:SQL1_NEXT{WN.家計簿_内容,W0.家計簿_日
◆1000 = ,WN.家計簿_仮設定,W0.家計簿_金額}JUMP{SQL1_END};
★1件づつ処理します。SQLは基本的には1件づつ処理しなくても、SQLだけで対応出来ますが、今回は件数も少なく、SQLだけでは複雑な処理となるので、1件づつ処理する事でプログラムをより簡単にしました。
◆1100 =IF{W0.家計簿_日<8}SET{WC.FUNC='MIN',WC.GL='>'}JUMP{};
◆1200 =         SET{WC.FUNC='MAX',WC.GL='<'};
★8日以前は後方の一番小さい(MIN)稼働日、8日以降は前方の一番大きい(MAX)稼働日を選びます。JUMP{}のように空のJUMP命令は以降のセミコロン(;)2個を飛ばすので、一般的なプログラムのELSEと同じ動きをします。
◆1300 =IF{W0.家計簿_日@LENGTH=1}SET{WC.DD='0'+W0.家計簿_日}JUMP{};
◆1400 =             SET{WC.DD=W0.家計簿_日};
★日が1文字の場合は2文字にし全ての日を2文字にします。
◆1400 =IF{WC.家計簿_日@LENGTH=1}SET{WC.家計簿_日='0'+WC.家計簿_日};
★日が1桁の物は先頭に"0"を付けて2桁にします。
◆1500 =SQL_SET{WC.家計簿_年月日}{SELECT ?WC.FUNC?(SYSTEM_DATE) FROM
◆1600 =  ?_MP_ZZZZ?ZZ_CALENDAR_TABLE WHERE SYSTEM_HOLIDAY=' '= ?_MP_ZZZZ?ZZ_CALENDAR_TABLE WHERE ZZZZZZ_HOLIDAY=' '
◆1700 =  AND SYSTEM_DATE?WC.GL?='?W0.Y??WC.MM??WC.DD?'
◆1800 =  AND Z_CANCEL=' '};
★システム提供のカレンダー(?_MP_ZZZZ?ZZ_CALENDAR_TABLE)で直近の稼働日を抜き出し年月日を決定します。
◆1900 =IF{_SQL_SET_COUNT=0}ERROR{カレンダー未作成};
★カレンダー無しはエラーとします。
◆2000 =PROGRAM{?_MM?_家計簿実表}{WC.家計簿_年月日,WN.家計簿_内容}
◆2100 =  {W0.家計簿_金額,WN.家計簿_仮設定}{2N};
★家計簿実表に作成します。尚{2N}とするとすでにデータが作成されていると、作成しないで正常終了しますが、同じ年月の同じ内容が有っても作成されます、この場合でも作成しない場合はかなり複雑なSQLとなるので、今回はこれで良しとします。
◆2200 =BACK{SQL1_NEXT};
★次のデーターを読みに戻ります。
◆2300 =SQL1_END:
★これで終了です。

(2.10)操作でT(TEST)で実行してみると「列名 '家計簿_仮設定’が無効です」のエラーがでました。これは家計簿実表に家計簿_仮設定の列が設定されていないのが原因です。
★ここで「カレンダー未作成」のエラーが出た場合は「2. I言語のインストール方法」で説明されている朝の立ち上げ処理を実行してカレンダーを作ってから再度実行して下さい。

(3.1)ZZZZ020226の「テスト テーブル 更新」最終列に家計簿_仮設定を追加します。

(3.2)ZZZZ010222で再度Tでテスト実行してEndで成功しました。

(3.3)ZZZZ010221で仮設定のDATA=を追加します。

(3.4)Tでテスト実行しすると電気代と新聞代が作成されているので、これで完成です。
All Rights Reserved, Copyright (C) 2016-2016 Nobumichi Harasawa.