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

No35257 の記事


■35257 / )  Re[7]: Excel Com オブジェクトの増殖
□投稿者/ たこ 一般人(19回)-(2022/11/28(Mon) 22:38:47)
  • アイコンNo35252に返信(魔界の仮面弁士さんの記事)
    No35253に返信(魔界の仮面弁士さんの記事)
    No35255に返信(魔界の仮面弁士さんの記事)
    No35256に返信(radianさんの記事)

    魔界の仮面弁士様、radian様、返信ありがとうございます。

    返信が前後しますが、まずはradian様ご紹介ありがとうございます。
    どうしようも無くなった時は検討させて頂きます(^^ゞ

    余談にはなりますが…
    元々私、プログラミングは全部独学でして、スキルアップの為に今回の質問をさせて頂いています(^^ゞ
    (いつもはどうしようも無くなって質問させて頂いていますが…(^^ゞ)
    まだしっかりと解ってる訳では無いですが、VB6.0からオブジェクトの概念を解る様になるまでは苦労しました^^;

    最終的には会社で5年分くらいExcelで見積書が溜まっていますので、これをデータベース化するのが目的です。。。
    最初はExcel VBAで5年分の見積書の内容をまとめようかと思っていましたが、クラスの概念を覚えてしまうとクラスを使った方が楽なので(^^ゞ
    VB6.0やVBAにもクラスはありますが、使い方が良く解りません…
    …と言う訳でVB.NETで…(^^ゞ

    お気持ちは有難く頂戴致しました。
    ありがとうございます。



    今回、いろいろ調べてやっとExcelのオブジェクトモデルを発見出来ました。
    https://learn.microsoft.com/ja-jp/office/vba/api/overview/excel/object-model
    VBAと同じなのですね…
    当たり前と言えば当たり前ですが…

    Option Strict Onも調べました…
    https://atmarkit.itmedia.co.jp/fdotnet/vb6tonet/vb6tonet26/vb6tonet26_03.html

    DirectCast、CTypeの違いも調べました…
    http://vb.navi-ch.net/2015/07/18/post-118/
    https://learn.microsoft.com/ja-jp/dotnet/visual-basic/language-reference/operators/directcast-operator



    さて、本題に戻ります。

    No35252に返信(魔界の仮面弁士さんの記事)
    >>  Private _xlsApplication As Excel.Application = Nothing
    >>  Friend ReadOnly Property xlsApplication As Excel.Application
    >>    Get
    >>      Return _xlsApplication
    >>    End Get
    >>  End Property
    > これではあまり意味が無いと思いますよ。結局のところ、
    >  Friend ReadOnly xlsApplication As Excel.Application
    > な読み取り専用フィールドと、さほど変わらないように見えます。
    >
    >
    > COM オブジェクトを直接公開してしまうと、ExcelEx の外部で
    >  ExEx1.xlsApplication.Workbooks.Add()
    > などと書かれてしまえば、COM オブジェクトの解放漏れに繋がります。
    >
    > IDisposable としてカプセル化するのであれば、Excel の COM オブジェクトは
    > 外部からは直接操作できないようにして、すべてクラス内に隠蔽します。
    > 戻り値と返すのも COM オブジェクトではなく、.NET のマネージオブジェクトにします。

    全てをクラス内でやってしまう…と言う考え方で良いのでしょうか…
    例えば…
    -----------------------------------------------------------------
    Private _xlsApplication as Excel.Application = Nothing

    Private _ExcelVisible As Boolean = True
    Public Property ExcelVisible As Boolean
      Set(Value as Boolean)
        _ExcelVisible = Value
        If value then
          _xlsApplication.Visible = True
        Else
          _xlsApplication.Visible = False
        End If
      End Set
      Get
        Return _ExcelVisible
      End Get
    End Property
    -----------------------------------------------------------------
    …の様な感じで…

    >>  _xlsWorkSheet = xlsApplication.Sheets.Add()
    > この処理には、問題点が 2 つあります。
    >
    > 1 つは「.」による COM オブジェクトの連続呼び出しであり、
    > Sheets プロパティから返されるコレクションの解放が漏れています。
    Excel.Applicationオブジェクト(COMモデル)の中の、Application.Sheetsプロパティ…あれ?w
    https://learn.microsoft.com/ja-jp/office/vba/api/excel.application.sheets
    COMオブジェクトの場合は(COMオブジェクトの)プロパティの解放も必要と理解して良いのでしょうか…

    >  Dim obj1 = 対象ワークブック.Sheets 'これは Sheets 型        …と言う事は Dim obj1 As Excel.Sheets
    >  Dim obj2 = obj1(strSheetName) 'これは Object 型となることに注意   …と言う事は Dim obj2 As Object
    …で合ってますかね^^?
    ここの理解はまだ追い付いていません(>_<)

    > ただし厳密にいえば、xlsSheets によって列挙されるシートが Excel.Worksheet である保証はありません。
    > Excel.Chart や Excel.DialogSheet が列挙される可能性もあることは頭の片隅に置いといてください。

    …と言う事は…
    -------------------------------------------------------------------------------------
    Friend Sub WorkSheet_Select(strSheetName As String)
      Dim check As Boolean = False
      For x As Integer = 1 to _xlsSheets.Count
        If _xlsSheets(x) Is Excel.Worksheet then                '← 怒られました^^;
          If CType(_xlsSheets (x), Excel.Worksheet).Name = strSheetName Then
            check = True
            Exit For
          End If
        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
    -------------------------------------------------------------------------------------

    下の方に書いてありました^^;
    >   Dim ws = DirectCast(xlsSheets(n), Excel.Worksheet)
    これだと『WorkSheet』以外はNothingになるのでしょうか…

    (DirectCastは明示的な型変換と書いてありました…
    http://vb.navi-ch.net/2015/07/18/post-118/
    -------------------------------------------------------------------------------------
    サンプルソース
    Dim a As Object = 3.14
    Dim b As Integer = DirectCast(a, Integer)
    MsgBox(b)
    End Sub
    End Class
    実行結果
    メッセージーボックスも表示されません。
    -------------------------------------------------------------------------------------

    頭大パニック中…
違反を報告
返信 削除キー/


Mode/  Pass/


- Child Tree -