Excelのプロセスが消えない(再)

タグの編集
投稿者 たらちゃん  (社会人) 投稿日時 2009/1/18 19:52:37
お世話になります。
大変申し訳ありませんが、再度Excelプロセス終了する方法について教えてください。
先に質問させていただいたものと同じコードで、COMオブジェクトを開放すれば問題なくプロセスが終了するようになりました。しかし、Excelに名前をつけて保存する処理をいれたところ、またプロセスが終了しないようになりました。下記コードの(※1)(※2)の箇所をコメントにすると、正常にプロセスが終了しますので、(※)マークのコードに問題がある事までは分かりましたが、いったい何が悪いのか分かりません。また保存先が問題あるのかと思い(※1)をコメントしましたがやはりプロセスが残ったままです。


コードの間違い探しをしてもらうようで大変恐縮なのですが、何卒宜しくお願いいたします。

  '-------------
        '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 xlCells As Excel.Range


       
        'Excelを非表示にする()
        xlApp.Visible = False

        '-------------------------
        'DataSet抽出結果を出力する
        '-------------------------

        Me.ProgressBar1.Minimum = 0
        Me.ProgressBar1.Maximum = oledv.Count - 1

        Dim i As Integer
        For i = 0 To oledv.Count - 1
            xlCells = xlsheet.Cells
            xlCells(1, 1).value = "会社名"
            xlCells(1, 2).value = "住所"
            xlCells(1, 3).value = "県名"
            xlCells(i + 2, 1).value = oledv(i)(1)    '会社名
            xlCells(i + 2, 2).value = oledv(i)(5) '住所
            xlCells(i + 2, 3).value = oledv(i)(10) '県
            'COMオブジェクトの開放
             System.Runtime.InteropServices.Marshal.ReleaseComObject(xlCells)
            Me.ProgressBar1.Value = i
        Next

        System.Runtime.InteropServices.Marshal.ReleaseComObject(xlsheet)
        System.Runtime.InteropServices.Marshal.ReleaseComObject(xlSheets)

      (※1)xlBook.SaveAs("C:\Users\hoge\Documents\book.xls")
      (※2)xlBook.Close()

        'COMオブジェクトの開放       
         System.Runtime.InteropServices.Marshal.ReleaseComObject(xlBook)
        System.Runtime.InteropServices.Marshal.ReleaseComObject(xlBooks)

        xlApp.Quit()
        System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp)
        xlSheet = Nothing
        xlBook = Nothing
        xlApp = Nothing

        '処理終了メッセージ
         MsgBox("ファイルの加工を終了しました")
        Me.ProgressBar1.Value = 0

    End Sub
投稿者 (削除されました)  () 投稿日時 2009/1/19 01:54:54
(削除されました)
投稿者 neptune  (社会人) 投稿日時 2009/1/19 02:06:22
こんにちは

http://homepage1.nifty.com/MADIA/vb/vb_bbs2/200412/200412_04120059.html
を参考に自分の保存用サンプルを書いてみました。
詳しくは魔界の仮面弁士 さんのコメントを読んで下さい。
要はCellsプロパティの使い方みたいです。

私もまだよく判りませんが、取り合えずプロセスは残りません。
COMを使う場合特にOption Strict Onは要りますね。


Option Strict On
'無関係部分省略 
    Private Sub ExcelTest()
        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
        Dim xlRange As Excel.Range
        Dim xlCells As Excel.Range
        Const csSheetName As String = "Sheet1"
        Const csPath As String = "E:\Data\Office\Excel\vb2008Test.xls"

        'ファイルを削除しておく 
        Try
            System.IO.File.Delete(csPath)
        Catch ex As Exception
            '何もしない 
        End Try

        xlApp = New Excel.Application
        xlBooks = xlApp.Workbooks
        xlBook = xlBooks.Add()
        My.Application.DoEvents()
        xlSheets = xlBook.Worksheets
        xlSheet = DirectCast(xlSheets(csSheetName), Excel.Worksheet)
        xlCells = DirectCast(xlSheet.Cells, Excel.Range)

        'データ入力 
        For i As Integer = 1 To 5
            xlRange = DirectCast(xlCells(i, 1), Excel.Range)
            xlRange.Value = i * 100
            ReleaseComObject(xlRange)
        Next

        xlApp.Visible = True
        xlBook.SaveAs(csPath)
        xlBook.Close(False)             'xlBook を閉じる 

        '開放処理 
        ReleaseComObject(xlCells)        'xlCells の解放 
        xlCells = Nothing
        ReleaseComObject(xlSheet)       'xlSheet の解放 
        xlSheet = Nothing
        ReleaseComObject(xlSheets)      'xlSheets の解放 
        xlSheets = Nothing
        ReleaseComObject(xlBook)        'xlBook の解放 
        xlBook = Nothing
        ReleaseComObject(xlBooks)       'xlBooks の解放 
        xlBooks = Nothing

        xlApp.Quit()                    'Excel終了  
        ReleaseComObject(xlApp)         'xlApp を解放 
        xlApp = Nothing
    End Sub


#これでまともに動けば大丈夫ですよね?
おかしい所があれば教えてくださいね。
投稿者 るきお  (社会人) 投稿日時 2009/1/19 22:30:15
こんにちは。
.NETになってから、Excel連携が面倒になりましたよね。
特にたらちゃんさんが苦労されているように、処理後もプロセスが解放されない現象に
かなり気と時間を使いそうです。

逆にプロセスの解放を考えなくていいのなら、
素直にプログラムするだけで済むように思えるので、
いっそうのこと、Excel連携部分だけ別exeにして、1処理ごとに起動するというような逃げはどうでしょうか。

私はまだ.NETになってから本格的なExcel連携のプログラムを
書いた経験がないのですが、もしその必要があったら検討してみたいです。

ちなみにNetAdvantageなどサードパーティ製のExcel操作ライブラリもありますが、
事情は同じなのでしょうか?

※疑問形で書いてしまいましたが、98%情報共有と意見です。
投稿者 たらちゃん  (社会人) 投稿日時 2009/1/21 16:39:40
neptuneさん、るきおさんご回答ありがとうございます。
お返事が遅くなりましたこと、まずはお詫びいたします。
のっぴきならない事情で今朝までパソコンをしばらく見ることができませんでした。
とくにneptuneさんにはサンプルコードまで書いていただき大変恐縮しております。

まだ検証できていないのですが、教えていただいたコードを見ながら書き直してみたいと思います。
2,3日以内にまた結果のほうご連絡させていただきます。

取り急ぎお礼まで。
ありがとうございました。

投稿者 たらちゃん  (社会人) 投稿日時 2009/1/23 16:50:36
neputuneさんに教えていただいたように、現在xlsheet.cellsを使用している箇所を
xlCells = DirectCast(xlSheet.Cells, Excel.Range)
と修正したところ正常にプロセスが終了するようになりました。
アドバイスをいただきました皆様、ありがとうございました。