@IT会議室 新規書き込み停止(2012年10月9日)のお知らせ

@ITの会員制度「@ITクラブ・メンバーシップ」(@ITクラブ)は、10月9日より、弊社が運営するメディアの共通会員制度である「アイティメディアID」へ移行することになりました。これに伴い、@ITクラブのサービスの一部を変更させていただきます。

@IT会議室については、2012年10月9日をもって新規書き込みを終了いたしました(閲覧は引き続き可能です)。今後、質問や回答などは「QA@IT」(http://qa.atmarkit.co.jp/)をご利用くださいますよう、お願い申し上げます。

VB.NETからEXCELファイルの起動と終了について


morimori

2009-10-05 13:59

VB.NETからExcelファイルの起動,終了を行うプログラムを
インターネット上の情報を元に作成を行っています。
下記のソースを実行すると、見た目はExcelは終了しているのですが
タスクマネジャーを見るとEXCEL.EXEがプロセスとして残っています。
何処が悪く、プロセスが消えないのか良く分かりません。
何方か原因,対策を御願いします。

Sub TestExcRunEnd()
Dim xlApplication As New Excel.Application
Dim xlBooks As Excel.Workbooks = xlApplication.Workbooks
xlBooks.Open("C:\test\VBNET.xls")
xlApplication.Visible = True
System.Threading.Thread.Sleep(1000)
'
xlApplication.Quit()
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlBooks)
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApplication)
End Sub

[前のページ 1

コメント

2009-10-05 14:14

Workbooks.Open から返される Workbook オブジェクトに対する Marshal.ReleaseComObject が不足しているからでしょう。

2009-10-05 16:13

>Workbooks.Open から返される Workbook オブジェクトに対する Marshal.Release>ComObject が不足しているからでしょう。

下記のソースに修正を行ってみましたが、現象は変わりませんでした。
Hongliangさんの言われている内容と私が行った内容は違うのでしょうか?

Dim xlApplication As New Excel.Application
Dim xlBooks As Excel.Workbooks
Dim xlbook As Excel.Workbook

xlBooks = xlApplication.Workbooks
xlBooks.Open("C:\VBNET.xls")
xlApplication.Visible = True
System.Threading.Thread.Sleep(1000)
'
For Each xlbook In xlBooks
xlbook.Close(False)
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlbook)
xlbook = Nothing
Next
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlBooks)
xlBooks = Nothing
xlApplication.Quit()
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApplication)
xlApplication = Nothing
GC.Collect()

2009-10-05 16:32

xlBooks.Open("C:\VBNET.xls")

で開いたものを代入して開放して無いのがなんとなく怪しいと思ったので、

Dim xlTest As Excel.Workbook

と宣言し

xlTest = xlBooks.Open("C:\VBNET.xls")

と書き換え、Sleepの直後に

xlTest.Close(False)
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlTest)

とするとプロセスが消えました。

2009-10-06 09:42

'System.NullReferenceException'のハンドルされていない例外が発生しました。
追加情報:オブジャクト参照がオブジェクトインスタンスに設定されていません
とのエラーが、下記の○行で発生します。
何故、エラーが出るのか教えていただけませんでしょうか。

Dim xlApplication As New Excel.Application
Dim xlBooks As Excel.Workbooks
Dim xlBook As Excel.Workbook
○xlBook = xlBooks.Open("C:\nexus_test\VBNET.xls")

xlApplication.Visible = True
System.Threading.Thread.Sleep(1000)
'
xlApplication.Quit()
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlBook)
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlBooks)
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApplication)
GC.Collect()

2009-10-06 10:40

'System.NullReferenceException'のハンドルされていない例外が発生しました。
追加情報:オブジャクト参照がオブジェクトインスタンスに設定されていません

エラー内容のとおり、「xlBooks」がインスタンス化されていないとおもわれます

2009-10-06 11:21

該当箇所以外もコードが色々変わってませんか?

xlBooks = xlApplication.Workbooks

が消えているのがとりあえず原因だと思いますが。

2009-10-06 12:06

申し訳ありません。
私の勘違いで、xlBooks = xlApplication.Workbooks が抜けてしまったようです。
行の追加でエラーは発生しなくなりましたが、
下記のソースを実行してもEXCEL.EXEが残ったままとなります。
何故残るのかお分かりでしょうか。

Dim xlApplication As New Excel.Application
Dim xlBooks As Excel.Workbooks
Dim xlBook As Excel.Workbook
xlBooks = xlApplication.Workbooks
xlBook = xlBooks.Open("C:\VBNET.xls")

xlApplication.Visible = True
System.Threading.Thread.Sleep(1000)
'
xlBook.Close(False)
xlApplication.Quit()
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlBook)
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlBooks)
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApplication)
GC.Collect()

宜しく御願いします

2009-10-06 13:41

提示されているコードで、希望する動作はできますよ
こちらのほうでも確認できました

必要最低限のコードで試されたらどうでしょう?

Imports Microsoft.Office.Interop

Public Class Form1

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim xlApplication As New Excel.Application

xlApplication.Visible = True
System.Threading.Thread.Sleep(1000)

xlApplication.Quit()
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApplication)
End Sub

End Class


#あと気になるのは、ファイルを開いてから何か操作していませんか?

2009-10-06 14:44

下記の最小のソースの場合は、実行後にEXCEL.EXEは消えました。
Dim xlApplication As New Excel.Application
xlApplication.Visible = True
System.Threading.Thread.Sleep(1000)
xlApplication.Quit()
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApplication)

但し、xlBooksをソースに追加すると、実行後にEXCEL.EXEは消えなくなります。
Dim xlApplication As New Excel.Application
Dim xlBooks As Excel.Workbooks = xlApplication.Workbooks
xlApplication.Visible = True
System.Threading.Thread.Sleep(1000)
xlApplication.Quit()
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlBooks)
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApplication)

因みに、このソースの実行以外は何も行っていません。
何故、この様な現象になるのか分かりません。

宜しく御願いします

2009-10-06 16:06

こちらではxlBooksを追加したコードでもプロセスは消えています。
まさか実行する前からプロセスが残っていたからって事はないですよね。

2009-10-07 08:36

>こちらではxlBooksを追加したコードでもプロセスは消えています。
私の環境では、EXCEL.EXEが残ってしまいます。

>まさか実行する前からプロセスが残っていたからって事はないですよね。
私も、何かゴミが考えられると思い、PCのリブート後直ぐに実行してみましたが
状況に変わりません。

私の環境に問題があるのでしょうか?
VB.NETは2002,EXCELは2003です。

どの様にして良いのか、分からなくなってしまいました。

2009-10-07 09:37

詳細にはどのように確認しましたか。
こちらでは下記のように確認しました。
同じ操作をして同様の現象が起こるか試してください。

【環境】
Windows XP SP2
Visual Studio 2005 SP1
Microsoft Excel 2002 SP3

1.VS2005で「Windowsアプリケーション」のプロジェクトを新規作成する。

2.「参照の追加」で「COM」タブの「Microsoft Excel 10.0 Object Library」を追加する。

3.フォームにボタンを貼り付けて、イベントハンドラに下記の定義をする。
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim xlApplication As New Excel.Application
Dim xlBooks As Excel.Workbooks = xlApplication.Workbooks
xlApplication.Visible = True
System.Threading.Thread.Sleep(1000)
xlApplication.Quit()
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlBooks)
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApplication)
End Sub


4.タスクマネージャを開き「プロセス」タブで「イメージ名」でソートし「EXCEL.EXE」のプロセスが無いことを確認する。

5.プロジェクトをデバッグ実行し、先ほど張り付けたボタンをクリックする。

6.実行中はタスクマネージャに「EXCEL.EXE」が表示されるが、実行終了時には消えている。

2009-10-07 09:47

EXCEL.EXE が消えないというのは、良く聞く現象なのですが、同じコードでも起きる環境と起きない環境があるらしく、なぜこのような違いがあるのかが不思議です。

ちなみに C# ですが最近の似たような事例を紹介します。
http://ap.atmarkit.co.jp/bbs/core/fdotnet/14962
http://ap.atmarkit.co.jp/bbs/core/fdotnet/13832

推理ですが、Excel に限らずソフトウェア関連の話題で環境によって挙動が異なることを掲示板でいろいろ話していると、最後にはウィルス対策ソフトウェア(やウィルスそのもの)による影響だと分かった、というのが最近増えてきました。ウィルス対策ソフトウェアが空気のようになっていて、なかなかその存在に気付きにくくなってきています。
もしかしたら EXCEL.EXE の件もそういうことなのかな?と最近思うようになりました。

2009-10-07 09:54

上記手順を、Visual Studio 2002で行っても同様の結果が出ました。

2009-10-07 10:29

EXCEL.EXEが消えました。

原因は、デバッグモードで実行していた為と思われます。
紹介されたC#の事例の中にデバッグモードという言葉があったもので
もしやと思い、デバッグ無しで実行してみましたら、上手くいきました。

この現象は、常識の内容なのでしょうか?
自分では、デバッグで動かし、1行1行確認を行っていく動作が普通だったもので。

アドバイス、有り難う御座いました

[前のページ 1