QA@IT
この質問・回答は、@ITの旧掲示板からインポートされたものです。

Excelのプロセス終了方法は??

いつも参考にさせていただいております。
さて、ヘルプを参考にエクセルを起動/終了して
みたのですが、タスクマネージャにExcelのプロセス
が残ったままになります。
解放方法を色々試したのですが・・・
どこか不備があるのでしょうか?

(↓以下、MSヘルプを参照し実行)
---------------------------------------
Sub TestExcel()
Dim xlApp As Excel.Application
Dim xlBook As Excel.Workbook
Dim xlSheet As Excel.Worksheet
xlApp = CType(CreateObject("Excel.Application"), Excel.Application)
xlBook = CType(xlApp.Workbooks.Add, Excel.Workbook)
xlSheet = CType(xlBook.Worksheets(1), Excel.Worksheet)
xlSheet.Cells(2, 2) = "This is column B row 2"
xlSheet.Application.Visible = True
xlSheet.SaveAs("C:\aaa.xls")
xlBook.Close()
xlApp.Quit()
xlSheet = Nothing
xlBook = Nothing
xlApp = Nothing
End Sub
[ メッセージ編集済み 編集者: takahon 編集日時 2003-08-15 18:56 ]

質問者:takahon

回答

こんばんは、meiです。

takahonさんの書き込み (2003-08-15 18:06) より:

さて、ヘルプを参考にエクセルを起動/終了して

みたのですが、タスクマネージャにExcelのプロセス

が残ったままになります。

処理の最後に、
System.GC.Collect()
を追加するとどうでしょうか?

Notingでクリアしてあげても、
ガベージコレクタが削除してくれていないと思われます。

投稿者:mei

編集 履歴 (0)

meiさんこんばんは。
返信有り難うございます。

引用:
--------------------------------------------------------------------------------

処理の最後に、
System.GC.Collect()
を追加するとどうでしょうか?

--------------------------------------------------------------------------------

処理を追加してみたのですが・・・
状況は変わらないようです。
CreateObjectでの「CLOSE」「Nothing」が
失敗しているんでしょうか・・・
(VB6.0の時も同じような処理で悩みました)

投稿者:takahon

編集 履歴 (0)

takahonさんの書き込み (2003-08-15 21:20) より:

処理を追加してみたのですが・・・

状況は変わらないようです。

駄目ですか・・・
私のところで動かした限りはタスクマネージャ上で、
Excelが消えるのが確認出来たのですが・・・

あと、
xlSheet.SaveAs("C:\aaa.xls")
は、エラーになりますが(\が一個多い)、SaveAsで失敗している訳じゃないですよね?

追記
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=3343&forum=7
↑過去ログが参考になりそうです。

[ メッセージ編集済み 編集者: mei 編集日時 2003-08-15 21:52 ]

投稿者:mei

編集 履歴 (0)

meiさんの書き込み (2003-08-15 21:09) より:

処理の最後に、

System.GC.Collect()

を追加するとどうでしょうか?

Notingでクリアしてあげても、

ガベージコレクタが削除してくれていないと思われます。

DisposeメソッドまたはCloseメソッドがある場合は必ずコールする。
GC.Collect(2)で、完全解放させる←詳しくは川俣さんのコラム。
↑どの記事だったか忘れました。『ガベージコレクタが走るときに参照されているメモリは世代があがり、解放されにくくなる。加えて確保時に一定量以上のメモリを確保した場合は世代が2になり、コレクトの対象とならない。』みたいなことが書いてありました。

 より完全を期すなら、メインとなるクラスでエクセルをコールするのではなく、メインとなるクラスによって作成されるクラスのインスタンスでエクセルをコールし、このインスタンスを破棄する。エクセルを起動するために確保したメモリが、完全に参照されなくなるようにする。また、いきなりCreateObjectではなく、インスタンスの有無を調べ、再利用するような仕組みも考える。

 私も含めて、過去に数回同じ内容のポストがあるので、検索して参照してください。
[ メッセージ編集済み 編集者: Jitta 編集日時 2003-08-18 09:15 ]

投稿者:Jitta

編集 履歴 (0)

後輩が同じことで悩んでましたが、結局、
Excelのプロセスをkillしてたようでした。

投稿者:cats

編集 履歴 (0)

関係ないかもしれませんが、

xlSheet.SaveAs("C:\aaa.xls")

って xlBook.SaveAs("C:\aaa.xls")  ですかね。

それと、
Application.DisplayAlerts = False
等を入れてみては?

投稿者:Beatle

編集 履歴 (0)

間違った、

Application.DisplayAlerts = False
ではなく、
xlapp.Application.DisplayAlerts = False
ですかね。

投稿者:Beatle

編集 履歴 (0)

xlSheet.Application.Visible = True

こいつ外すとどうなりますか?
私もVB6.0のときに同現象で悩んだ結果
たしかApplicationプロパティを利用するとプロセスが残る現象が
発生してたように記憶しています。

遠い昔の話なので間違っていたらすみません(^^;

投稿者:takira

編集 履歴 (0)

こんにちは。
わたしも、この問題には長いこと苦しめられました。

解決方法としては、

xlSheet.Application.Visible = True の後で
xlSheet.Application.ScreenUpdating = True

を試してみてください。

これは、EXCEL97以降の既知の問題のようです。

マイクロソフト サポート技術情報 - 187745
[BUG] オートメーション機能を使用していると Microsoft Excel が正しく再描画されない
http://support.microsoft.com/default.aspx?scid=kb;ja;187745

参考にしてください。

投稿者:リックス

編集 履歴 (0)

xlSheet.Application.Visible = True の後で
xlSheet.Application.ScreenUpdating = True

VB6のときもそうでしたが、なんでxlsheetをいきなりVisible=Trueに
するのですかねぇ?
手順どおりなら、xlap→xlBook→xlsheetではなのかしらん?(現象とは
直接関係無いかもしれませんが)

それとVB6のときにアーリーバインド、レイトバインドともWithを使ったほうが
問題が少なかったように思うのですが...

あ、そういえば私がVB6のときこの問題に出くわしたときは確かWithEventsを
使うときれいに落ちてくれたような覚えがあります。というかExcel側で操作
されるという前提ならWithEventsのほうが良いですよ。(.netじゃ使えるのか
どうか知りませんが)

投稿者:Beatle

編集 履歴 (0)

手順どおりなら、xlap→xlBook→xlsheetではなのかしらん?(現象とは
直接関係無いかもしれませんが)
おっしゃるとおりですが、今問題にしている部分の改善方法が分かり難くなる事から、元のコードに追加する形にしました。

ご了承ください。

確かに、OLEオートメーション/COMは循環参照などに弱いので、このあたりの理解は無用のトラブルを減らす上で重要ですね。

[ メッセージ編集済み 編集者: リックス 編集日時 2003-08-18 14:07 ]

投稿者:リックス

編集 履歴 (0)

Beatleさんの書き込み (2003-08-18 13:44) より:

xlSheet.Application.Visible = True の後で

xlSheet.Application.ScreenUpdating = True

VB6のときもそうでしたが、なんでxlsheetをいきなりVisible=Trueに

するのですかねぇ?

手順どおりなら、xlap→xlBook→xlsheetではなのかしらん?(現象とは

直接関係無いかもしれませんが)

 手順としてsheet→book→appの順に表示しているのではなく、sheetを作成したappを、sheetから参照して表示させているのだから、かまわないのでは?

 で、元の質問はプログラムから終了させたときにエクセルのインスタンスが残る、という問題で、リックスさんの提示されたMSのページは「OLEオートメーションで起動したエクセルインスタンスを手動で終了させると(そのインスタンスが残るために)、次回起動時に正しく描画されない」という問題だと思うのですが、プログラム上で表示させてから終了させるとインスタンスが解放されるのでしょうか?

投稿者:Jitta

編集 履歴 (0)

こんにちは。

すみません。私の方法では現象は改善しませんでした。

表面的には同じEXCELのプロセスが残留する現象だったのですが、
想定していた障害とは違っていました。

未確認で返答してしまい失礼しました。

問題の挙動を見ていると、GC絡みの問題のように感じですね。

投稿者:リックス

編集 履歴 (0)

「[ASP.NET]EXCELが終了しない」
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=3343&forum=7

「やっぱりわからないGCの動作」
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=2904&forum=7

「VB.NETでEXCELが終了しない。」
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=4524&forum=7

「続Excelが終了できない」
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=3895&forum=7

 ちなみに、エクセルを起動したプログラムを終了すれば、エクセルのインスタンスも消えると思います。
[ メッセージ編集済み 編集者: Jitta 編集日時 2003-08-18 18:56 ]

投稿者:Jitta

編集 履歴 (0)

皆様有り難うございます。
返信が遅れ、大変申し訳ございません。
色々試している最中です・・・

引用:---------------------------------------------------------------
meiさん
SaveAsで失敗している訳じゃないですよね?
--------------------------------------------------------------------
Save無しで実行後も状況は変わりませんでした。

引用:---------------------------------------------------------------
リックスさん
xlSheet.Application.Visible = True の後で
xlSheet.Application.ScreenUpdating = True
--------------------------------------------------------------------
上記行を追加後も状況は変わりませんでした。

引用:---------------------------------------------------------------
takiraさん
xlSheet.Application.Visible = True
こいつ外すとどうなりますか?
--------------------------------------------------------------------
そうなんですよ。VB6.0でも同様の悩みがあったような・・・
上記行を削除後に実行でも状況は変わりませんでした。

引用:---------------------------------------------------------------
Jittaさん
「[ASP.NET]EXCELが終了しない」
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=3343&forum=7

おくちnさん
WebConfigに追加した

がいけなかったみたいです。

当初、EXCELオブジェクトがNEW出来なかったので、上記の一行を追加したのですが。
EXCELオブジェクトをコンポーネントサービスもしくは、DCOMCNFGでセキュリティの
起動の許可に、ASPNETユーザーを追加すればOKでした。

--------------------------------------------------------------------
申し訳ございません。過去履歴を検索しきれませんでした。
上記を試す前に、VB.NETで実行してみたところ(VB.NETは初めてですが・・)プロセス
は残っておりませんでした。「VB.NET」では成功です!
あとは、ASP.NETでどうなるか・・・・
引き続きやってみます。

投稿者:takahon

編集 履歴 (0)

次のように入れ替えるだけでも、効果がありそうに思えるのは、安易でしょうか?

xlSheet.SaveAs("C:\aaa.xls")
xlBook.Close()
xlApp.Quit()
xlSheet = Nothing
xlBook = Nothing
xlApp = Nothing

xlSheet.SaveAs("C:\aaa.xls")
xlSheet = Nothing
xlBook.Close()
xlBook = Nothing
xlApp.Quit()
xlApp = Nothing

投稿者:MyTime

編集 履歴 (0)

たくさんの返信有り難うございます。
過去レス及び皆様の意見を参考にし、無事プロセスが終了しました。

Sub TestExcel()
Dim xlApp As New Excel.Application
Dim xlBooks As Excel.Workbooks = xlApp.Workbooks
Dim xlBook As Excel.Workbook = xlBooks.Open("c:\aaa.xls")

    xlApp.DisplayAlerts = False
    Dim xlSheets As Excel.Sheets = xlBook.Worksheets
    Dim xlSheet As Excel.Worksheet = CType(xlSheets(1), Excel.Worksheet)
    Dim xlRange As Excel.Range = xlSheet.Cells
    xlRange(2, 2) = "This is column B row 2"
    xlBook.Save()
    xlBook.Close(False)
    xlApp.DisplayAlerts = True

    xlApp.Quit()
    System.Runtime.InteropServices.Marshal.ReleaseComObject(xlRange)
    System.Runtime.InteropServices.Marshal.ReleaseComObject(xlSheet)
    System.Runtime.InteropServices.Marshal.ReleaseComObject(xlSheets)
    System.Runtime.InteropServices.Marshal.ReleaseComObject(xlBook)
    System.Runtime.InteropServices.Marshal.ReleaseComObject(xlBooks)
    System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp)

End Sub

投稿者:takahon

編集 履歴 (0)
ウォッチ

この質問への回答やコメントをメールでお知らせします。