• ベストアンサー

.NET2008 VC# から Excel2003 の Comオブジェクトが開放されない

こんにちは。 Visual C# .NET 2008 から、Excel2003をCOMオブジェクトとして操作しようとしたのですが、プロセスが解放されずに残っています。 (同じような質問や情報がWEB上に沢山あったのですが、いくら単純化しても解決しないため、質問しました。) 以下、ソースの抜粋です。 ----------------------------------------------- using Excel = Microsoft.Office.Interop.Excel; ~~~~ 省略 ~~~~ 01: Excel.Application exApp = null; 02: Excel.Workbooks workbooks = null; 03: 04: exApp = new Excel.Application(); *1 05: workbooks = exApp.Workbooks; 06: 07: workbooks.Close(); *2 08: exApp.Quit(); 09: 10: System.Runtime.InteropServices.Marshal.ReleaseComObject(workbooks); 11: System.Runtime.InteropServices.Marshal.ReleaseComObject(exApp); ~~~~省略~~~~ *1 で、EXCEL.EXE プロセスが起動しています。 *2 は追加したり消したりしてみましたが、結果は変わりませんでした。 05,07,10行目を削除すると、EXCEL.EXE プロセスは11行目で終了しました。 なお、関係あるのか分かりませんが、 OfficeLiveSignIn.exe がEXCEL.EXEプロセスと同時に立ち上がりますが、 11行目で終了します(EXCEL.EXEのみ残る。) 01行目からデバッグ実行しています。 単純なソースで恐縮ですが、初歩的な躓きなだけに、かなり困ってます。 よろしくお願いいたします。 環境:VS 2008.NET C# EXCEL 2003

質問者が選んだベストアンサー

  • ベストアンサー
  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.1

デバッガ自体が何か悪さしているのかも ・・・ 04と12ぐらいにブレークポイントを置いて このメソッドを呼び出します 04で停止した後に F5キーで続行した場合 プロセスが残りますか? デバッガ自体が 暗黙のObjectを何か参照してしまうのかも 当方の環境は C#2005 + Excel2003 で試してみました ^^ VB2005の場合 12行目あたりで System.GC.Collect(); を実行しておくと このメソッドを抜けたところで プロセスが消滅しましたよ C#の場合はデバッガでステップ実行すると効果は無いようですが ・・・

1year365
質問者

お礼

お礼、遅くなりました。 回答ありがとうございました。 色々と試したところ、デバッグ実行で、オブジェクトの内容をウォッチしていたのが原因のようでした。要注意ポイントですね。 なにより、使いづらいですね、この仕様。 別プロセスを用意して、そっちで処理を行い、エラーが出た場合は、そのプロセスごと殺してしまおうか、とも思ってます。 とにかく、助かりました。 ありがとうございました!

その他の回答 (2)

noname#259269
noname#259269
回答No.3

どこかで暗黙の参照を使ってしまっているとしか思えません。 すでにお調べになっているサイトに含まれているかもしれませんが、 .NET で Excel を使う場合には、このぐらい気を使う必要があるという事で、下記に参考サイトの一つを掲載しておきます。 http://jeanne.wankuma.com/tips/vb.net/programming/releasecom.html

1year365
質問者

お礼

#1の回答お礼に原因は記載いたしました。 デバッガーの変数ウォッチとは盲点でした。 ちなみに、ウォッチする変数を全部消しても、ステップ実行すると、プロセスが残ることもありました。 ありがとうございました!

回答No.2

これじゃないでしょうかね。 workbooks.Close(); 記述を省略しないで、ブックごとに Close をしてやる。 foreach (Excel.Workbook exBook in exBooks) { exBook.Close(false, Type.Missing, Type.Missing); } としてみるとか。 # Close メソッドの引数は適宜変えてください。

1year365
質問者

お礼

#1の回答お礼に原因は記載いたしました。 ご指摘の件は今回の原因では無かったようですが、チェックポイントとして勉強になりました。 ありがとうございました!

関連するQ&A

  • ASP.NET 2.0(VB)からEXCELオブジェクトを起動・操作し

    ASP.NET 2.0(VB)からEXCELオブジェクトを起動・操作し、クライアントにDLさせる仕組みを実装しようとしています。 DCOMコンポーネントにASP.NETユーザーを権限追加し、以下のコードでDLさせることはできたのですが、イベント発行からDLボックスが表示されるまでのレスポンスが60秒掛かってしまっています。 サーバーのタスクを監視してると (1)でEXCELプロセス起動までは、1~2秒後 (2)でファイル作成されるのが、60~70秒後 DCOMによるオートメーションではこんなに時間掛かるものなのでしょうか? デバッグ環境(XP)では、数秒で動作できているので オートメーション、もしくはActiveDirectoryに因果しているのかと思っています。 レスポンスを早くするなにか解決策などありましたらご教授願います。 また、以下のコードではリソースが解放されずにリークが発生してしまっています。 こちらもなにか解決案ありましたらよろしくお願いします。 [サーバー環境] OS:Server 2003、IIS:6.0、Excel 2002 Protected Sub Button_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button.Click Dim objExApp As Excel.Application objExApp=Server.CreateObject("Excel.Application")    '<----(1) objExApp.Application.DisplayAlerts=False Dim objExBooks As Excel.Workbooks objExBooks=objExApp.Workbooks Dim objExBook As Excel.Workbook objExBook=objExBooks.Add Dim objExSheets As Excel.Sheets objExSheets=objExBook.Sheets Dim objExSheet As Excel.Worksheet objExSheet=objExSheets(1) Dim objExCell As Excel.Range objExCell=objExSheet.Cells objExCell(1, 1)="EXCEL操作" objExBook.SaveAs(Server.MapPath("ファイル名"))    '<----(2) If Not objExCell Is Nothing Then System.Runtime.InteropServices.Marshal.ReleaseComObject(objExCell) objExCell=Nothing End If If Not objExSheet Is Nothing Then System.Runtime.InteropServices.Marshal.ReleaseComObject(objExSheet) objExSheet=Nothing End If If Not objExSheets Is Nothing Then System.Runtime.InteropServices.Marshal.ReleaseComObject(objExSheets) objExSheets=Nothing End If If Not objExBook Is Nothing Then objExBook.Close() System.Runtime.InteropServices.Marshal.ReleaseComObject(objExBook) objExBook=Nothing End If If Not objExBooks Is Nothing Then System.Runtime.InteropServices.Marshal.ReleaseComObject(objExBooks) objExBooks=Nothing End If If Not objExApp Is Nothing Then objExApp.Quit() System.Runtime.InteropServices.Marshal.ReleaseComObject(objExApp) objExApp=Nothing End If GC.Collect() System.Windows.Forms.Application.DoEvents() Response.Redirect("ページ名") End Sub

  • EXCELのプロセスに関して

    教えて下さい。 VB2008でEXCELを操作しようと考えていますが、以下のような記述をした場合、 EXCELのプロセスが残ってしまいます。 いろいろ調査し、いらない部分を削除した結果、以下のところまで絞込みを行い、 ****のところを削除した場合、問題なくプロセスは終了した為、****印の中の記述が 原因というところまで絞れました。 単純にブックの中のシートをコピーで追加しているだけですが、何がどのようにすれば プロセスは残らずに消えてくれるでしょうか。。。 よろしくお願いします。 《記述内容》 '既存のEXCELファイルを開く Dim xlFilePath As String = "C:\test.xls" '起動時の処理 Dim xlApp As New Excel.Application Dim xlBooks As Excel.Workbooks = xlApp.Workbooks Dim xlBook As Excel.Workbook = xlBooks.Open(xlFilePath) xlApp.Visible = True ' 確認のためExcelのウィンドウを表示する Dim xlSheets As Excel.Sheets = xlBook.Worksheets Dim xlSheet As Excel.Worksheet = CType(xlSheets.Item(1), Excel.Worksheet) ************************* xlSheet = xlSheets.Item(1) 'シートの選択 xlSheet.Copy(After:=xlBook.Worksheets(1)) 'シートのコピー xlSheet = xlSheets.Item(2) '再度シートを選択 xlSheet.Name = "zz" 'シートに名前を付ける ************************* xlBooks.Close() xlApp.DisplayAlerts = False xlApp.Quit() ' COM オブジェクトの解放 System.Runtime.InteropServices.Marshal.ReleaseComObject(xlBooks) System.Runtime.InteropServices.Marshal.ReleaseComObject(xlBook) System.Runtime.InteropServices.Marshal.ReleaseComObject(xlSheets) System.Runtime.InteropServices.Marshal.ReleaseComObject(xlSheet) ' Excel のプロセス終了 System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp)

  • VB2008でのExcelオブジェクトの宣言と解放

    下記のようなコードを書きました。 Public Sub XXXXXXXXXXX Dim xlApp As New Excel.Application Dim xlBook As Excel.Workbook Dim xlSheet As New Excel.Worksheet try xlApp = CreateObject("Excel.Application") xlApp.Workbooks.Open(Filename:=excelTempPath, UpdateLinks:=0) xlBook = DirectCast((xlApp.Workbooks.Open(excelTempPath)), Excel.Workbook) シートのコピー、削除など操作 xlBook.Close(SaveChanges:=True, Filename:=strExcelPath) xlApp.Quit() Finally MRComObject(xlSheet) MRComObject(xlBook) System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp) xlApp = Nothing End Try End Sub Public Sub MRComObject(Of T As Class)(ByRef objCom As T, Optional ByVal force As Boolean = False) If objCom Is Nothing Then Return End If Try If System.Runtime.InteropServices.Marshal.IsComObject(objCom) Then If force Then System.Runtime.InteropServices.Marshal.FinalReleaseComObject(objCom) Else Dim count As Integer = System.Runtime.InteropServices.Marshal.ReleaseComObject(objCom) End If End If Finally objCom = Nothing End Try End Sub MRComObject(xlBook)でコンパイルの警告が出力されるのですが 回避する方法はないのでしょうか。

  • シートのコピーでプロセスが残ってしまう

    シートのコピーでプロセスが残ってしまう vb2008よりエクセルを起動し、シートを同一のブック内でコピーしようと思うのですが、 下記コードだとシートのコピーはできるのですがリソースが解放できず、プロセスが残ってしまいます。 wsh.Copy(wshh) の部分を wsh.Copy()にして違うブックにコピーすると問題無い。 Excel2003以降の複数のバージョンに対応させるため、CreateObjectを使用しています。 この場合、wsh.copy の部分はどのように記述すれば良いのでしょうか? わかりやすくするため例外等のコードは省いています。 Dim app As Object Dim wbs As Object Dim wb As Object Dim wshs As Object Dim wsh As Object Dim wshh As Object app = CreateObject("Excel.Application") wbs = app.Workbooks wb = wbs.Open("c:\hoge.xls") wshs = wb.Worksheets wsh = wshs.item(1) wshh = wshs.item(1) wsh.Copy(wshh) wb.Close() wbs.close() app.Quit() System.Runtime.InteropServices.Marshal.ReleaseComObject(wshh) System.Runtime.InteropServices.Marshal.ReleaseComObject(wsh) System.Runtime.InteropServices.Marshal.ReleaseComObject(wshs) System.Runtime.InteropServices.Marshal.ReleaseComObject(wb) System.Runtime.InteropServices.Marshal.ReleaseComObject(wbs) System.Runtime.InteropServices.Marshal.ReleaseComObject(app) wshh = Nothing wsh = Nothing wshs = Nothing wb = Nothing wbs = Nothing app = Nothing

  • EXCELファイルからの値取得に関して

    環境:Visual Basic 2008 教えて下さい。 画面上から2つのEXCELファイルを指定し、1回の処理でその2つの EXCELからそれぞれ値を取得したいと考えています。 その為、以下のような記述をしましたが、2回目の値取得のところで "オブジェクト参照がオブジェクト インスタンスに設定されていません。" というエラーメッセージとなってしまいます。 1つのファイルから取得する事は経験ありましたが、同時に2回は初めてで ある為、記述方法が正しいのか、、、 どのように記述したら良いかを教えて下さい。 初歩的な質問で申し訳ありませんが、よろしくお願いします。 《記述内容》 'EXCELファイルを開く Dim xlFilePath As String = ofd1.FileName '起動時の処理 Dim xlApp As Object xlApp = CreateObject("Excel.Application") Dim xlBooks As Object = xlApp.Workbooks Dim xlBook As Object = xlBooks.Open(xlFilePath) '現シート数 Dim S_COUNT As Integer = xlBook.Worksheets.Count Dim xlSheets As Object = xlBook.Worksheets Dim xlSheet As Object = CType(xlSheets.Item(1), Object) '現シート数 S_COUNT = xlBook.Worksheets.Count Dim R_名称 As String R_名称 = "" R_名称 = xlSheet.Cells(1, 1).Value 'COM オブジェクトの解放 System.Runtime.InteropServices.Marshal.ReleaseComObject(xlSheet) System.Runtime.InteropServices.Marshal.ReleaseComObject(xlSheets) System.Runtime.InteropServices.Marshal.ReleaseComObject(xlBook) System.Runtime.InteropServices.Marshal.ReleaseComObject(xlBooks) 'Excel のプロセス終了 xlApp.DisplayAlerts = False xlApp.Quit() System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp) GC.Collect() 'のEXCELファイルを開く Dim xlFilePath2 As String = ofd2.FileName '起動時の処理 Dim xlApp2 As Object xlApp2 = CreateObject("Excel.Application") Dim xlBooks2 As Object = xlApp2.Workbooks Dim xlBook2 As Object = xlBooks2.Open(xlFilePath2) '現シート数 Dim S_COUNT2 As Integer = xlBook2.Worksheets.Count Dim xlSheets2 As Object = xlBook2.Worksheets Dim xlSheet2 As Object = CType(xlSheets2.Item(1), Object) '現シート数 S_COUNT = xlBook2.Worksheets.Count Dim R_番号 As String R_番号 = "" R_番号 = xlSheet2.Cells(I_COUNT2, 1).Value 'COM オブジェクトの解放 System.Runtime.InteropServices.Marshal.ReleaseComObject(xlSheet) System.Runtime.InteropServices.Marshal.ReleaseComObject(xlSheets) System.Runtime.InteropServices.Marshal.ReleaseComObject(xlBook) System.Runtime.InteropServices.Marshal.ReleaseComObject(xlBooks) 'Excel のプロセス終了 xlApp.DisplayAlerts = False xlApp.Quit() System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp) GC.Collect()

  • VB2005からマクロ(EXCEL2003)呼出時の戻り値

    現在VB2005からExcel2003のマクロを呼び出していますが、 戻り値の取得方法が分からなく調べています。 マクロが実行できることは確認しています。 戻り値はそもそも取得できるのでしょうか? 行っている処理は以下の通りです。 ■VB側■ Dim oExcel As New Excel.ApplicationClass() Dim oBook As Excel.WorkbookClass Dim filePath As String = "参照XLSファイルパス" Dim oBooks As Excel.Workbooks = oExcel.Workbooks oExcel.Visible = False oBook = oBooks.Open(filePath) Dim ans As String = CType(oExcel.Run("'" & oBook.Name & "'!ThisWorkbook.DoKbTestWithParameter", "テスト"), String) System.Runtime.InteropServices.Marshal.ReleaseComObject(oBook) oBook = Nothing System.Runtime.InteropServices.Marshal.ReleaseComObject(oBooks) oBooks = Nothing oExcel.Quit() System.Runtime.InteropServices.Marshal.ReleaseComObject(oExcel) oExcel = Nothing ■EXCE側■ Public Function DoKbTestWithParameter(sMsg As String) MsgBox sMsg DoKbTestWithParameter = "VBA関数戻り値" End Function ご教授お願いします。

  • vb2010で既存のエクセルを開くには?

    初心者です。 VB6.0からvb2010への乗り換えをしていますが、以下のコードでxlBooks = xlApplication.Workbooksのところで止まってしまいます。 参考ページをいろいろ見ましたが原因が分かりません。 実行する前のコードに波線はでません。 CreateObjectでやっても結果は同じでworkbookを作るところでエラーとなります。 エラーは「タイプライブラリのロードに失敗」ですが、であればDim xlApplication As New Excel.Application()かCreateObjectで止まるように思いますが、理由がわかりません。 WinXP, Office2003, .Net 4.0. vb2010Expressの組み合わせで全てアップデート済み、参照設定はExcel 11.0 Object Libraryです。 どなたかご教示頂ければ幸甚です。 Imports Excel = Microsoft.Office.Interop.Excel Public Class Form1 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim xlApplication As New Excel.Application() Dim xlBooks As Excel.Workbooks xlBooks = xlApplication.Workbooks xlBooks.Open("C:\Hoge.xls") - - System.Runtime.InteropServices.Marshal.ReleaseComObject(xlBooks) System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApplication) End Sub End Class

  • VB2005でのEXCELマクロ操作

    お世話になっております。 VB2005から指定したEXCELファイルを開き、標準モジュールにあるマクロを起動したいと考えております。 調べたところ、Runメソッドを使用するようですが、マクロファイルを開くところで停止してしまいます。 以下にソースを書きましたので、アドバイス頂きたいと思います。 Dim n As Short Dim xlApp As Excel.Application = Nothing Dim xlBooks As Excel.Workbooks = Nothing Dim xlBook As Excel.Workbook = Nothing Dim xlSheets As Excel.Sheets = Nothing Dim xlSheet As Excel.Worksheet = Nothing Dim xlRange As Excel.Range = Nothing Dim Fname As String = "C:\Documents and Settings\hoge\Application Data\Microsoft\Excel\XLSTART\PERSONAL.XLS" '読み込むファイル Try xlApp = New Excel.Application() xlBooks = xlApp.Workbooks For n = 0 To fil.Length - 1 xlBook = xlBooks.Open(fil(n)) xlSheets = xlBook.Worksheets xlApp.Run("'" & Fname & "'!module2.DB処理", fil(n)) '引数をもつ処理の呼び出し方法 '1000ミリ秒(1秒)待機する System.Threading.Thread.Sleep(1000) ' Excel ブックを保存する xlApp.DisplayAlerts = False xlBook.Save() Next ' Microsoft Excel を終了する xlApp.Quit() Finally If Not xlSheet Is Nothing Then System.Runtime.InteropServices.Marshal.ReleaseComObject(xlSheet) End If If Not xlSheets Is Nothing Then System.Runtime.InteropServices.Marshal.ReleaseComObject(xlSheets) End If If Not xlBook Is Nothing Then System.Runtime.InteropServices.Marshal.ReleaseComObject(xlBook) End If If Not xlBooks Is Nothing Then System.Runtime.InteropServices.Marshal.ReleaseComObject(xlBooks) End If If Not xlApp Is Nothing Then System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp) End If End Try

  • VS2003.NET(C#)からのEXCELのプロセス解放

    ご存知の方がいたら教えて下さい。 【動作環境】 OS:WINDOWS XP(SP2) VisualStadio20003.NET(C#) EXCEL2003 VS.NETのプロジェクトメニューの参照の追加で「Microsoft Excel 11.0 Object Library」を追加してあります。 セルの更新を行った場合に、プロセスが解放されずに残ってしまいます。 (セルの更新を行っている行を実行しない場合にはプロセスは解放されます) いろいろ調べてはみたのですが、どうも原因がつかめません。 ご存知の方がいましたら教えてください。 (以下ソースコードになります) Excel.Application app; Excel.Workbook book; Excel.Worksheet sheet; Excel.Workbooks books; Excel.Sheets sheets; Excel.Range range; app = new Excel.Application(); books = app.Workbooks; book = books.Add("c:\\inetpub\\wwwroot\\ExcelData.xls"); sheets = book.Worksheets; sheet = (Excel.Worksheet)sheets["Sheet1"]; range = sheet.get_Range("A1","A1"); range.Value2 = "テストです"; // 解放 Marshal.ReleaseComObject(range); Marshal.ReleaseComObject(sheet); Marshal.ReleaseComObject(sheets); Marshal.ReleaseComObject(book); Marshal.ReleaseComObject(books); // Excel終了 app.Quit(); Marshal.ReleaseComObject(app); よろしくお願いします。

  • VB2010でExcel罫線

    VB初心者です。 VB2010からExcel操作をして帳票印刷をするコードを考えています。 色々調べた結果、下記のようなコードに行き着きました。 (その他のExcel操作コード) '罫線設定 Dim xlBorders As Excel.Borders Dim xlBorder As Excel.Border xlBorders = xlSheet.Range(xlCells(2, 5), xlCells(3, 20)).Borders xlBorder = xlBorders(Excel.XlBordersIndex.xlEdgeBottom) xlBorders.LineStyle = Excel.XlLineStyle.xlDouble xlSheets.PrintOut() If Not xlBorder Is Nothing Then System.Runtime.InteropServices.Marshal.ReleaseComObject(xlBorder) If Not xlBorders Is Nothing Then System.Runtime.InteropServices.Marshal.ReleaseComObject(xlBorders) (その他のExcel開放コード) このままですと選択された範囲全てのセルが格子状に二重線になってしまいます。 選択範囲の下辺のみ罫線を引くのはどの様にしたらいいでしょうか? またこの罫線コードを追加すると『EXCEL.EXE』がプロセスに残ってしまいます。 この2点ご教授お願いします。

専門家に質問してみよう