タイトル | : Re: 掛線を書いて、EXCELを終了 |
記事No | : 1000 |
投稿日 | : 2004/07/22(Thu) 01:49 |
投稿者 | : 魔界の仮面弁士 |
1000番!
> '現在、アクティブなシートを取得する > objsheet = objApp.ActiveSheet 今回の「プロセスが残る問題」とは、直接関係ありませんが、 ワークシートは、「Excelアプリ」ではなく、「ワークブック」に所属していますので、 「objsheet = objbook.ActiveSheet」の方が適切かと思います。
# ただし、objApp.ActiveSheet の場合は、objbook 以外のシートが取得される可能性も # ありえますので、厳密に言えば、objbook.ActiveSheet とは別の意味となりますけれどね。
なお、ActiveSheetが返すシートは、ワークシートとは限りませんので(チャートシートの可能性がある)、 シート名等が分かっている場合は、objbook.Worksheets("Sheet1") などの方が良いかも知れません。
> '掛線を引く > objBorders = _ > objsheet.Cells(1, 1).Borders > objBorders.LineStyle = Excel.XlLineStyle.xlContinuous 原因はここです。ReleaseComObjectされていないオブジェクトがありますよ。
先の分も含めて修正すると、このようになります。 なお、Option Strict Onに備え、"As Object"な物は、DirectCastでキャストしてあります。
Dim objCells As Excel.Range Dim objRange As Excel.Range objsheet = DirectCast(objbook.ActiveSheet, Excel.Worksheet) objCells = objsheet.Cells objRange = DirectCast(objCells._Default(1, 1), Excel.Range) objBorders = objRange.Borders objBorders.LineStyle = Excel.XlLineStyle.xlContinuous System.Runtime.InteropServices.Marshal.ReleaseComObject(objCells) objCells = Nothing System.Runtime.InteropServices.Marshal.ReleaseComObject(objRange) objRange = Nothing
このコードであれば、プロセスが残る事はありませんでした。(Excel 2002 + VB.NET 2002)
この時、『Cellsプロパティ』の動作に注意してください。もしも上記を、 Dim objRange As Excel.Range objsheet = DirectCast(objbook.ActiveSheet, Excel.Worksheet) objRange = DirectCast(objsheet.Cells(1, 1), Excel.Range) objBorders = objRange.Borders objBorders.LineStyle = Excel.XlLineStyle.xlContinuous System.Runtime.InteropServices.Marshal.ReleaseComObject(objRange) objRange = Nothing にした場合は、プロセスが残る結果となりました。
# ただし、 # objRange = DirectCast(objsheet.Cells(1, 1), Excel.Range) # ではなく、 # objRange = objsheet.Range("A1") # ならば、プロセスは残りません。
さて、Cellsプロパティについてもう少し書いておきます。
実は、 objsheet.Cells(1, 1) というのは、 objsheet.Cells._Default(1, 1) の省略表記となります。
つまり、Cells(1, 1) という操作の場合、 objRange = objsheet.Cells(1, 1) と書くのではなく、 objCells = objsheet.Cells objRange = DirectCast(objCells(1, 1), Excel.Range) のように、.Cells が返すRangeオブジェクトと、 ._Default が返すRangeオブジェクトとは、別々にわけて変数に取り、 それぞれを ReleaseComObject しないといけないわけです。
これは、 objBook = objApp.Workbooks(1) ではなく、 objBooks = objApp.Workbooks objBook = objBooks._Default(1) 'または、「objBook = objBooks(1)」 などと管理しなければならないのと、同じ理由による物です。
> 'ガーベジコレクト起動 > GC.Collect() これを呼んだとしても、Excelのプロセスが残ってしまう件の解決とはなりません。
COMコンポーネントのメモリ管理と、.NETのメモリ管理は別物ですから、 "garbage collect"したからといって、Excelが解放されるという保障は無いのです。
根本的な解決は、「全てのCOMオブジェクトを ReleaseComObject する事」となります。 hhttp://blogs.users.gr.jp/hidori/archive/2004/01/26/916.aspx
|