クラスモジュールを使いこなすためには、モデル化という概念をおさえておくと分かりやすい。しかしいきなりモデル化といわれても何のことかわからないと思うので、順を追って説明していく。
まずプログラミングにおけるモデル化の話をする前に、モデルという言葉の定義を押さえておこう。
モデルとは
Weblioでmodelを検索すると、次のように表示された。
主な意味:模型、モデル、ひな形、(原型の)塑像、原形、(理解などの)模型、(服装品・自動車などの)…型、(人・ものの)模範、手本、鑑(かがみ)
コア:型にはめるもの;ひな型
このうちプログラミングで扱うモデルは、「(理解などの)模型」の意味である。
物事を理解するために、その性質を抜き出して構造図にしたものだと考えるとよい。
モデルは実際の物事から必要な情報だけをピックアップして簡略化したものである。
必要な情報は、そのプログラムが何を扱うかによって変わる。たとえば同じ個人情報でも服屋さんなら身長や胸囲など体格に関する情報がメインになるだろうし、病院なら血圧、血液型、アレルギーなど健康に関する情報を扱うことになる。歯医者なら歯の一本ずつを情報として扱う必要があるだろう。
まぁそのような特殊な例はさておき、とりあえず今回は一般的と思われる4つの情報で人物をモデル化してみた。
その図がこちら。
人物に、氏名・住所・生年月日・性別が順序関係なくぶら下がっている。
これらの情報はどれも等しくその人物が持つ性質であり、そこに順序性は存在しない。
モデルをExcelの表に変換する
あるモデルをExcelの表で表現しようとすると、その性質上どうしても格納順を決める必要がある。
以下にサンプル表を書いてみた。
氏名 | 住所 | 生年月日 | 性別 |
山田太郎 | 大阪 | 2000/01/01 | 男 |
佐藤次郎 | 東京 | 2001/02/02 | 男 |
鈴木花子 | 愛知 | 2002/03/03 | 女 |
左から1番目が氏名、2番目が住所、3番目が生年月日、4番目が性別となっている。
モデルにはそうした順序構造や座標(アドレス)などは存在しないが、データをExcel表に落とし込む以上はどうしても順序を決めざるを得ないのである。
データの形として、理想はモデル、現実は表といったところだ。
あるいは、モデルに表という現実的な制約を与えることでようやくデータの形で利用できるという理解でもよいかもしれない。
さて、たとえば表から別の形式の表へ転記するようなマクロを考えてみる。
このとき表は座標を持っているので、表から表への転記は座標から座標への転記となる。
これは、VBAで書くとこういうコードになる。
Sub転記()Dim転記元 As Worksheet: Set転記元 = Sheets("転記元")Dim転記先 As Worksheet: Set転記先 = Sheets("転記先")For i =2To4転記先.Cells(1, i).Value=転記元.Cells(i,1).Value転記先.Cells(2, i).Value=転記元.Cells(i,4).Value転記先.Cells(3, i).Value=転記元.Cells(i,3).Value転記先.Cells(4, i).Value=転記元.Cells(i,2).ValueNextEndSub
これは表Aから人物情報を読み取って、その人物情報を表Bにコピーするという処理である。このときふつう、「氏名は転記元の1列目、転記先では1行目」「住所は転記元の2列目、転記先では4行目」といったことを考えながらコードを書く。
つまりプログラマーの頭の中には、「人物情報」というモデルが存在しているはずである。
図で表すと、こういう感じ。
しかしコードに書かれているのは、あくまで座標から座標だけであり、後日コードを見返したときに注意深く読まなければ何をやっているのかサッパリわからなくなる恐れがある。
クラスモジュールでモデルを扱う
さて、ここからが本題だ。
まずクラスモジュールを挿入し、オブジェクト名を人物としておく。そして追加した人物クラスのコードはこちらを入力する。
Public氏名 AsStringPublic住所 AsStringPublic生年月日 AsDatePublic性別 AsString
こういう状態↓
それから標準モジュールには以下を張り付ける。
Subモデルを介した転記()Dim転記元 As Worksheet: Set転記元 = Sheets("転記元")Dim転記先 As Worksheet: Set転記先 = Sheets("転記先")Dim m As人物 For i =2To4Set m =New人物 m.氏名 =転記元.Cells(i,1).Value m.住所 =転記元.Cells(i,2).Value m.生年月日 =転記元.Cells(i,3).Value m.性別 =転記元.Cells(i,4).Value転記先.Cells(1, i).Value= m.氏名 転記先.Cells(2, i).Value= m.性別 転記先.Cells(3, i).Value= m.生年月日 転記先.Cells(4, i).Value= m.住所 NextEndSub
実行するとうまく転記できているのがわかる。
もう一度さっきの図と、コードを見比べてみよう。
このように、実際に行っていることとコードが一致している。
ふつうの変数を使った方法と、クラスを使った方法と何が違うのか
ここで「ふつうの変数と何が違うの?」と思われたかもしれない。
そのとおり。わざわざ面倒なクラスなんて使わなくても以下のように普通の変数でも似たようなことができる。
Sub変数を介した転記()Dim転記元 As Worksheet: Set転記元 = Sheets("転記元")Dim転記先 As Worksheet: Set転記先 = Sheets("転記先")Dim氏名,住所,生年月日,性別 For i =2To4氏名 =転記元.Cells(i,1).Value住所 =転記元.Cells(i,2).Value生年月日 =転記元.Cells(i,3).Value性別 =転記元.Cells(i,4).Value転記先.Cells(1, i).Value=氏名 転記先.Cells(2, i).Value=性別 転記先.Cells(3, i).Value=生年月日 転記先.Cells(4, i).Value=住所 NextEndSub
しかし変数というのはあくまでそれぞれが単体で存在しているものであり、そこに構造的な結びつきはない。氏名・住所・生年月日・性別は確かに人物の情報であるが、それをプログラム上で結びつけるものが無いのだ。
クラスモジュールを使えばこれらは人物オブジェクトに対する属性として強固に結びつく。
また、クラスモジュールでモデルを扱うと、こんな風にコレクションにモデルを追加してモデルの束を作り、それを別表に転記するという方法も可能になる。
Subモデルを介した転記2()Dim転記元 As Worksheet: Set転記元 = Sheets("転記元")Dim転記先 As Worksheet: Set転記先 = Sheets("転記先")Dim m As人物 Dim People As Collection Set People =New Collection 'モデルの束を作成For i =2To4Set m =New人物 m.氏名 =転記元.Cells(i,1).Value m.住所 =転記元.Cells(i,2).Value m.生年月日 =転記元.Cells(i,3).Value m.性別 =転記元.Cells(i,4).Value People.Add m Next'モデルの束から転記 cnt =2ForEach m In People 転記先.Cells(1, cnt).Value= m.氏名 転記先.Cells(2, cnt).Value= m.性別 転記先.Cells(3, cnt).Value= m.生年月日 転記先.Cells(4, cnt).Value= m.住所 cnt = cnt +1NextEndSub
このようにデータをモデル化して扱うことができるのがクラスモジュールを使うメリットの一つである。
まとめ
さて、今回はモデル化の概念を抽象的な図をつかって説明した。
またモデルをコード上で表現するためにクラスモジュールが適していることがご理解いただけたかと思う。
さらにクラスモジュールのメリット・活用方法を学ぶには以下の記事もおススメ。
thom.hateblo.jp
また、便利なのはわかったけど実際クラスってどうつかうの?って方はこちらの記事が超おススメ!
ateitexe.com
このt-hom's diaryを参考にされたと書いてあるけど、私の記事より断然分かりやすくまとまっている!!
ま、私のブログはVBAマニア層に向けた小難しい記事が売りなので(笑