- ベストアンサー
EXCELのプロセスが残ってしまう現象について
- EXCELのプロセスが残ってしまう現象が発生しており、特定の記述が原因ではないかと考えています。
- 発注先コードが異なる場合にシートを分けるような記述を行っていますが、その際にプロセスが残る現象が起こっています。
- どのような記述がプロセスを残してしまう原因になっているのか教えてください。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
2行目消し忘れてた。。。いきなり解放したら命令できないよね。 *********************************************************************** xlSheet = xlSheets.Item(1) 'シートの選択じゃなくて参照!選択は xlSheet.Select() 'System.Runtime.InteropServices.Marshal.ReleaseComObject(xlSheet) '間違い xlSheet2 = xlSheets.Item(2) '同時に複数のシートを参照&解放できないのでもう1つ変数が必要 xlSheet.Copy(After:=xlSheet2) 'シートのコピー System.Runtime.InteropServices.Marshal.ReleaseComObject(xlSheet2) '使い終わったらすぐ解放しておく方が安全 System.Runtime.InteropServices.Marshal.ReleaseComObject(xlSheet) '次でシート3を参照するので必須 xlSheet = xlSheets.Item(3) 'シートを参照 xlSheet.Name = "YY" 'シートに名前を付ける ***********************************************************************
その他の回答 (3)
- MARU4812
- ベストアンサー率43% (196/452)
あまりに指摘事項が多いから、全体を修正しようと 思って見直したら、 SANA_999 って人とコードが同じ。 http://qanda.rakuten.ne.jp/qa7153396.html しかも、 > 確かに、xlRange.Value = strDat は外でしたね! は修正されていない。 ダメ過ぎて「プログラムしない方がいいよ」と アドバイスしたくなるほどです。 この質問に書いたコードは一体何ですか??? 他人のコピペ? 過去にだめすぎる質問して名前を変えた? 修正する気が無い?
- MARU4812
- ベストアンサー率43% (196/452)
>Dim xlSheet2 As Excel.Worksheet = xlBook.Worksheets(1) >xlSheet.Copy(After:=xlSheet2) 'シートのコピー > >のようにしてみてはどうでしょうか。 Worksheets オブジェクトが解放されないコードですね。 絶対に解放されるコードは、 Dim xlSheet2 As Excel.Worksheet = xlSheets.Item(1) xlSheet.Copy(After:=xlSheet2) 'シートのコピー です。 使いまわすなら、 *********************************************************************** xlSheet = xlSheets.Item(1) 'シートの選択じゃなくて参照!選択は xlSheet.Select() System.Runtime.InteropServices.Marshal.ReleaseComObject(xlSheet) '使い終わったら解放 xlSheet2 = xlSheets.Item(2) '同時に複数のシートを参照&解放できないのでもう1つ変数が必要 xlSheet.Copy(After:=xlSheet2) 'シートのコピー System.Runtime.InteropServices.Marshal.ReleaseComObject(xlSheet2) '使い終わったらすぐ解放しておく方が安全 System.Runtime.InteropServices.Marshal.ReleaseComObject(xlSheet) '次でシート3を参照するので必須 xlSheet = xlSheets.Item(3) 'シートを参照 xlSheet.Name = "YY" 'シートに名前を付ける ***********************************************************************
- MARU4812
- ベストアンサー率43% (196/452)
前の質問時に指摘された項目が全く修正されていないようですが? http://qanda.rakuten.ne.jp/qa7187674.html >xlSheet.Copy(After:=xlSheet2) 'シートのコピー > >のようにしてみてはどうでしょうか。 > 'シートのコピー > xlSheet.Copy(After:=xlBook.Worksheets(1)) と > xlSheet.Copy(After:=xlBook.Worksheets(2)) 'シートのコピー どちらも修正されていません。 ついでに言えば、ReleaseComObject は使ったオブジェクト 全てに適用しないといけません。 変数に対して1回実行するのではありません。 ある変数で「シート1」を参照し、 同じ変数で「シート2」を参照する場合は、 「シート2」を参照する前に、「シート1」を参照 している状態で ReleaseComObject します。 Excel 側で外部から参照されている事を覚える為に フラグ(実際は複数から参照がありえるのでカウンタ)が 立つのですが、ReleaseComObject は、それを降ろす命令 です。「シート1」が参照された時点で「シート1のフラグ」 が立ちます。「シート2」が参照された時点で「シート2の フラグ」が立ちます。 それぞれのフラグを降ろす命令が必要です。 同じシートを2回参照したら2回降ろす命令が必要です。 >GC.Collect は VB 側のメモリ解放なので、本質的には関係ありません。 Excel 側の問題です。(※だから残るのは Excel.EXE で、 VB の実行が終わっても残る。) >Dim xlSheet As Excel.Worksheet = CType(xlSheets.Item(1), Excel.Worksheet) > >'シートの選択 >xlSheet = xlSheets.Item(1) 上記で2回参照してますね。 …もともと無駄なコードですが。 切り分けまでされているようですが、問題なのは、 解放漏れとされるコードがあってもプロセスが残らない場合が あるのです。 GC.Collect で改善されたのも「たまたま」だと思ってください。 この辺りは色々と議論されていますが、結論は出ていません。 Excel からの操作自体がブラックボックスが多いのです。 私は「確実派」なので、全てのオブジェクトに解放命令を 出す事を勧めています。結果として解放漏れを起こした事は ありません。 >「Application」と「Workbooks」だけ http://www.asahi-net.or.jp/~ef2o-inue/vbnet/sub13_03_040.html という分析もあります。 ただ、単純なテストでは同じような結果が出るのですが、 コードを複雑にしていった時に、何かのタイミングでプロセス が残り始めるような現象も経験しており、そこから見直しとか なってしまうと工数の無駄なので、私はセル単位まで全ての オブジェクトを解放するコードを最初から書くようにしています。
お礼
ソースまで記述して頂き、本当にありがとうございました。 教えて頂いた内容をもとに実行したところ、問題なくプロセスが 終了しました。 ありがとうございました!!