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

Excelが(シート追加で)実行プロセス解放せず

環境/言語:[Win2000SP4, Office2000SP3, VB.NET2003]
分類:[.NET]

実行例-------------------------------------------------------------
Dim xlFilePath As String
Dim xlApp As Excel.Application
Dim xlBooks As Excel.Workbooks
Dim xlBook As Excel.Workbook
Dim xlSheets As Excel.Sheets
Dim xlSheet As Excel.Worksheet

xlApp = New Excel.Application
xlApp.Visible = True
xlBooks = xlApp.Workbooks
xlBook = xlBooks.Open(xlFilePath)
xlSheets = xlBook.Worksheets
xlSheet = xlBook.ActiveSheet

'利用者数分の新規シート追加、ただし定型シートが1ページに存在済み
If max_sheet - 1 > 0 Then
xlSheets.Add(Count:=max_sheet - 1, after:=xlSheets(1))
End If


xlApp.DisplayAlerts = False '更新・上書き問い合わせダイアログ表示しない
xlApp.ActiveWorkbook.SaveAs(xlFilePath) 'ファイル保存

ReleaseCOM(xlSheet)
ReleaseCOM(xlSheets)
xlBook.Close(False)
ReleaseCOM(xlBook)
xlBooks.Close()
ReleaseCOM(xlBooks)
xlApp.Quit()
ReleaseCOM(xlApp)
System.Threading.Thread.Sleep(5000)


'システム終了後もExcel等が終了しない(実行プロセスに残る)…終了させるモジュール
'COMプロセス解放
Public Sub ReleaseCOM(ByVal o As Object)
Try
System.Runtime.InteropServices.Marshal.ReleaseComObject(o)
Catch
Finally
o = Nothing
End Try
End Sub
-------------------------------------------------------------------

質問
xlSheets.Add(Count:=max_sheet - 1, after:=xlSheets(1))
上記例より、xlSheets.Add(〜) を実行して、シート自動追加を
試みると、Excel実行プロセスは解放されず、
xlSheets.Add(〜) を実行しなければ無事解放されます。
シート自動追加のケースで、何か方策ありませんでしょうか。
> シート自動追加を試みると、Excel実行プロセスは解放されず、
>xlSheets.Add(〜) を実行しなければ無事解放されます。



> xlSheets.Add(Count:=max_sheet - 1, after:=xlSheets(1))



after:=xlSheets(1)

で COM オブジェクトの参照が発生していますが、それを解放していません。

>何か方策ありませんでしょうか。

漏れなく、COM オブジェクトの参照を解放すればよいです。
2005/07/14(Thu) 14:28:22 編集(投稿者)

> xlSheet = xlBook.ActiveSheet
Excelの[マクロの記録]では、「Active/Selection系のメンバ」を多用した
コードが生成されますが、それだと無駄が多く、処理が曖昧になりがちですので、
特に理由が無い限りは、ActiveSheet等の使用を控えた方が良いでしょう。

> xlSheets.Add(Count:=max_sheet - 1, after:=xlSheets(1))
Sheets.Add()は戻り値のあるメソッドであり、
追加されたシート(これもCOMのオブジェクト)を返します。
また、xlSheets(1) についても、解放の必要があるでしょう。

> xlApp.ActiveWorkbook.SaveAs(xlFilePath) 'ファイル保存
上記ActiveWorkbookプロパティが返すオブジェクトについても同様です。
一度変数に受け、SaveAs完了後に解放するようにしてください。

さらに言えば、今回保存するのは、『xlBook』というオブジェクトなので、
これも「Active系のメンバ」を使って処理するのではなく、
xlBook.SaveAs(xlFilePath)
というコードにした方が、良いのですけれどね。


…という事で、こんな感じかな。

'    :
'    :
xlSheets = xlBook.Worksheets
xlSheet = xlSheets(1)
Dim NewSheet As Object = xlSheets.Add(Count:=4, after:=xlSheet)
If System.Runtime.InteropServices.Marshal.IsComObject(NewSheet) Then
  ReleaseCOM(NewSheet)
End If
xlApp.DisplayAlerts = False
xlBook.SaveAs(xlFilePath)
ReleaseCOM(xlSheet)
ReleaseCOM(xlSheets)
'    :
'    :
■No11796に返信(魔界の仮面弁士さんの記事)
> 2005/07/14(Thu) 14:28:22 編集(投稿者)

魔界の仮面弁士さん、下記の記述で「シート自動追加」については、
解決しました。 ありがとうございました。
また次回より突っ込んだ質問させていただきますので、
お願いします。

Sample---------------------------------------------------------------
> xlSheets = xlBook.Worksheets
> xlSheet = xlSheets(1)
> Dim NewSheet As Object = xlSheets.Add(Count:=4, after:=xlSheet)
> If System.Runtime.InteropServices.Marshal.IsComObject(NewSheet) Then
>   ReleaseCOM(NewSheet)
> End If
> xlApp.DisplayAlerts = False
> xlBook.SaveAs(xlFilePath)
> ReleaseCOM(xlSheet)
> ReleaseCOM(xlSheets)
----------------------------------------------------------------------
解決済み!

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