投稿日 | : 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」が悪さをしてるのでは
> ないかってことです。
ループを行うこと自体には、終了/解放処理の妨げにはなりません。
それでも問題が起きているのだとすれば、その使い方が間違っているのだと思いますよ。