<前書き>
VBA自体は、以前から使用していました。
オブジェクト指向というものがあることは、知っていましたが、ネットなどを見てもよく分からず、挫折した過去あり。
エクセルVBAで、オブジェクト指向を必要とすることもなかったので、諦めていましたが、youtubeで、「ひとりごとワンダーランド」様のエクセルVBAでのクラスに関する動画を見させていただき、少しだけやる気になっています。感謝。
(まだ、動画は最後まで見ていません。汗)
<以上前書き>
前回:
youtube「ひとりごとワンダーランド」様のクラスモジュールの作法(なるべくprivateでpublicを減らすとか、クラス内変数の書き方とか)を
使って、ネットHPで「いつも隣にITのお仕事」様の記事「エクセルVBAでエクセル表のデータを反映するメソッドとクラスを使うメリット」を
コード化しました。
分かっていないので、間違っているかも。(多分、間違っている。汗)
注:もしこのブログ記事に関し、youtube「ひとりごとワンダーランド」様、ネットHP「いつも隣にITのお仕事」様におかれまして、不都合があり、削除すべき場合は、即削除いたします。
前回は、「いつも隣にITのお仕事」の記事に、ちらっと「ユーザーフォームで扱えるようにすると・・・」と書いてあったので、ユーザーフォームを作ってみました。
今回:
(内容は、変数temperatureに数字(温度)を渡すと、数字に応じたExperience(熱い、ちょうどいい等)を返すコードです。 )
前回までと関係ありません。
注:「Kの備忘録(仮)」様におかれましても不都合があれば早急に削除いたします。
今回、クラスのprivete変数など本当に分からないので、上記temperatureを3パターンで書いてみました。(クラスなしも入れると4パターン。)
(手続き型なら簡単なのに、クラスだと同じ機能でも、いろんな書き方ができるようです。)
Bing様にもお手伝いいただきました。(不都合あれば削除します。)
////////////////////////////////////////////////////
【パターン0】(クラス使わない)手続き型というのか?普通の書き方。
'標準モジュール
Option Explicit
Sub TodaysTemperature()
Dim temperature As Long
temperature = 30
Debug.Print Experience(temperature)
temperature = 20
Debug.Print Experience(temperature)
End Sub
Function Experience(pTemperature As Long) As String
If pTemperature >= 30 Then
Experience = "暑い"
ElseIf pTemperature >= 15 Then
Experience = "ちょうど良い"
Else
Experience = "寒い"
End If
End Function
////////////////////////////////////////////////////
【パターン1】(クラスだけど、private変数使わない)
'標準モジュール
Option Explicit
Sub TodaysTemperature()
Dim v判定 As 判定
Set v判定 = New 判定
Dim temperature As Long
temperature = 30
Debug.Print v判定.Experience(temperature)
temperature = 20
Debug.Print v判定.Experience(temperature)
End Sub
'クラス「判定」
Option Explicit
Function Experience(pTemperature As Long) As String
If pTemperature >= 30 Then
Experience = "暑い"
ElseIf pTemperature >= 15 Then
Experience = "ちょうど良い"
Else
Experience = "寒い"
End If
End Function
////////////////////////////////////////////////////
【パターン2】(Temperatureにprivateを使う)
'標準モジュール
Option Explicit
Sub TodaysTemperature()
Dim v判定 As 判定
Set v判定 = New 判定
'Dim temperature As Long'(不要になった)
v判定.temperature = 30
Debug.Print v判定.Experience
v判定.temperature = 20
Debug.Print v判定.Experience
End Sub
'クラス「判定」
Option Explicit
Private mTemperature As Long
Property Let temperature(pTwmperature As Long)
mTemperature = pTwmperature
End Property
Function Experience() As String '引数なし(mTemperatureを使う)
If mTemperature >= 30 Then
Experience = "暑い"
ElseIf mTemperature >= 15 Then
Experience = "ちょうど良い"
Else
Experience = "寒い"
End If
End Function
////////////////////////////////////////////////////
【パターン3】(Temperature、Experienceにprivateを使う)
'標準モジュール
Option Explicit
Sub TodaysTemperature()
Dim v判定 As 判定
Set v判定 = New 判定
v判定.temperature = 30
Debug.Print v判定.Experience
v判定.temperature = 20
Debug.Print v判定.Experience
End Sub
'クラス「判定」
Option Explicit
Private mTemperature As Long
Private mExperience As String
Property Let temperature(pTwmperature As Long)
mTemperature = pTwmperature
Call hantei_Experience
End Property
Property Get Experience() As String
Experience = mExperience
End Property
Private Sub hantei_Experience()
If mTemperature >= 30 Then
mExperience = "暑い"
ElseIf mTemperature >= 15 Then
mExperience = "ちょうど良い"
Else
mExperience = "寒い"
End If
End Sub
*********************************************************
パターン1・・・うーんメリットとしては、なんだろ。インスタンス化が終われば保持した値が消えるということか?
パターン2・・・標準モジュールにTemperatureの宣言不要になった。
うーんメリットとしては、なんだろ。(実感がないが)、mTemperatureとしてprivate化することで、
標準モジュールで、書き換えようとしても、property letを通すことだろうか。
(ありがたみをあまり感じないが、property letで細工をすることも可能か。)
(全く分からないが、どこかで、変数が書き換わってしまうと、なかなかコードの修正やバグの発見がしにくいと聞いたことがある。)
(VBAでは、継承とかオーバーライドとかないのか、ありがたみを感じにくいのか?)
パターン3・・・クラス内の変数を全部private化しました。
標準モジュールから入ってくる方(Temperature)は、property letだけ。
標準モジュールへ出ていく方(Experience)は、property getだけ。
上記の変数を使用したサブルーチンを1個作り(functionを改修)、property let内でコール。
カプセル化かあ。
ちょっと強引だが、クラスを使う場合で、private変数を使う場合は、標準モジュールでは変数の宣言は必要なく、
クラス内で、private変数と合わせて、(標準モジュールでも使える変数用にpropertyを作成ということか。)
もしかして、大人数で作成する時は、クラスわかれているといいのかな。
その他:
何となく気になるのが、ローカルウインドウで見ると、クラスにすると(当然だけど)変数が増える。
そんなものなのか。