先日買った以下の書籍に取り組みはじめた。
- 作者: 橋本英美
- 出版社/メーカー: 工学社
- 発売日: 2013/11/01
- メディア: 単行本
- この商品を含むブログ (3件) を見る
序盤に足し算だけで掛け算をするという問題があるが、普通に書くとこのようになる。
Sub 足し算で乗算_ノーマル() a = 9 b = 5 Dim 合計 As Long For i = 1 To b 合計 = 合計 + a Next Debug.Print 合計 End Sub
つまり、aをb回足せば良い。簡単だ。
ここで面倒くさいのは、「合計 = 合計 + a」という表記である。
人間は普通、「合計にaを足す」と表現する。
「合計に1を足したものを合計に代入する」などとまどろっこしい言い方はコンピューター特有のものだ。
VBAではこれが普通なのだが、VB.NETでは「合計 += a」と書ける。
この、X = X + AというパターンはVBAで頻繁に登場する。
そこで、これを少しでもスマートな書き方に近づけるため、以下のクラスを用意した。
クラス名は「Accumulator」としている。
Private PNumber As Long Private Sub Class_Initialize() PNumber = 0 End Sub Property Get Number() As Long Number = PNumber End Property Public Sub Clear() Call Class_Initialize End Sub Public Sub Add(x As Variant) PNumber = PNumber + x End Sub
中身は分からなくても良い。単にクラスモジュールを挿入し、クラス名を変えて上記のコードを貼り付ければ良い。
これを使うと、メインのコードはこうなる。
Sub 足し算で乗算_累算機サンプル() a = 31 b = 9 Dim 合計 As New Accumulator For i = 1 To b 合計.Add a Next Debug.Print 合計.Number End Sub
合計変数の宣言文は長くなる。
そして数字を取り出すのに、.Numberとしなければならない。
それでも、「合計にaを足す」という人間の思考とマッチした書き方が出来るのは嬉しい。
オブジェクト指向の最大のメリットは内部の操作を隠蔽し、直感的に操作できるモノを作り出すことである。
Accumulatorの内部でどういう計算がされているかは一切考える必要は無い。
ただAddすれば値を加えることが出来、.Numberで取り出せる。ただそれだけ知っていれば使える。
さらに、.Numberと指定するのが面倒であれば、デフォルトプロパティを作成するというテクニックがある。
これは過去記事に書いたのでそちらを参照して欲しい。
thom.hateblo.jp
このテクニックを使うと、.Numberがデフォルトプロパティとなるため、ただ「合計」と書けば数値を参照できる。
Sub 足し算で乗算_累算機サンプル2() a = 31 b = 9 Dim 合計 As New Accumulator For i = 1 To b 合計.Add a Next Debug.Print 合計 End Sub
今回のサンプルは小さいので、わざわざクラスを作成するメリットは小さいと感じるかもしれない。
もう少しクラスを強化してみよう。
今度はいろんな演算ができるようにしたのでクラス名も「OperatableNumber」とした。
Private PNumber As Double Private Sub Class_Initialize() PNumber = 0 End Sub Property Get Number() As Long Number = PNumber End Property Property Let Number(x As Long) PNumber = x End Property Public Sub Clear() 'ゼロに戻す Call Class_Initialize End Sub Public Sub Add(x As Variant) '引数を足す PNumber = PNumber + x End Sub Public Sub Substruct(x As Variant) '引数を引く PNumber = PNumber - x End Sub Public Sub Times(x As Variant) '引数を掛ける PNumber = PNumber * x End Sub Public Sub Devides(x As Variant) '引数で割る PNumber = PNumber / x End Sub Public Sub Plus() '1足す PNumber = PNumber + 1 End Sub Public Sub Minus() '1引く PNumber = PNumber - 1 End Sub Public Sub Half() '半分にする PNumber = PNumber / 2 End Sub Public Sub Twice() '2倍にする PNumber = PNumber * 2 End Sub
そしてそのクラスを使用するサンプルがこちら
※デフォルトプロパティのテクニックも使用しています。
Sub クラス使用サンプル() Dim X As New OperatableNumber Debug.Print "初期値:"; X X = 1 Debug.Print X X.Add 3 Debug.Print X X.Half Debug.Print X X.Times 5 Debug.Print X For i = 1 To 5 X.Plus Next Debug.Print X X.Minus Debug.Print X End Sub
自分専用のクラスを作っておくと、便利なオブジェクトとしていろんなコードで使いまわしできる。
以下のように取り扱い説明書を用意すれば、誰でも使える。
OperatableNumberのトリセツ
まず、OperatableNumber.clsファイルをインポートしておきます。
コードで使用する場合は、最初にOperatableNumber型で変数を宣言してください。
Integer型やLong型の変数を作るときと同じですが、ひとつだけ、「New」というおまじないが必要です。
例) Dim X As New OperatableNumber
あとは普通の変数と同じように代入や参照ができます。
例) X = 1 : MsgBox X
値を加えるときは従来どおり、X = X + 10などと書くこともできますが、Add命令を使うと、X.Add 10というふうにシンプルに書けます。
他にも以下のような命令があります。
X.Add 10 | Xに10を加える |
X.Plus | Xに1を加える |
X.Minus | Xから1を引く |
X.Times 5 | Xを5倍する |
X.Half | Xを半分にする |
… | … |
まとめ
クラスモジュールを使いこなせるようになると、コーディングの幅が広がる。
ExcelのSheetやRangeもオブジェクトなので、自分でクラスを作れるようになるとより理解が深まる。
使えば慣れるし、ここぞという場面でどんどん閃くようになるだろう。
こういう小さなことでも、もっと気軽にクラスを使って良いと思う。