VBAを用いた集合の理解 ① aは集合Aの要素である
子供から、数学の集合について訊かれた。高校を卒業して三十余年、
「そういえば、そんな話もあったっけ?」
ぐらいの認識だ。
当時は思考も漠としていて、先生たちの話は常に意識の表層を滑り
抜けていた感覚だけが記憶に残っている(=脳に刺さっていない)。
どちらかといえば集合の問題は、
- よく解らない
- 苦手
な分野だった。
ところが今になって見てみると、少なくとも当時より容易に理解
できていることに気づく。おそらく日々、これと似たようなもの、
特に「配列」と向き合ってきたことが、理解の一助となっている
に違いない。
ということで今回は、数回に分けて、VBAを用いた集合の理解
に挑戦してみよう。
なおブログの内容によっては、集合の定義から外れる部分もある
と思うが、お遊びということでご容赦願いたい。
改めて高校数学における「集合とは何か」の情報を求めたところ、
こちらにとても分かりやすくまとめられていた。
manabitimes.jp
- a∈A aは集合Aの要素である
- a∉A aは集合Aに属さない
ここで集合Aを配列で表すなら、例えばこのようになると考える。
Dim 果物 As Variant 果物 = Array("りんご", "みかん", "ばなな")
- 「りんご」は、配列「果物」に含まれる
- 「ぶどう」は、配列「果物」に含まれない
と考えれば、なじみ深い。
そこで、含む/含まないを「True / False」(=真/偽)のBoolean型で
返す関数を作ってみよう。
クラスモジュール(MathSet)
まず、クラスモジュール「MathSet」を作成する。「集合」は、英語で
Set だそうな。ややこしくなる、嫌な予感しかしない。とりあえず頭に
「数学の」という意味で「Math」を付けてみた。
クラスモジュールとしたのは、ほかにも集合に関する関数などをここに
入れ、一まとめにしたかったから。実際は標準モジュールでも構わない。
今回、クラスモジュールに作成した関数がこちら。
Option Explicit ' このクラス内で**Setや**_setと表現されるものはすべて、 ' 数学における「集合(set)」を指している。 ' ※ややこしいのでご注意ください。 ' このクラス内では、集合はすべてn次元配列で表現する。 ' 例)集合:果物 = Array("りんご", "みかん", "ばなな") ' 指定文字列が、ある集合の要素であるか否かを返す。 Public Function IsElement(ByVal element As Variant, _ ByVal target_set As Variant, _ Optional LookAt As XlLookAt = xlWhole) As Boolean ' 集合ではないものが指定された場合、Falseを返す。 If Not IsArray(target_set) Then Exit Function ' 配列内の値と順にelementを照合し、同じものがある時点でTrueを返す。 ' 従って、この関数はtarget_set内で複数の同じ値が含まれる場合を除外しない。 Dim a As Variant If LookAt = xlPart Then element = "*" & element & "*" For Each a In target_set If a Like element Then IsElement = True Exit Function End If Next End Function
部分一致と完全一致の切り替えが可能な点などが、数学の集合とは違うところ。
いずれどこかで役に立つかもと思い、盛り込んでみた。
標準モジュール
それでは早速、テストしてみよう。
Sub test() Dim MS As New VBAProject.MathSet Dim 果物 As Variant 果物 = Array("りんご", "みかん", "ばなな") Debug.Print "ばなな:" & MS.IsElement("ばなな", 果物) Debug.Print "ぶどう:" & MS.IsElement("ぶどう", 果物) End Sub
結果は ↓ こちら。とりあえず、意図したとおりに動いてくれた。
※ここで示しているのは、「ぶどうは果物ではない」ということではなく、
先に定義した「果物」グループのメンバーに「ぶどう」が入っていない
ということになります。
今回のシリーズは、配列の編集などを多く盛り込みつつも、仕事ではあまり
役に立たなそうな気がする(いつも?)。でも個人的には面白そうなので、
しばらく続けてみようと思う。
参考まで。