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

No35250 の記事


■35250 / )  Re[4]: Excel Com オブジェクトの増殖
□投稿者/ たこ 一般人(17回)-(2022/11/27(Sun) 16:46:37)
  • アイコンしばらく見ない間に返信も増殖してました^^;

    No35244に返信(魔界の仮面弁士さんの記事)
    @ 魔界の仮面弁士様のアドバイスを元に、各オブジェクトをプライベートに設定し、プロパティとメソッドを分けました。
    ----------------------------------------------------------------------------------------------------
      'Excel のアプリケーション参照用オブジェクト
      Private _xlsApplication As Excel.Application = Nothing
      Friend ReadOnly Property xlsApplication As Excel.Application
        Get
          Return _xlsApplication
        End Get
      End Property

      〜〜(以下同じ)〜〜
       xlsWorkBooks
       xlsWorkBook
       xlsSheets
       xlsWorkSheet
       xlsRange

      〜〜(省略)〜〜

      Friend Sub New()
        'Excel アプリケーション起動
        _xlsApplication = New Excel.Application
        'Excel の WorkbookBeforeClose イベントを取得
        'AddHandler xlsApplication.WorkbookBeforeClose, AddressOf xlsApplication_WorkbookBeforeClose
        'Excel の Workbooks 取得
        _xlsWorkBooks = _xlsApplication.Workbooks
        'Excel非表示
        _xlsApplication.Visible = False
        _xlsApplication.DisplayAlerts = False
      End Sub

      Friend Sub WorkBook_Open(strFileName As String)
        '既存 Excel ファイルを開く
        _xlsWorkBook = xlsWorkBooks.Open(strFileName)
        'Excel の Worksheets 取得
        _xlsSheets = xlsWorkBook.Worksheets
        'Excel の Worksheet 取得
        _xlsWorkSheet = CType(xlsSheets.Item(1), Excel.Worksheet)  ' (a)
        _xlsWorkSheet.Select()
        _xlsApplication.Visible = ExcelVisible
      End Sub

      Friend Sub Workbook_Save()
        If Not WorkBookName Is Nothing Then
          _xlsWorkBook.SaveAs(Filename:=WorkBookName)
        Else
          _xlsWorkBook.Save()
        End If
      End Sub

      Friend Sub WorkBook_Close()
        '終了処理
        'xlsRange の解放
        MRComObject(xlsRange)
        'xlsWorkSheet の解放
        MRComObject(xlsWorkSheet)
        'xlsWorkSheets の解放
        MRComObject(xlsSheets)
        'xlsWorkbookを閉じる
        xlsWorkBook.Close(SaveChanges:=False)
        'xlsWorkbook の解放
        MRComObject(xlsWorkBook)
        'xlsWorkbooks の解放
        MRComObject(xlsWorkBooks)
        'Excelを閉じる
        xlsApplication.Quit()
        'xlsApplication を解放
        MRComObject(xlsApplication)
      End Sub

      Friend Sub WorkSheet_Select(strSheetName As String)
        Dim check As Boolean = False
        For Each sh In xlsSheets
          If sh.Name = strSheetName Then
            check = True
            Exit For
          End If
        Next
        If Not check Then
          _xlsWorkSheet = xlsApplication.Sheets.Add()
          xlsWorkSheet.Name = strSheetName
        Else
          _xlsWorkSheet = xlsApplication.Sheets(strSheetName)
        End If
        If SheetVisible Then xlsWorkSheet.Select()
      End Sub
    ----------------------------------------------------------------------------------------------------

    No35247に返信(魔界の仮面弁士さんの記事)
    A
    >>xlsWorkSheet = xlsWorkSheets.Item(1)
    > .Item の戻り値は Object のはずですので、明示的にキャストしましょう。

    明示的にキャストしました。…(a)


    > 参照カウントが不用意に増加することを防ぐため、可能であれば
    > 「Option Strict On」で実装することをお奨めします。

    Option Strict Onをすると『Option Strict On では、遅延バインディングを使用できません。』といっぱい怒られます(^^ゞ
    調べたところ… (https://learn.microsoft.com/ja-jp/dotnet/visual-basic/misc/bc30574
    『明示的に書け』だそうで…

    例えばシートを選択する処理…
    ----------------------------------------------------------------------------------------------------
      Friend Sub WorkSheet_Select(strSheetName As String)
        Dim check As Boolean = False
        For Each sh In xlsSheets
          If sh.Name = strSheetName Then  '←ここで怒られましたが、これは『Ctype(sh,Excel.Worksheet).Name = strSheetName』とする事で解決。
            check = True
            Exit For
          End If
        Next
        If Not check Then
          _xlsWorkSheet = xlsApplication.Sheets.Add()  '←ここでも怒られますが、『CType(xlsApplication.Excel.Sheets, Excel.Worksheet).Add()』としてみましたが、怒られたままです><
                                 ’■No35248に返信(魔界の仮面弁士さんの記事) 参考情報: https://www.petitmonte.com/bbs/answers?question_id=25306 ここの…
                                 '>> 基本的に、『.』を連続して使うのは赤信号だと思ってください。ここにヒントがある気はしまして…
                                 '『 CType(CType(xlsApplication.Excel, Excel.Application).Sheets, Excel.Worksheet).Add()』とかしてみましたが、駄目でした><
                                 'いろいろやってみました。『CType(xlsSheets.Add(), Excel.Worksheet)』で良さそうな感じが…(まだエラーだらけで実行出来ていません(^^ゞ
          xlsWorkSheet.Name = strSheetName
        Else
          _xlsWorkSheet = xlsApplication.Sheets(strSheetName)  '←怒られた
                                     '『 CType(xlsApplication.Sheets(strSheetName), Excel.Worksheet)』で良さそう…

                                     '<参考>
                                     '> ■No35245に返信(たこさんの記事)
                                     '> xlsWorkSheet = xlsApplication.Sheets(strSheetName) ではなく
                                     '> xlsWorkSheet = xlsWorkSheets(strSheetName) でしょう。
                                     '最終『_xlsWorkSheet = CType(xlsSheets(strSheetName), Excel.Worksheet)』で良さそう…

        End If
        If SheetVisible Then xlsWorkSheet.Select()
      End Sub
    ----------------------------------------------------------------------------------------------------

    > もしもレイトバインド前提で実装するのなら、.NET ではなく
    > VBS や VBA から利用した方が安全です。

    VB.NETからExcelを操作する勉強も兼ねているので、このまま行きます(^^ゞ

    例えばシートを選択する処理最終版…
    ----------------------------------------------------------------------------------------------------
      Friend Sub WorkSheet_Select(strSheetName As String)
        Dim check As Boolean = False
        For Each sh In xlsSheets
          If CType(sh, Excel.Worksheet).Name = strSheetName Then
            check = True
            Exit For
          End If
        Next
        If Not check Then
          _xlsWorkSheet = CType(xlsSheets.Add(), Excel.Worksheet)
          xlsWorkSheet.Name = strSheetName
        Else
          _xlsWorkSheet = CType(xlsSheets(strSheetName), Excel.Worksheet)
        End If
        If SheetVisible Then xlsWorkSheet.Select()
      End Sub
    ----------------------------------------------------------------------------------------------------

    他の処理でもエラーが多すぎて頭が追い付かず…
    実行出来たらまた報告致します。。。

    (私、実はすごくなんとなくで作っているんだなぁ…と実感しました…
違反を報告
返信 削除キー/


Mode/  Pass/


- Child Tree -