VB.NET から Excel の COM オブジェクトを操作する際に
COM オブジェクトを適切に解放しないと,Excel のプロセスが正しく終了しない。 正しく終了させるにはCOMオブジェクトを全て解放すること!
↓↓↓ 以下サンプル ↓↓↓
'名前空間Imports System.Data
Imports System.IO
Imports Excel
Public Class Form1
Dim xlApp
As Excel.Application
'「New」宣言してしまうとこの時点でエクセルが起動してしまうので注意。 Dim xlBooks
As Excel.Workbooks
Dim xlBook
As Excel.Workbook
Dim xlSheets
As Excel.Sheets
Dim xlSheet
As Excel.Worksheet
Dim xlCells
As Excel.Range
Private Sub btnINSERT_Click(
ByVal sender
As Object,
ByVal e
As System.EventArgs)
Handles btnINSERT.Click
Dim i
As Long i = 0
'Excelから読み込みxlApp =
CreateObject(
"Excel.Application")
xlBooks = xlApp.Workbooks
xlBook = xlBooks.Open(
"***.xls")
xlSheets = xlBook.Worksheets
xlSheet = xlSheets.Item(1)
xlApp.Visible =
False xlCells = xlSheet.Cells
Do Until i >= 3
i = i + 1
ListBox1.Items.Add(xlCells(i, 1).value & " " & xlCells(i, 2).value)
Loop 'COMオブジェクトの解放 System.Runtime.InteropServices.Marshal.FinalReleaseComObject(xlCells)
xlCells =
Nothing System.Runtime.InteropServices.Marshal.FinalReleaseComObject(xlSheets)
xlSheets =
Nothing System.Runtime.InteropServices.Marshal.FinalReleaseComObject(xlSheet)
xlSheet =
Nothing xlBook.Close()
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(xlBook)
xlBook =
Nothing System.Runtime.InteropServices.Marshal.FinalReleaseComObject(xlBooks)
xlBooks =
Nothing xlApp.DisplayAlerts =
False xlApp.Quit()
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(xlApp)
xlApp =
Nothing 'ガベージ・コレクタを明示的に動作 GC.Collect()
End Sub<< 解 説 >>
■COMオブジェクト
[.]を2つ連続で使用したら基本的に解放できない。
[.]を2つ使用した時点で暗黙的に参照が追加されているから解放できなくなる。
例) 誤:xlSheet.Item(1).Name="01"
正:xlSheet=xlSheet.Item(1) xlSheet.Name="01"
Rangeオブジェクトは引数を取らない仕様になっている。
例) 誤:xlRange=xlSheet.Range("A18:F52")
正:R1=DirectCast(xlCells(18,1),Excel.Range)
R2=DirectCast(xlCells(52,6),Excel.Range)
xlRange=xlSheet.Range(R1,R2)
■COMオブジェクトの解放
COMオブジェクトを使用する場合に一番注意しなければいけないのが参照カウントの解放。この解放がされていないと意図したタイミングにプロセスが解放されなくなってしまう。
参照カウントを解放するには、System.Runtime.InteropServices.MarshalクラスのFinalReleaseComObjectメソッドを実行するだけ。
FinalReleaseComObjectは.Net Framework 2.0から追加された機能で、一度の呼び出しのみで参照カウントを 0 に設定してくれる。
■ガベージ・コレクタとは・・・
自動的なメモリ解放を行う機構のこと。解放する行為のことをガベージ・コレクションという。
■ガベージ・コレクションで行うこと・・・
プログラムの実行中に使用されなくなったメモリを自動的に見つけ出し、再利用できるようにする。
通常の機能はランタイム・エンジンやライブラリにより実装される。省略して単に「GC」と呼ばれることもある。
GC.Collect()のタイミングはボタン操作の最後にした方がいいかもしれない。
(Functionでやっても動作しなかった)