.NET FrameworkのArrayListクラス
このページではJavaのArrayListクラスっぽいものを自作+紹介しています。
.NET FrameworkのArrayListの使い方については「VBAで.NET FrameworkのArrayListを使う」にて紹介していますのでご参照ください。
JavaのArrayListっぽいクラスを自作する
VBA以外のプログラミング言語を使うと便利な機能がよくあります。その1つがクラスです。
VBAにもクラスはあるのですが、機能が限定されています。0継承、抽象化、オーバーロード、オーバーライドなどの他の言語では当たり前のことが出来ません。あるのはメンバー変数とメソッドとカプセル化ぐらいです。コンストラクタはあります。
わざわざクラスモジュールを作らなくてもいいじゃん、と言われても仕方ないほどです。
クラスだけでなく、VBAの不得意な分野に配列があります。サイズを最初に確保して、そのあとは必要に応じて拡張する、ということが必要ですが、はっきり言って面倒です。
そのVBAの不便な配列をどうにか少しでもマシに出来ないかと思い、.NET Frameworkがまともに使えない時代にJavaのArrayListっぽいクラスを作ってみたものに手を入れたものです。
あくまでも「っぽい」です。いくつかの関数はJavaのArrayListとは違うメソッド名にしています。
ArrayListクラス説明
このArrayListクラスの説明です。
クラスのインスタンスが生成されるとメンバー変数のVariant配列(mvArray)を初期化します。このVariant配列がデータを格納するリストの実体になります。あとは、リストへの追加、削除、参照、クリアなどの各メソッドを用意しています。
下段の使い方を見て頂くとわかると思います。
以下がArrayListクラスのコードです。作成する際にはクラスモジュールとして追加してください。
ArrayListクラス
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 |
'//---------------------------------------------------------------------------- '// ArrayListクラス '//---------------------------------------------------------------------------- Option Explicit Private mvArray() As Variant '//---------------------------------------------------------------------------- '// 関数名 :Class_Initialize '// 引数 :なし '// 戻り値 :なし '// 機能 :コンストラクタ '// 備考 : '//---------------------------------------------------------------------------- Private Sub Class_Initialize() ReDim mvArray(0) End Sub '//---------------------------------------------------------------------------- '// 関数名 :Add '// 機能 :値をクラスに追加する '// 引数 :(I) asVal '// 戻り値 :なし '// 備考 :JavaのArrayList.Addと一緒 '//---------------------------------------------------------------------------- Public Sub Add(asVal) On Error Resume Next Dim vArray() Dim iCnt iCnt = Me.Count If (IsEmpty(mvArray(iCnt)) = True) Then mvArray(iCnt) = asVal Else ReDim Preserve mvArray(iCnt + 1) mvArray(iCnt + 1) = asVal End If End Sub '//---------------------------------------------------------------------------- '// 関数名 :Remove '// 機能 :値をクラスから削除する '// 引数 :(I) asVal '// 戻り値 :なし '// 備考 :JavaのArrayList.Removeと一緒 '//---------------------------------------------------------------------------- Public Sub Remove(aiIndex) On Error Resume Next Dim vArray() Dim iCnt Dim i '// ループカウンタ Dim iAdjust '// mvArrayからvArrayへコピーするためのIndex iAdjust = 0 iCnt = Me.Count ReDim vArray(iCnt - 1) '// 要素を削るのでその分もマイナスする For i = 0 To iCnt If (i <> aiIndex) Then vArray(iAdjust) = mvArray(i) iAdjust = iAdjust + 1 End If Next Me.Clear ReDim mvArray(iAdjust) mvArray = vArray End Sub '//---------------------------------------------------------------------------- '// 関数名 :GetVal '// 機能 :指定要素位置の値を取得する '// 引数 :(I) aiIndex '// 戻り値 :指定要素位置の値 '// 備考 :JavaのArrayList.Getと一緒 '//---------------------------------------------------------------------------- Public Function GetVal(aiIndex) Dim vRet As Variant If (aiIndex > Me.Count) Then vRet = Null Else vRet = mvArray(aiIndex) End If GetVal = vRet End Function '//---------------------------------------------------------------------------- '// 関数名 :GetIndex '// 機能 :指定要素のリスト内で最初に検出された位置のインデックスを取得する '// 引数 :(I) asVal '// 戻り値 :指定要素のインデックス。要素がない場合は-1を返す。 '// 備考 :JavaのArrayList.indexOfと一緒 '//---------------------------------------------------------------------------- Public Function GetIndex(asVal) On Error Resume Next Dim iCnt Dim i '// ループカウンタ Dim bExistFlg As Boolean '// 要素存在フラグ(True:要素あり、False:なし) Dim iIndex bExistFlg = False iCnt = Me.Count For i = 0 To iCnt If (mvArray(i) = asVal) Then bExistFlg = True Exit For End If Next If (bExistFlg = True) Then iIndex = i Else iIndex = -1 End If GetIndex = iIndex End Function '//---------------------------------------------------------------------------- '// 関数名 :Clear '// 機能 :配列要素をクリアする '// 引数 :なし '// 戻り値 :なし '// 備考 :JavaのArrayList.Clearと一緒 '//---------------------------------------------------------------------------- Public Function Clear() Call Class_Initialize End Function '//---------------------------------------------------------------------------- '// 関数名 :Count '// 機能 :配列要素数を調べる '// 引数 :なし '// 戻り値 :Long :マッピング数 '// 備考 :JavaのArrayList.Countと一緒 '//---------------------------------------------------------------------------- Public Function Count() As Long Count = UBound(mvArray) End Function '//---------------------------------------------------------------------------- '// 関数名 :Contains '// 機能 :引数値がリストに含まれるかを確認する '// 引数 :(I) asVal '// 戻り値 :Boolean :True:引数がリストに含まれる、False:含まれない '// 備考 :JavaのArrayList.containsと一緒 '//---------------------------------------------------------------------------- Public Function Contains(asVal) As Boolean Dim iCnt As Long Dim iListCnt As Long Dim bRet As Boolean bRet = False iListCnt = Me.Count Do While (iCnt <= iListCnt) If (asVal = mvArray(iCnt)) Then bRet = True Exit Do End If iCnt = iCnt + 1 Loop Contains = bRet End Function '//---------------------------------------------------------------------------- '// 関数名 :ContainsU '// 機能 :引数値がリストに含まれるかを確認する。大文字で統一して比較。 '// 引数 :(I) asVal '// 戻り値 :Boolean :True:引数がリストに含まれる、False:含まれない '// 備考 :JavaのArrayList.containsと一緒 '//---------------------------------------------------------------------------- Public Function ContainsU(asVal) As Boolean Dim iCnt As Long Dim iListCnt As Long Dim bRet As Boolean bRet = False iListCnt = Me.Count Do While (iCnt <= iListCnt) If (UCase(asVal) = UCase(mvArray(iCnt))) Then bRet = True Exit Do End If iCnt = iCnt + 1 Loop ContainsU = bRet End Function '//---------------------------------------------------------------------------- '// 関数名 :ContainsInstr '// 機能 :引数文字列値がリスト文字列の一部に含まれるかを確認する。大文字で統一して比較。 '// 引数 :(I) asVal '// 戻り値 :Boolean :True:引数がリストに含まれる、False:含まれない '// 備考 :JavaのArrayList.containsと一緒 '//---------------------------------------------------------------------------- Public Function ContainsInStr(asVal) As Boolean Dim iCnt As Long Dim iListCnt As Long Dim bRet As Boolean bRet = False iListCnt = Me.Count Do While (iCnt <= iListCnt) If (InStr(1, UCase(asVal), UCase(mvArray(iCnt))) > 0) Then bRet = True Exit Do End If iCnt = iCnt + 1 Loop ContainsInStr = bRet End Function |
ArrayListクラスの使い方
使い方はこんな感じです。
Newしてインスタンスを作っているところはクラスっぽいですね。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
Sub testMethod() Dim arylist As New ArrayList Dim s Dim i Call arylist.Add("1") Call arylist.Add("aaa") Call arylist.Add("ddddddd") Call arylist.Remove(1) For i = 0 To arylist.Count Debug.Print arylist.GetVal(i) Next End Sub |