• ベストアンサー

.NETでエクセル解放時のコーディング・現象についてアドバイスください

AKARI0418の回答

  • ベストアンサー
  • AKARI0418
  • ベストアンサー率67% (112/166)
回答No.1

>(1)この一行を書くためだけに,すべての階層のObjectを作成・解放するものなのでしょうか???   一応動作はするのですが,あまりこんな書き方を見かけないのですが..... そういうものだと思います。 VB6のときのほうが簡単でしたよね。 Vistual Studio Office Editionのような名前のものを使ってください。 >(2)解放の順序については,下の階層からすべき? みたいなルールは特に無いのでしょうか. もちろんです。 下から開放しなければ、MRComObjectが開放対象を正しく特定できません。 >3)下のコードだとぜんぜん問題ないんですが, Dim xlApp As Object = CreateObject("Excel.Application") Dim xlBooks As Object = xlApp.Workbooks Dim xlBook As Object = xlBooks.Open(ExcelPath) Dim xlSheets As Object = xlBook.Worksheets Dim flg As Short = 0 For Each sht As Object In xlSheets MRComObject(sht) Next MRComObject(xlSheets) 'xlSheets の解放 Try xlBook.Save() xlBook.Close(False) 'xlBook を閉じる Catch ex As Exception End Try MRComObject(xlBook) 'xlBook の解放 MRComObject(xlBooks) 'xlBooks の解放 xlApp.Quit() 'Excelを閉じる MRComObject(xlApp) 'xlApp を解放 ちゃんと消えます。 sheetから書くと、bookあたりが自動的に?作られてしまうのではないでしょうか? >(4)Excel解放のタイミングが,同じプログラム実行時でも弱冠異なるのですが・・・ どうでしょうか? さほど大きくづれることはないはずです。

camputer
質問者

お礼

 AKARI0418 様  どうもありがとうございます.なんとすべての質問にご回答いただけますとは. ご親切にどうもありがとうございます. >(1) >そういうものだと思います。 >VB6のときのほうが簡単でしたよね。  一発ですっきりしました.どうもありがとうございます.  VB6は触ったことがございません...VB6のコードを拾ってきて .NETに直せないことはたまにございますが... ずっとFortranオンリーで,何週間も数値計算して数字の羅列を吐き出すのが この世のプログラムのすべてと思い込んでおりましたが, .NETに始めて触れて取りつかれて毎晩ワクワクいるヘタレでございます.  あまりこういう書き方に触れたことがないということは まだまだ修行と検索量が足りないのかもしれませんね. どうもありがとうございます. >(2) >もちろんです。 >下から開放しなければ、  どうもありがとうございます.すっきりしました. ネットで必死に検索をかけておりますと,たまにxlAppから 解放しているコードを見かけますので,????と.  お詳しい方にアドバイスいただけて良かったです. >(3)  コードでご確認までいただきどうもありがとうございます.  ご指摘いただいた通り,sheetあたりの宣言文をもう少し練ってみます. どうもありがとうございます. >(4)さほど大きくづれることはないはずです。  ご回答をいただいてから考えておりましたが,どうも私の コーディングが下手なせいでもともと解放されにくいプログラムを 実行したときに発生している現象のようでございます. おそらくきちんとしたコードの場合はAKARI0418様のおっしゃる通りに なるのだと.というかなるはずですよね.  ご親切に沢山のアドバイスをいただけて助かります. 本当にどうもありがとうございました.

関連するQ&A

  • .NETでエクセル解放がうまくいきません.

     ネット上で散々ある良回答を拝見させていただいても, 自分で解決しきれませんでした.どうぞよろしくお願いいたします.  下の2行を追加するとエクセルが解放できなくなってしまいます. Private Sub Excel一括置換(ByRef N As Integer) Dim xlApp As New Excel.Application Dim xlBooks As Excel.Workbooks = xlApp.Workbooks Dim WB As Excel.Workbook Dim xlSheet As Excel.Worksheet Dim Mypath As String = TextBoxパス.Text Dim FName As String FName = Dir(Mypath & "*.xls", vbNormal) Do While FName <> "" WB = xlBooks.Open(Mypath & FName) For Each xlSheet In WB.Worksheets 'For N_s = 1 To WB.Worksheets.Count Next 'Next N_s ' ↑の2行がなくなれば無事解放できます MRComObject(xlSheet) : xlSheet = Nothing WB.Save() : WB.Close() MRComObject(WB) FName = Dir() Loop Me.Activate() xlSheet = Nothing WB = Nothing MRComObject(xlBooks) : xlBooks = Nothing xlApp.Quit() : MRComObject(xlApp) : xlApp = Nothing End Sub  最初の「For N_s = 1 To WB.Worksheets.Count」という書き方だと, ネット上で見かけるWorksheet「暗黙のオブジェクト」になるのかな??と思い, xlSheetを宣言してみましたが,うまくいきません. できればFor N_s = ~ という記述法にしたいのですが...  お詳しい方がいらっしゃれば,どうぞよろしくお願いいたします.

  • (再質問) .NETでエクセル解放に悩んでおります.

     数個前のスレッドで勘違いして,締め切らせていただきました. 申し訳ございません.未解決で同じ質問をさせてください.  コードの流れといたしましては,  エクセル操作  ↓  エクセル解放  ↓  ←下記2行のコードが無ければ,この時点でExcel.exeは消えています.  MsgBox("終了")   ↓  アプリケーションを右上の×マークから終了(下記2行のコードを入れると,Excel.exeがギリギリまで残っております.)       Dim xlApp As New Excel.Application Dim xlBooks As Excel.Workbooks = xlApp.Workbooks Dim WB As Excel.Workbook Dim xlSheets As Excel.Worksheets Dim xlSheet As Excel.Worksheet Dim Mypath As String = TextBoxパス.Text Dim FName As String FName = Dir(Mypath & "*.xls", vbNormal) Do While FName <> ""   WB = xlBooks.Open(Mypath & FName)   For Each xlSheet In WB.Worksheets   Next  ' ↑の2行がなくなれば無事解放できます   WB.Save() : WB.Close()   MRComObject(WB)   FName = Dir() Loop Me.Activate() MRComObject(xlSheet) : xlSheet = Nothing MRComObject(xlSheets) : xlSheets = Nothing WB = Nothing MRComObject(xlBooks) : xlBooks = Nothing xlApp.Quit() : MRComObject(xlApp) : xlApp = Nothing MsgBox("終了")  先ほどのスレッドでアドバイス・指摘していただいた部分とあわせて 色々試してみましたが,自分では怪しそうな個所を見つけることすらできません... 暗黙宣言やNothing,Quit等ネットで見かけるものは一通り試したつもりなのですが...  もしお詳しい方がいらっしゃれば,些細なことでも結構ですので なんでもアドバイスいただければ非常にうれしいです.  どうぞよろしくお願いいたします.

  • VB.NET Excelの解放

    Excel出力の解放について質問です。 下記URLを参考に作成しましたが、出力をし終えたときにプロセスを見るとExcelの解放がされません。 http://hanatyan.sakura.ne.jp/dotnet/Excel01.htm 助言をもらえないでしょうか? With SaveFileDialog1 .FileName = savefilename If .ShowDialog() = Windows.Forms.DialogResult.OK Then wstrPath = .FileName() If Func_Excelチェック(wstrPath) = False Then Exit Function End If End If End With Dim excel As New Excel.Application Dim xlbooks As Excel.Workbooks = excel.Workbooks Dim xlbook As Excel.Workbook = xlbooks.Add Dim xlsheets As Excel.Sheets = xlbook.Worksheets Dim xlsheet As Excel.Worksheet = xlsheets.Item(1) Dim xlCells As Excel.Range Dim xlRange1 As Excel.Range xlCells = xlsheet.Cells Dim i As Integer = 1 作成データテーブルに接続 xlRange1 = xlCells(1, 1) xlRange1.Value = "工場番号" MRComObject(xlRange1, True) While sqlReader.Read xlRange1 = xlCells(i + 1, 1) xlRange1(xlCells(i + 1, 1)).Select() xlRange1.Value = sqlReader("入力_工場番号") MRComObject(xlRange1, True) i += 1 End While excel.DisplayAlerts = False xlsheet.SaveAs(wstrPath) 'Select Case Val(excel.Version) 'Case 9 'xlbook.SaveAs(Filename:=wstrPath) 'Case 12 'xlbook.SaveAs(Filename:=wstrPath, FileFormat:=56) 'End Select 'MRComObject(xlsheet, True) excel.DisplayAlerts = True MRComObject(xlsheet)'xlSheet の解放 MRComObject(xlsheets)'xlSheets の解放 xlbook.Close()'xlBook を閉じる MRComObject(xlbook)'xlBook の解放 MRComObject(xlbooks)'xlBooks の解放 excel.Quit()'Excelを閉じる MRComObject(excel)'excel を解放 Private Function Func_Excelチェック(ByVal arg As String) As Boolean Dim excel As New Excel.Application Dim xlbooks As Excel.Workbooks = excel.Workbooks Dim xlbook As Excel.Workbook excel.Visible = False excel.Application.DisplayAlerts = False Try If System.IO.File.Exists(arg) = True Then xlbook = xlbooks.Open(arg) xlbook.SaveAs(arg, FileFormat:=42, CreateBackup:=False) MRComObject(xlbook, True) Return True Else Return True End If Catch ex As Exception MessageBox.Show("") Return False Finally xlbooks.Close() MRComObject(xlbooks, True) excel.Quit() MRComObject(excel, True) End Try End Function

  • エクセルの開放

    VB2008でエクセルを操作しているのですが、エクセルのプロセスが残ってしまってどうやって解放すればいいのかわかりません。 サンプルプログラム-------------- Dim xlApp As New Excel.Application Dim xlBooks As Excel.Workbooks = xlApp.Workbooks Dim xlBook As Excel.Workbook = xlBooks.Add Dim xlSheets As Excel.Sheets = xlBook.Worksheets Dim xlSheet As Excel.Worksheet = xlSheets.Item(1) Dim xlobj As Object '開放用 xlobj = xlSheet.Range("A1:C3") xlobj.Value = "TEST" MRComObject(xlobj) MRComObject(xlSheet) MRComObject(xlSheets) xlBook.Close(False) MRComObject(xlBook) MRComObject(xlBooks) xlApp.Quit() MRComObject(xlApp) MRComObjectでCOM オブジェクトへの参照を解放しています。 このプログラムでは特に問題ないのですが、 xlobj = xlApp.Worksheets("Sheet2") xlobj2 = xlobj.Range("A1:C2") xlobj2.Value = "TEST" のようにワークシートを指定すると解放できません。 xlSheet = xlBook.Worksheets("Sheet2") としてもプロセスが残ります。 またVB6.0では可能だった xlApp.Worksheets("Sheet2").Select() のようにワークシートを切り替えるときもVB2008ではプロセスが残ってしまいます。 これはどのようにしたら解決するのでしょうか?

  • EXCELのグラフ

    下のようにVBからExcel にデータを送りグラフを表示しています。 印刷プレビューを表示したときにグラフと表が表示されてしまいます。グラフだけを表示して表は表示をしたくないのですが どうすればいいのでしょうか お願いします。 Private Sub Command1_Click() Dim xlApp As Excel.Application Dim xlBook As Excel.Workbook Dim xlSheet As Excel.Worksheet Set xlApp = CreateObject("Excel.Application") Set xlBook = xlApp.Workbooks.Add Set xlSheet = xlBook.Worksheets.Add Dim i As Integer Dim j As Integer For i = 2 To 6 For j = 2 To 6 xlSheet.Cells(j, i) = CInt(71 * Rnd + 30) Next j Next i xlSheet.Cells(2, 1) = "国語" xlSheet.Cells(3, 1) = "数学" xlSheet.Cells(4, 1) = "英語" xlSheet.Cells(5, 1) = "社会" xlSheet.Cells(6, 1) = "体育" xlSheet.Cells(1, 2) = "石原" xlSheet.Cells(1, 3) = "小泉" xlSheet.Cells(1, 4) = "田中" xlSheet.Cells(1, 5) = "平沼" xlSheet.Cells(1, 6) = "森山" Dim MyChart As ChartObject Set MyChart = xlSheet.ChartObjects.Add(10, 100, 600, 330) With MyChart.Chart .SetSourceData xlSheet.Range("A1:F6"), xlColumns .Axes(xlValue).MaximumScale = 100 .Axes(xlValue).MajorUnit = 20 .HasTitle = True .ChartTitle.Text = "中間テスト結果" .ApplyDataLabels (xlDataLabelsShowValue) .Location xlLocationAsObject, xlSheet.Name End With xlApp.Visible = True With xlSheet.PageSetup .PaperSize = xlPaperA4 .Orientation = xlPortrait .LeftMargin = xlApp.CentimetersToPoints(2) .RightMargin = xlApp.CentimetersToPoints(2) .TopMargin = xlApp.CentimetersToPoints(2.5) .BottomMargin = xlApp.CentimetersToPoints(2.5) .HeaderMargin = xlApp.CentimetersToPoints(1) .FooterMargin = xlApp.CentimetersToPoints(1) End With xlSheet.PrintPreview Set MyChart = Nothing Set xlSheet = Nothing Set xlBook = Nothing Set xlApp = Nothing End Sub

  • Excelオブジェクトの解放

    VBでExcelを編集しています。 下記コードを実行するとExcelがタスクに残ったままになります。 どうしたら解放されるでしょうか。 (処理は少し省略しています) Dim objExcel as Object Dim objExcelBook as Object Dim objExcelSheet as Object Set objExcel = CreateObject("excel.application") Set objExcelBook = objExcel.Workbooks.Open(パス, 0) Set objExcelSheet = objExcelBook .Sheets(シート名) With objExcelSheet.Range(Cells(1,2),Cells(3,2)).Borders(xlEgeBottom) .LineStyle = xlContinuous End With Set objExcelSheet = Nothing Set objExcelBook = Nothing Set objExcel = Nothing

  • vb2008で操作中のエクセルが解放されてない?

     質問させていただきます.どうぞよろしくお願いします.  vb2008で,エクセル操作をするアプリケーションの作成を試みております. コードの流れとしましては,  エクセル操作   ↓  オブジェクト・アプリケーション解放   (自分的にはここでタスクマネージャからExcel.exeが              消えると思うのですが,残ります)   ↓  メッセージボックス「終了」   ↓  アプリケーションを右上の×マークで閉じる   (タスクマネージャからExcel.exeが消えます) となります.  色々なページを参考にさせていただいて,Excelが解放されるように したつもりなのですが,VBアプリケーション終了ギリギリまで 存在し続けるという事は,うまく解放できていないということなのでしょうか?  作成したコードは以下のようになります. (バグ取り中に,エクセル操作部分のコードはほとんど消去してみました. しかしまだ上記のような現象になっております) Private Sub ButtonA_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonA.Click Dim N_e As Integer Call Excel一括置換(N_e) MsgBox("終了" ) End Sub Private Sub Excel操作(ByRef N As Integer) Dim xlApp As New Excel.Application Dim xlBooks As Object Dim WB As Object Dim Rng As Object '================== 終了処理 ===================== Rng = Nothing : MRComObject(Rng) WB = Nothing : MRComObject(WB) xlBooks = Nothing : MRComObject(xlBooks) xlApp.Quit() : xlApp = Nothing : MRComObject(xlApp) End Sub Public Shared 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) Debug.WriteLine(count) End If End If Finally objCom = Nothing End Try End Sub  何か些細なことでもご指摘いただければ非常に助かります. どうぞよろしくお願いたします.

  • グラフの表示

    VB6.0 ACCESS2000で開発しています。 下の様にACCESSからデータを読んでEXCELでグラフを表示して プレビューへ表示しています。 プレビューを表示した後、印刷してEXCELを閉じる。 又は、印刷せずに閉じた場合でも画面上はEXCELは閉じているのですが プロセスに残ってしまいます。 どこが悪いのでしょうか? よろしくお願いします。 Private Sub Command1_Click() Dim ExcelApp As Object 'Excel.Application Dim Book As Object 'Excel.Workbook Dim Sheet As Object 'Excel.Worksheet Dim cn As ADODB.Connection Dim rst As ADODB.Recordset Set cn = New ADODB.Connection cn.ConnectionString = _ "Provider=Microsoft.Jet.OLEDB.4.0;" & _ "Data Source=C:\temp\db2.mdb" cn.Open Set rs = New ADODB.Recordset rs.Source = SELECT = "SELECT = "SELECT 商品名, 単価 FROM m_品名 rs.ActiveConnection = cn rs.CursorType = adOpenStatic rs.Open Set ExcelApp = CreateObject("Excel.Application") Set Book = ExcelApp.Workbooks.Add Set Sheet = Book.Worksheets(1) Sheet.Cells(1, 1).CopyFromRecordset rst Dim MyChart As ChartObject Set MyChart = Sheet.ChartObjects.Add(10, 100, 600, 330) With MyChart.Chart .SetSourceData Sheet.Range(Range("A1:B1"), Range("A1:B1").End(xlDown)), xlColumns .ChartType = xlBarClustered .Axes(xlValue).MaximumScale = 350 .Axes(xlValue).MajorUnit = 50 .HasTitle = True .ChartTitle.Text = "案件実績合計" .ApplyDataLabels (xlDataLabelsShowValue) '.SeriesCollection(1).ApplyDataLabels (xlDataLabelsShowValue) .Location Where:=xlLocationAsNewSheet End With ExcelApp.Visible = True Book.ActiveSheet.PrintPreview Book.Close ExcelApp.Quit Set Sheet = Nothing Set Book = Nothing Set ExcelApp = Nothing Set rst = Nothing Set cn = Nothing End Sub

  • VB.NETからEXCELの起動が、うまくいかない

    3回目の同じ質問になってしまうのですがよろしくお願いいたします。 下記のようなソースでEXCELファイルを作成し、その後ファイルを開くという処理をしています。 Dim xlApp As New Excel.Application Dim xlBooks As Excel.Workbooks = xlApp.Workbooks Dim xlBook As Excel.Workbook = xlBooks.Add Dim xlSheets As Excel.Sheets = xlBook.Worksheets Dim xlSheet As Excel.Worksheet = xlSheets.Item(1) Dim xlRange As Excel.Range Dim xlCells As Excel.Range = xlSheet.Cells xlRange = xlCells(1, 10) xlRange.Value = "--" xlRange = xlCells(1, 5) xlCells.EntireColumn.AutoFit() xlBook.SaveAs(sPath & "\" & sFileName, Excel.XlFileFormat.xlWorkbookNormal) System.Runtime.InteropServices.Marshal.FinalReleaseComObject(xlCells) System.Runtime.InteropServices.Marshal.FinalReleaseComObject(xlRange) System.Runtime.InteropServices.Marshal.FinalReleaseComObject(xlSheet) System.Runtime.InteropServices.Marshal.FinalReleaseComObject(xlSheets) xlCells = Nothing xlRange = Nothing xlSheet = Nothing xlSheets = Nothing xlBook.Close() System.Runtime.InteropServices.Marshal.FinalReleaseComObject(xlBook) System.Runtime.InteropServices.Marshal.FinalReleaseComObject(xlBooks) xlBook = Nothing xlBooks = Nothing xlApp.Quit() System.Runtime.InteropServices.Marshal.FinalReleaseComObject(xlApp) xlApp = Nothing GC.Collect() System.Diagnostics.Process.Start(sPath & "\" & sFileName) ある特定のPCでのみEXCELのメニューバーとステータスバーのみしか表示されない状態です。 起動部分(Process.Start)をコメントアウトして確認したところ GC.COLLECTでEXCELが終了することなく、アプリの終了時にEXCELが終了する 状態にあります。 これはオブジェクトの開放がうまくいっていないのでしょうか? よろしくお願いいたします。

  • ExcelのVBAでメモリ解放できない

    以下のようなプログラムで、ExcelVBAで作成しております、Webの情報を取得しております。 strGetUrl のところのサイトによっては、メモリが解放できず困っています。 Whileで繰り返すほど、メモリを消費して解放されません。メモリいっぱいになれば解放してくれるのかと思いましたが、止まってしまいました。2回目はOSを壊して再インストールしてもらいました(VPS上で)。 困っております。オブジェクトも”Set xxxx = Nothing”で解放しているつもりです。 考えられる理由をご教授頂けると幸いです。 環境は OSはWindowsServer2008R2 IEはIE8 でVPSなので変更不可と言われました。 ちなみに、Windows8.1の環境ではメモリが溜まっていくことはなかったです。 何か良い方法はありますでしょうか? また、別のWebアクセス方法はありますでしょうか? IE = CreateObject("InternetExplorer.Application")は同じ結果でした。 以下のプログラムでサイトにもよりますが、発生しています。 *********************************** Option Explicit Sub testHtml() Dim doc As Object, objTag1 As Object, objTag2 As Object Dim oHttp As Object Dim strUrl As String, strGetUrl As String Dim rowIndex As Integer ' 基本URL設定 strGetUrl = "http://www.xxxx.xxx.com" rowIndex = 1 '1列目が1行づつ進めてが空になったら終了 While Cells(rowIndex, 1).Value <> "" Set oHttp = CreateObject("MSXML2.XMLHTTP") Set doc = CreateObject("htmlfile") ' *************** HTTPヘッダの作成し、送信してデータを取得 ***************** With oHttp .Open "GET", strGetUrl, False .Send ' 受信したデータをオブジェクトに書き込みます。 doc.Write .responseText End With ' *************** 受信データを解析し、H2データ取得に分割 ***************** For Each objTag1 In doc.body.getElementsByTagName("H2") If objTag1.className = "resultCount" Then Cells(rowIndex, 2).Value = objTag1.innerText End If Next ' Objectの解放 Set objTag1 = Nothing Set objTag2 = Nothing Set doc = Nothing Set oHttp = Nothing rowIndex = rowIndex + 1 Wend End Sub