tagCANDY CGI VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板)
VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板)
[ツリー表示へ]  [ワード検索]  [Home]

タイトル Re^6: VB2005からAccess2000への連携時のトラブル
投稿日: 2008/06/28(Sat) 08:59
投稿者魔界の仮面弁士
> 解放処理出来ました。ありがとうございます。
解決したようで何よりです。


問題は解決したようなので、以下、第三者からのたわ言をつらつらと。


> Public Function Excel_Write_Open(…
このメソッドが False を返すような状況における設計が、不十分であるように見えます。
・Excel_App 変数が Dispose 済み、あるいは Nothing 状態だった場合。
・ファイルを開くことができなかった場合。
・該当するシートが見つからなかった場合。
・Excel がビジー状態だった時(ユーザー応答のダイアログを表示中など)。
などの状況では、このメソッドは False を返す可能性がありますが、
その場合、それぞれの変数(Excel_Bookなど)の後始末はどのように行われるのでしょうか?

たとえば、存在しないシート番号を指定して Excel_Write_Open が呼ばれた場合
「Sheets は取得できたが、Sheet は Nothing な状態」になる可能性がありますが、
この場合の解放処理は、どこにその責務が発生するでしょうか?

もし、モジュール側にその責があるのなら、Excel_Write_Open 内にて、
失敗時の後始末を行わねばなりませんが、現在はそうなっていません。

あるいは、呼びだし側に解放の責任を負わせるならば、このメソッドが
False を返した場合に、それらを解放させるためのメソッドが用意されるべきですが
現在はそれが見当たりません。(事前の処理が正常に行われた場合には、
Excel_Write_Close/Excel_Write_End のメソッドで解放できますけれども…)


> Public Function Excel_Write_Main(…
メソッド内で使われている Excel.Range オブジェクトの解放処理が抜けています。
ここのサイトの Excel 関係の項目を再読ください。
http://hanatyan.sakura.ne.jp/dotnet/excelme.htm

なお、参照設定しているアセンブリによっては、Range や WorkSheets が
 「(ReleaseComObject の呼び出しが必須な) COM オブジェクトである場合」と、
 「(ReleaseComObject してはいけない) マネージオブジェクトである場合」とが
ありますので、この点も注意しておいた方が良いでしょう。


> Public Function Excel_Write_Close(…
このメソッドも True / False を返すように設計されていますが、呼び出し側では
False が返された場合に、どのように対処することが想定されているのでしょうか?


> MRComObject
そもそも、このメソッドの実装はどのようになっているのでしょうか。
同名のメソッドを実装したサンプルは幾つかありますが、それぞれ
微妙にコードが異なるようですので、少々気になります。


> このようにしたのは他の処理でも使いまわししたいからです。
Module でそのような実装を行うと、その分、ステート管理の手間が増えますよ。

Private Class の場合は、“メソッドの呼び出し順”を親クラス側で制限できるので
あまり問題にはなりませんけれども、今回は Module だそうなので、現状の
実装手法には少々不安を感じます。


現在の実装は、それぞれのモジュールレベル変数について
 ・その変数は、どのメソッドによって生成されるのか。
 ・その変数は、どのメソッドによって破棄されるのか。
 ・破棄する前に次の生成が行われた場合に、対処できているか。
 ・処理の途中で何らかのエラーが発生した場合、変数の状態はどうなるのか。
といった点の管理が、モジュール側で行われるのか、呼び出し側に任せるのかが
曖昧になってしまっているように見えました。

たとえば、Excel_Write_End や Excel_Write_Close を呼び出した後で、再度、
Excel 処理を行うような要件が今後発生した場合、現状のコードでは対応できません。
(クラスではなくモジュールであるため、Application インスタンスを再生成できない)

現時点の実装はそれで良いとしても、たとえば数ヵ月後、自分あるいは他人が
バグ修正や機能追加のために手を加えるような場合には、その開発者が
それぞれのモジュールレベル変数のスコープを十分に理解していないと、
オブジェクトの解放漏れといった、見つけにくい問題を引き起こしやすくなるかと。


----
以下、今回の実装に必ずしも必要というわけではありませんが、
COM オブジェクトをカプセル化する場合によく使われる
「Dispose Finalize パターン」という実装手法に関する技術資料を。

http://msdn.microsoft.com/ja-jp/library/s9bwddyx%28VS.80%29.aspx
http://msdn.microsoft.com/ja-jp/library/b1yfkh5e%28VS.80%29.aspx
http://hongliang.seesaa.net/article/14551716.html

- 関連一覧ツリー をクリックするとツリー全体を一括表示します)

古いスレッドにレスはつけられません。