DOBON.NETプログラミング道掲示板
HOME
HELP
新規作成
新着記事
ツリー表示
スレッド表示
トピック表示
発言ランク
ファイル一覧
検索
過去ログ
No35244 の記事
■35244
/ )
Re[1]: Excel Com オブジェクトの増殖
□投稿者/ 魔界の仮面弁士
大御所(1486回)-(2022/11/27(Sun) 08:37:41)
■
No35241
に返信(たこさんの記事)
> Excelの処理部分はクラスにまとめ処理していますが、タスクマネージャーで見ると閉じたはずのExcelが残っています。
> いろいろやってみましたが解決できず、お知恵をお借りしたいと投稿致します。
省略されている箇所に問題があるような気もしますね。
たとえば、使用例のところで
> ExEx1 = New ExcelEx()
> ExEx1.WorkBook = path & "Test.xlsx"
> ExEx1.xlsApplication.WindowState = Excel.XlWindowState.xlMaximized
> ExEx1.Sheets(1)
> ExEx1.WorkBook = "Close"
と書かれていますが、Sheets メソッドの実装が不明瞭ですし。
> Friend xlsApplication As Excel.Application = Nothing
これらの COM オブジェクトを非 Private として公開されていますが、
Friend で公開するにしても、ReadOnly な Property にしておくべきかと。
ただし ReadOnly だとしても、ExcelEx 外から Open や Close 等、あるいは Cells 等への
アクセスは無制限に可能となってしまいますので、COM オブジェクトを直接公開すると、
ExcelEx だけでは、参照と解放の管理をまかないきれなくなることがあります。
解放まですべてクラス側で管理するなら、委譲している Excel のオブジェクトを
直接公開するのではなく、必要な操作のみを再公開するようにしたうえで、
IDisposable パターンも追加実装しておくのが安全です。実装量は爆発的に増えますけれどね。
https://learn.microsoft.com/ja-jp/dotnet/standard/garbage-collection/implementing-dispose
https://ufcpp.net/study/csharp/rm_disposable.html
逆に、そこまでの実装コストをかけられないというのであれば、
ヘルパーライブラリとしての実装に留めるという手もあろうかと。
> Private _WorkBookIsNew As Boolean = Nothing
= False と書いた方が素直ではありませんか?
> Public Property WorkBook As String
今回の COM 解放の問題からは外れますが、こういったものはプロパティではなく、
String 引数を持ったメソッドとして実装する方が望ましいです。
クラス設計的には、プロパティは "状態" を表すものであり、
"動作" を行うことを目的としたプロパティを実装すべきではありません。
"動作" を目的とするのはメソッドの役目ですよね。
16bit 時代の Visual Basic ではプロパティで動作させていたりもしますがね…。
(例:32bit 版では非推奨になった CommonDialog.Action プロパティなど)
> Private Sub WorkBook_Open(Optional ByVal strFileName As String = Nothing)
> 'Excel アプリケーション起動
> xlsApplication = New Excel.Application
WorkBook_Open が 2 回呼ばれると、xlsApplication 変数が
以前に編集していたインスタンスを破棄することなく、
新しい Application インスタンスを生成することになりそうですが、
何らかの再入防止策が組み込まれていますか?
インスタンス管理を考えると、Application の起動は
ExcelEx のコンストラクタで行った方が良いと思います。
> MRComObject(xlsRange, True)
ExcelEx の他の部分の処理がどうなっているのかにもよりますが、
Range オブジェクトは複数使われることも多いので、
自分ならコレクション管理するかな…?
> If Not xlsWorkbook Is Nothing Then xlsWorkbook.Close()
省略された部分のコードによって、この時点で Nothing になっていることがあるということですか?
提示された範囲のコードを見るだけでは、ここで Nothing になっているケースとは、外部から
ExEx1.xlsWorkbook = Nothing
とされた場合か、あるいは WorkBook_Open がまだ呼ばれていない時ぐらいしかなさそうですが…。
(または、存在しないファイル名を指定するなどして、WorkBook_Open が失敗した場合とか)
あと、xlsWorkbook.Saved が False の時に Close を呼び出すと、
DisplayAlerts が True に戻されていた場合、保存確認のダイアログが表示されることになります。
そして保存確認でキャンセルされた場合、実際には Close されません。
もしも終了時の保存が常に不要な場合は、Close 前に Saved プロパティを True にしておくか、
もしくは Close メソッドの SaveChanges 引数に False を指定するようにします。
> Excelを閉じた時にプロセスは終了・削除されると思っているのですが、認識が違うのでしょうか…
.NET 側を解放したとしても、ReleaseComObject されねば COM 側は生き残りますが、
その逆に COM 参照が残っている状態で Excel を閉じた場合、終了せずに非表示だけで留まることがあります。
逆に、 COM 側だけが解放されたとしたら、解放済みのオブジェクトを操作するタイミングで、
HRESULT: 0x80010108 (RPC_E_DISCONNECTED) に相当する例外
たとえば「起動されたオブジェクトはクライアントから切断されました。」などが
発生する可能性があります。
違反を報告
Javascriptを有効にしてください
この投稿が掲示板のルールに違反しており、何らかの対処が必要であると思われる場合は、以下のフォームを利用して管理人に報告することができます。
マルチポストの報告は、
返信フォーム
の上にある「マルチポストの報告」リンクをご利用ください。
この機能の悪用は絶対にしないでください。
悪用されたと管理人が判断した場合は、予告なしで厳しい対処がなされる可能性があります。
確認等の目的で、入力されたメールアドレス宛に返信メールが送信される可能性があります。メールの受信ができないメールアドレスは入力しないでください。
下のフォームが使用できない場合は、
メールフォーム
を使って管理人にご報告ください。
お名前(必須)
メールアドレス(必須)
本文(必須)
(違反理由など)
返信
削除キー/
編集
削除
Mode/
通常管理
表示許可
Pass/
HOME
HELP
新規作成
新着記事
ツリー表示
スレッド表示
トピック表示
発言ランク
ファイル一覧
検索
過去ログ
-
Child Tree
-