標準モジュールのFriend変数は開放されない
いゃ当たり前と言えば当たり前なんですが。
今携わっているプロジェクトで、どーにも月次処理がおかしかったんですよ。
今月〆分の処理の部分で、ときどき前月分の明細まで拾ってくるんです。
この「ときどき」ってのが何ともいやらしく。
毎回同じように間違うならトレースかけて洗い出せば済むんですが。
IDEからのデバッグ実行では出ず、リリースEXEにした時だけ、しかも「ときどき」出るんですね。
どーいぅ組み合わせで操作した時に出るのかもいまいちはっきりせず。
丸一日いろんなパターンでいじり回して、どぅやら一度の起動で〆戻しを数回やってから〆を数回やると出るらしい、といぅところまでたどり着き。
でも同じ操作をIDEからやると出ません。
しかたがないので、SQL文吐くところに全部通し番号+SQL文でログを吐くようなトレースロジックを組み込んでまた半日回しまくり。
今回のプロジェクトはメニューをスタートアップに指定、各機能は単体EXEで各々製造し、クラスライブラリ(DLL)に切り替えてソリューションに追加→一括ビルドといぅ形式を採っているんですが、この客先リリース版でだけ狂うといぅことが判明。
で、一度の起動でメニューから連続して複数回〆処理を呼び出した時に発生することが判明。
IDEデバッグ実行版のトレースログと付き合わせると、明細取得のSQL文はまったく同じものが吐かれているのに、月次データ吐き出しのSQL文は確かに先月分までよけいに発生してるんですね。
同じ月を単独で〆めた時には正常に回ります。
連続〆でも、一度メニューまですべて終了→もう一度起動してだと発生しません。
で、答え。
月次処理用標準モジュールの先頭で定義している、取得した明細を一時格納するFriendの配列変数が初期化されていませんでした(T-T)(T-T)(T-T)。
単体テスト時はDLLをWindowsアプリケーションとして単独実行するので、1起動に対して処理は1回。連続〆は複数回実行することでチェックしていたんですね。
これを客先リリース用にソリューションに取り込んでDLLとしてビルドすると、標準モジュール内のFriend変数は、メニュー起動に対して1度だけ初期化(てゅうか生成)されるわけです。
だから、1度の起動で2回〆を実行すると、2回目の実行時には1度目の実行の時に格納した前月分明細の内容が残ったまま当月分を追加で取り込んでいた、というお粗末。
あわてて〆処理の先頭に、明示的にFriend変数群に初期値を代入するロジックを組み込んで一件落着。
わかれば非常に当たり前のことなんですが、なんとなく〆処理の完了時に〆処理DLLが開放されるよぅなつもりになっていました。
標準モジュールが開放されるわけないじゃん。
必ず広域変数は初期化してから使用すること、と製造ルールを作ってもいいんですけど、標準モジュールの使用禁止を謳った方が早いかなぁ。
全部クラスにしちゃえば、呼び出し側でインスタンスの生成→破棄だけをチェックすれば済む話だし。
でも旧VB上がりのPG/SEって、クラスモジュールを嫌がる傾向があるので…人的リソースとしてはどぅなんだろぅ。
来月から次のプロジェクトに込み込まれる予定なので、それまでに少し考えてみよぅっと。