エクセルVBAクラス備忘録 変数の使い方(宣言)(privateかpublicか)しつこい

20240420 エクセルVBAクラス備忘録 変数の使い方(宣言)(privateかpublicか)


<前書き>
エクセルVBAオブジェクト指向、初心者です。
VBA自体は、以前から使用していました。
オブジェクト指向というものがあることは、知っていましたが、ネットなどを見てもよく分からず、挫折した過去あり。
<以上前書き>

(素人なので間違っているかもしれません。汗。)

今回:
今回、メイン処理について、思ったことをメモしようと思いましたが、そこにたどり着く前に、備忘録。
また、変数の使い方(宣言)(privateかpublicか)です。

 

クラスを作成する場合、privateかpublicかどっちがいいのかという話がありました。
privateだと、セッターとか、ゲッターとか面倒だし、その使い方も、中をただ通すだけならあんまり意味ないのでは?と思っていました。

でも、bing様(copilot様)に、簡単なクラスを書いてもらったら、「ああこんな風に使えるのか」というのがあったので、備忘録。
(以下コードは適宜直しています。)


シートはこんな感じ。


簡単に日付と店名と金額があって、それらを行ごとに取得するコードを書いてもらう。

---------------------------------------
Sub Main2()
    Dim salesData As New LibWorkSheet
    salesData.Init "売上" ' シート名を指定

    ' レコードが最終行に到達するまで日付を表示
    Do While salesData.売上_Date <> ""
        Debug.Print "日付: " & salesData.売上_Date
        salesData.ReadNext
    Loop
End Sub


-----------------------------------
' LibWorkSheetクラス
'Public Class LibWorkSheet
    Private Ws As Worksheet
    Private readrow As Long

    ' 初期化
    Public Sub Init(sheet_name As String)
           
        Set Ws = ThisWorkbook.Sheets(sheet_name)   '
        readrow = 2 ' 読み込み行数(初期値は2行目)
    End Sub

    ' 日付を取得
    Public Property Get 売上_Date() As Variant
        売上_Date = Ws.Cells(readrow, 1).Value  ' A列から値を取得
    End Property

    ' 店名を取得
    Public Property Get ShopName() As Variant
'        ShopName = Val("B" & ReadRow)
        ShopName = Ws.Cells(readrow, 2).Value

    End Property

    ' 金額を取得
    Public Property Get Amount() As Variant
'        Amount = Val("C" & ReadRow)
        Amount = Ws.Cells(readrow, 3).Value
    End Property

    ' 次の行を読み込む
    Public Sub ReadNext()
        readrow = readrow + 1
    End Sub

 
'End Class
--------------------------------------------

こんな感じ。親モジュールのDo Whileで、日付をdebug.printする。

注目は、下記のプロパティ。

    ' 日付を取得
    Public Property Get 売上_Date() As Variant
        売上_Date = Ws.Cells(readrow, 1).Value  ' A列から値を取得
    End Property

通常、自分だと、単純に、
    Public Property Get 売上_Date() As Variant
        売上_Date = m売上_Date
    End Property

として、クラス内のprivate変数(m売上_Date)を売上_Dateに戻して、メインに返すようにするが、ここでは、
Ws.Cells(readrow, 1).Value
として、readrowを変えることで、次のデータに移行している。
(また、この売上_Dateプロパティは、シートから、触接値を取得するため、セッターを使っていないのも注目)

この使い方なら、セッター・ゲッターを設定する価値はあると思った。

ちなみに、「public変数を使って」自分で書くなら以下のコード。
*****************************
Option Explicit
Public readrow As Long  'publicはここしか置けないし、dimだとだめなので、publicしかない。

Sub main_kari()
    Dim cnt As Long
    

    Dim v売上 As 売上
    Set v売上 = New 売上 
    readrow = 2 'publicでクラスに渡す
    v売上.初期化

    ' レコードが最終行に到達するまで日付を表示
    Do While v売上.店名 <> ""
        Debug.Print "日付: " & v売上.日付
        v売上.ReadNext
        v売上.初期化
    Loop
End Sub

-----------------------------------
'クラス「売上」
Option Explicit

Public 日付 As Date
Public 店名 As String
Public 金額 As Double

Private Ws As Worksheet


Sub 初期化()      

    Set Ws = ThisWorkbook.Sheets("売上")

    日付 = CDate(Ws.Cells(readrow, 1).Value)
    店名 = Ws.Cells(readrow, 2).Value
    金額 = Ws.Cells(readrow, 3).Value
End Sub

Public Sub ReadNext()
    readrow = readrow + 1
End Sub

-------------------------------
これだと、セッター・ゲッターを使わないが、特にメインモジュールに書いた、readrowが危険すぎる気がする。
長いコードになると分からなくなる。
もっと上手な書き方はあると思うが、今回はここまでです。


その他
do whileは、v売上.店名 <> ""にしています。
'    Do While v売上.日付 <> ""    '型が一致しません 「""」は文字型のため
エラーになるようです。