VB6.0用掲示板の過去のログ(No.2)−VBレスキュー(花ちゃん)
[記事リスト] [新規投稿] [新着記事] [ワード検索] [管理用]

投稿日: 2007/07/29(Sun) 22:13
投稿者魔界の仮面弁士
Eメール
URL
タイトルRe^5: エクセルがタスクマネージャに残ってしまいます。

> この処理順番は本サイト「http://hanatyan.sakura.ne.jp/vbhlp/excelframe.htm」で
> 紹介されているものをそのままなのですがダメなのかな(ノ_`)
いえ、「そのまま」にはなっていないと思いますよ…。

正直なところ、そこに書かれた手順も、あまり好ましくは無いと思います。
Sheet 解放 → Book 解放 → Quit → Application 解放の順が推奨されるでしょう。

ただ、(VB6 なら)解放順に関してはある程度融通が利くので、そこに書かれた手順でも
さほど問題はないと思います。しかし、のぞみさんが行っているような手順、すなわち、
下位のオブジェクトを処理中に、上位のオブジェクトを Close / Quit したり、あるいは
Close / Quit 処理後に、それらのオブジェクトを操作するのは問題があるということです。


> ★端折って簡潔に書かないとかなり多くなるのと、
(中略)
> 最小限エリアで解決して行こうと思ったからです。
もちろん、コードが多いならば、最低限の長さまで縮めることは確かに必要なのですが、
肝心な部分が端折られた、部分的な投稿にはならないようにして欲しいのです。

少なくとも、For Each しただけ(ループ内には 1 行もコードを書かない)ならば、
問題は出ません。ですから、ループ処理の中で「やってはいけないこと」を
書いてしまっている可能性が高いと予想されるのです。

重要な部分は端折らずに投稿してください。そうでないと間違いを指摘できません。

それに、もし同一のコードを使っても、のぞみさんの環境でしか問題が発生しないのなら、
それは「プログラム上のミス」ではなく、「環境自体に不具合がある」のかも知れません。
その可能性を探る意味でも、省略されていない(かつ、長くない)コードが必要なのです。


> 【終了確認パーン1】
> Public Sub SheetCheck()      '【終了処理をFor処理の前置きの場合】・・・正常終了
> 'ファイルオープンして別のプロシージャーに入ったらすぐ終了して試してみる。
>  xlApp.Quit
>  Set xlSheet = Nothing
>  Set xlBook = Nothing
>  Set xlApp = Nothing    '←実行した時点で正常にEXCEL.EXE終了
>   For Each ObjSheet In xlBook.Worksheets
>    '処理
>   Next
> End Sub
このコードには、2 つの問題があるように見えます。

まず 1 つめに…… Excel が終了するかどうか以前の問題として、xlBook が Nothing の
状態で xlBook.Worksheets を実行すれば、その時点で処理が失敗するはずです。
もし、事後の処理でエラー等が発生していないというのであれば、
 (a) On Error を使って、実行時エラーを握りつぶしている。
 (b) 変数宣言時に New キーワードを補っている。
のいずれかの状態だと思いますし、その場合、a,b の処理には問題があるでしょう。
(逆に、エラーが起きているなら、事後にそのような処理を書く事自体が問題です)


2 つめの問題点は、処理手順自体の間違いです。そもそも xlApp.Quit させた後で、
他の Excel オブジェクトを操作しようとすること自体、処理としては NG でしょう。

Quit は、Excel アプリ本体を終了させる命令ですから、Quit を呼び出した後では、
一切、Excel 系のオブジェクトを操作すべきではありません。


> 【終了確認パーン2】
> Public Sub SheetCheck()      '【終了処理をFor処理の後置きの場合】・・・NG
> 'ファイルオープンして別のプロシージャーのFor文に入ったらすぐ終了して試してみまる
>  For Each ObjSheet In xlBook.Worksheets
>    xlApp.Quit
すでに先に回答したことの繰り返しになりますが、マズイです。

For Each 中は、列挙オブジェクトが保持された状態となります。安全のため、
Quit メソッドを呼ぶなら、Exit For などで ループを抜けた後に行いましょう。


For Each ではなく For であれば、列挙オブジェクトを使用しないので、
オブジェクトが保持された状態にはならないでしょうけれど、その場合でも、ループ中に
> xlApp.Quit
> Set xlSheet = Nothing
> Set xlBook = Nothing
> Set xlApp = Nothing・・・この処理を実行してもプロセスにEXCEL.EXEが残ります
> '処理
のようなコードを記述することには問題があります(「処理」部で何をさせるにしても)。

1回目のループで終了処理を行ったのなら、2回目のループでは何を終了させるのでしょう?



> ここで分かったこと、「For Each ObjSheet In xlBook.Worksheets」が悪さをしてるのでは
> ないかってことです。
ループを行うこと自体には、終了/解放処理の妨げにはなりません。
それでも問題が起きているのだとすれば、その使い方が間違っているのだと思いますよ。


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

- 返信フォーム (この記事に返信する場合は下記フォームから投稿して下さい)

- VBレスキュー(花ちゃん) - - Web Forum -