DOBON.NET DOBON.NETプログラミング掲示板過去ログ

エクセルの解放

  • 題名: エクセルの解放
  • 著者: 歩野
  • 日時: 2012/09/20 11:59:09
  • ID: 30947
  • この記事の返信元:
    • (なし)
  • この記事への返信:
  • ツリーを表示
環境/言語:[winXP vb.net(2010) excel2000]
分類:[.NET]

はじめまして、あちこちで調べたりこちらの過去ログを参照して下記のように記述してデバッグしたのですがエクセルが解放されません。
内容を削りつつ確認した所、sheet関係が怪しいのかな?と素人考えしてみたのですが…
解決方法がどうにも出てきません、御教授願います。


Private Sub Form2_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load

Dim oXL As New Excel.Application

Try
Dim oWBs As Excel.Workbooks = oXL.Workbooks
Dim FileName As String = "C:\test.xls" 'ファイル名はフルパス指定

Try
Dim oWB As Excel.Workbook = oWBs.Open(FileName)

Try
Dim oSheet As Excel.Worksheet = DirectCast(oWB.Worksheets("基準条件"), Excel.Worksheet) 'シート指定は””の中へ
oXL.Visible = False ' Excel を非表示にする

Try
Dim sCellVal As String
Dim i As Integer
Dim rng As Excel.Range ' Range オブジェクト

Try
i = 0
For i = 5 To 12
rng = oSheet.Range("b" & i)
sCellVal = rng.Text.ToString()
ComboBox1.Items.Add(sCellVal) ' セルの内容をcomboboxへ格納

System.Runtime.InteropServices.Marshal.ReleaseComObject(rng)
Next
Finally
If Not rng Is Nothing Then
System.Runtime.InteropServices.Marshal.ReleaseComObject(rng)
End If
End Try
Finally
If Not oSheet Is Nothing Then
System.Runtime.InteropServices.Marshal.ReleaseComObject(oSheet)
End If
End Try
Finally
If Not oWB Is Nothing Then
System.Runtime.InteropServices.Marshal.ReleaseComObject(oWB)
End If
End Try
Finally
If Not oWBs Is Nothing Then
System.Runtime.InteropServices.Marshal.ReleaseComObject(oWBs)
End If
End Try
Finally
oXL.Quit() ' Excel を終了する
If Not oXL Is Nothing Then
System.Runtime.InteropServices.Marshal.ReleaseComObject(oXL)
End If
End Try
End Sub

やりたい事は、フォームを開いた時に指定xlsからコンボボックスへデータを放り込むという物です。
宜しくお願いします。
予想ですが、

Dim oSheet As Excel.Worksheet = DirectCast(oWB.Worksheets("基準条件"), Excel.Worksheet) 'シート指定は””の中へ



oWB.Worksheets

の解放わすれじゃないかなーと思います。
■No30948に返信(おのでらさんの記事)

おのでらさん、ありがとうございます。

> oWB.Worksheets

>
> の解放わすれじゃないかなーと思います。

との事で、「さて、どこで指定すれば?」と試行錯誤した結果元データを弄りすぎて収拾がつかなくなってしまい…
そこで解放の参考にさせて頂いたサイト(http://jeanne.wankuma.com/tips/vb.net/programming/releasecom.html)よりもう一度コピーして色々した所、参考した時からすでにいくつか間違えていた事が判明…
とりあえずそれを直しつつ再度試行錯誤した結果、何故か動いてしまいました。
以下そのコードです。

Private Sub Form2_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Dim oXL As New Excel.Application() '--解放対象【oXL】
Dim oWBs As Excel.Workbooks = oXL.Workbooks '--解放対象【oWBs】
Dim FileName As String = "C:\test.xls" 'ファイル名はフルパス指定
Try
Dim oWB As Excel.Workbook = oWBs.Open(FileName) '--解放対象【oWB】
Try
Dim oSheets As Excel.Sheets = oWB.Worksheets '--解放対象【oSheets】
Try
Dim oSheet As Excel.Worksheet = DirectCast(oSheets("基準条件"), Excel.Worksheet) 'シート指定は””の中へ--解放対象【oSheet】
Try
Dim sCellVal As String
Dim i As Integer
Dim rng As Excel.Range ' Range オブジェクト--解放対象【rng】
Try
i = 0
For i = 5 To 12
rng = oSheet.Range("b" & i)
sCellVal = rng.Text.ToString()
ComboBox1.Items.Add(sCellVal) ' セルの内容をcomboboxへ格納
System.Runtime.InteropServices.Marshal.ReleaseComObject(rng) '【rng】はfor〜next単位で解放必要?
Next
Finally
If Not oSheet Is Nothing Then
System.Runtime.InteropServices.Marshal.ReleaseComObject(oSheet) '【oSheet】解放。【rng】は上で解放済み?なので記載不要?
End If
End Try
Finally
If Not oSheets Is Nothing Then
System.Runtime.InteropServices.Marshal.ReleaseComObject(oSheets) '【oSheets】解放。
End If
End Try
Finally
If Not oWB Is Nothing Then
Try
oWB.Close() 'Workbookを閉じる
Finally
System.Runtime.InteropServices.Marshal.ReleaseComObject(oWB) '【oWB】解放。
End Try
End If
End Try
Finally
If Not oWBs Is Nothing Then
System.Runtime.InteropServices.Marshal.ReleaseComObject(oWBs) '【oWBs】解放。
End If
End Try
Finally
If Not oXL Is Nothing Then
Try
oXL.Quit() 'Excelを閉じる
Finally
System.Runtime.InteropServices.Marshal.ReleaseComObject(oXL) '【oXL】解放。
End Try
End If
End Try
End Sub

で、動いたのは良いのですが疑問点が1つ。
解放は指定した順番の逆で〜と、どこかで読んだのです。(例:1,2,3の場合3,2,1と解放)
で、その時にfor〜nextで使う時はその都度解放と。それでnextの前に一度【rng】を解放しているのですが…
この場合、最後で解放しちゃってるので他の解放みたいにFinaly以下に含めなくても良い。ということでしょうか?
動いたものの、何か釈然としないのです…
■No30950に返信(歩野さんの記事)
> で、その時にfor〜nextで使う時はその都度解放と。それでnextの前に一度【rng】を解放しているのですが…
> この場合、最後で解放しちゃってるので他の解放みたいにFinaly以下に含めなくても良い。ということでしょうか?
Forの次で毎回rngに新しいRangeオブジェクトを設定し前のRange情報がなくなってしまうので、Nextの前で解放をしているということでしょう。もしFinallyで行うならList(Of Object)を使ってRangeオブジェクトをNextの手前でAddしておいて、FinallyでループしてReleaseすれば他と同じように処理することが可能です。
  • 題名: Re[4]: エクセルの解放
  • 著者: 歩野
  • 日時: 2012/09/21 8:50:02
  • ID: 30958
  • この記事の返信元:
  • この記事への返信:
    • (なし)
  • ツリーを表示
■No30952に返信(shuさんの記事)
> ■No30950に返信(歩野さんの記事)
>>で、その時にfor〜nextで使う時はその都度解放と。それでnextの前に一度【rng】を解放しているのですが…
>>この場合、最後で解放しちゃってるので他の解放みたいにFinaly以下に含めなくても良い。ということでしょうか?
> Forの次で毎回rngに新しいRangeオブジェクトを設定し前のRange情報がなくなってしまうので、Nextの前で解放をしているということでしょう。もしFinallyで行うならList(Of Object)を使ってRangeオブジェクトをNextの手前でAddしておいて、FinallyでループしてReleaseすれば他と同じように処理することが可能です。

shuさん、ありがとうございます。
try〜finalyや解放に関しては雰囲気で何となく「あ〜、そういうものか」的に理解してた感じでしたが…
おかげ様でそれなりに理解できたような気がします。(「完璧に理解できました!」と言えないのが何ともはや…ですが)
また他の事でお世話になるかと思いますが、その時もよろしくお願いしますね。
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板