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売上.日付 <> "" '型が一致しません 「""」は文字型のため
エラーになるようです。