Newキーワードの使用について

タグの編集
投稿者 yasu  (社会人) 投稿日時 2009/1/6 03:40:55
VB初心者です。以下の構文でEXCEL2000のファイルとやり取りをしたのですが
起動1回目はOKですが2回目以降、エラーで接続できません。

Public Class Form1
    Dim 保存 As String
    Dim システム As String
    Dim xlApp As New Excel.Application
    Dim xlBooks As Excel.Workbooks = xlApp.Workbooks
    Dim xlBook As New Excel.Workbook
    Dim xlSheets As Excel.Sheets
    Dim xlSheet As Excel.Worksheet

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
           (中略)

        Finally
            objCom = Nothing
        End Try
    End Sub

Private Sub 接続(ByVal FileName)
        Dim xlFilePath As String = FileName
        xlBook = xlBooks.Open(xlFilePath) ←ここでエラー(Newキーワードを使用くださいのメッセージ)
        xlSheets = xlBook.Worksheets
        xlSheet = xlSheets.Item(1)
    End Sub

Private Sub 接続終了()
 
        MRComObject(xlSheet)            'xlSheet の解放
        MRComObject(xlSheets)           'xlSheets の解放
        xlBook.Close(False)             'xlBook を閉じる
        MRComObject(xlBook)             'xlBook の解放
        MRComObject(xlBooks)            'xlBooks の解放
        xlApp.Quit()                    'Excelを閉じる 
        MRComObject(xlApp)              'xlApp を解放
    End Sub

 Private Sub 書込()
        接続(保存)
        
        (中略)
        
        接続終了()
    End Sub

接続と終了処置が何回も必要なので独立させた物にしたかったのですが Newキーワードの使い方が
よくわかりません。よろしくお願いします
環境 VB2005 Excel2000
投稿者 るしぇ  (社会人) 投稿日時 2009/1/6 04:26:24
Public Class Form1
  ・・・
  Dim xlApp As New Excel.Application
この書き方だと、Form1 が New された時に xlApp が New されます。

その後、
  xlApp.Quit()                    'Excelを閉じる 
  MRComObject(xlApp)              'xlApp を解放
するのですから、New したオブジェクトは破棄されます。

再度、使うときはもう一度 New する必要があります。
・・・当然ですよね?それほど難しい内容では無いはずです。

Class は紙の設計図です。紙に書いた電卓では計算
できませんよね?New はメモリ上に実際に計算できる
部品で電卓を作る命令です。
破棄したら分解されて分別ゴミになってしまいます。
もう一度使いたいなら、部品を集めて作り直します。

また、
  xlBook = xlBooks.Open(xlFilePath)
既存の Book を開くのですから、開いた時点で
保存されていたファイルの Book が実体化します。
それを参照すればいいだけですから、
Public Class Form1
  ・・・
  Dim xlBook As New Excel.Workbook
この New は必要ありません。

xlApp はプログラム起動時から終了時まで保持するのですか?
なら、
  xlApp.Quit()                    'Excelを閉じる 
  MRComObject(xlApp)              'xlApp を解放
閉じなければ(破棄しなければ)いいのでは?

ただし、xlApp を解放する処理をプログラムを終了する時に
実行する必要があります。また、接続しっぱなしなので関数名も
変えたほうがいいですね。

---------------------------------------------------
ここから別案
接続終了を意識するなら、Form の New 時は変数宣言だけに
します。
Public Class Form1
  Dim 保存 As String
  Dim システム 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

接続時に New します。
Private Sub 接続(ByVal FileName)
  Dim xlFilePath As String = FileName
  xlApp = New Excel.Application
  xlBooks = xlApp.Workbooks
  xlBook = xlBooks.Open(xlFilePath)
  xlSheets = xlBook.Worksheets
  xlSheet = xlSheets.Item(1)

接続と接続終了の対応関係に注意してみてください。
投稿者 yasu  (社会人) 投稿日時 2009/1/7 02:03:59
返事送れてすみません。おかげさまで別案のほうでうまくいきそうです。
Newキーワードの使い方もおぼろげながら理解できてきました。
ありがとうございます。

関連してですが終了処置後にタスクマネージャーをみるとEXCEL.EXEが残ったままになっている
(デバッグを終了すると消える)のですがこれっていいんでしょうか?(次の処理に入ると消える
こともある)
投稿者 るしぇ  (社会人) 投稿日時 2009/1/7 10:44:20
>終了処置後にタスクマネージャーをみるとEXCEL.EXEが残ったままになっている
プロセスが残っているのですから、解放できてない Excel オブジェクトが
あるのでは?