.NET FrameworkのArrayListを使うには
VBAでは.NET Frameworkの一部のクラスを利用することが出来ます。
利用するにはWindowsもしくはExcelのバージョンによってはVBAで参照設定が必要です。
VBA画面のツールメニュー→参照設定で以下の選択もしくは参照してください。
C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscorlib.tlb(dllではありません)
Microsoft Common Language Runtime Class Library
なお私の環境では参照設定不要です。設定してもチェックが表示されません。
mscorlib.dllはWindows 7の以下の環境にて動作確認を行っています。
.NET Frameworkのバージョンによって参照設定できるものもあります。
私の環境の最新バージョンは上記のとおりv4.0.30319ですが、v2.0.50727のを参照するとチェックが付きます。
v2.0.50727の参照設定をするとCreateObject関数を使わなくてもよくなります。
1 2 3 4 5 6 7 8 9 10 |
Sub mscorlib_v2Test() Dim ar1 As New mscorlib.ArrayList Dim ar2 As New ArrayList Call ar1.Add("111") Call ar1.Add("222") Call ar2.Add("333") Debug.Print ar1.Count End Sub |
ただ、.を押してもメソッドやプロパティの候補は出ません。候補は出ませんが、メソッドやプロパティを手で書けばはちゃんと動作します。
参照設定するべきなのか、そうでないのか、などはOSや64bitかどうかも関係するようですが、よくわかりませんでした。
なので、以下はそういう「動けばいいんだよ」精神なのをご了承ください。
ArrayListのオブジェクト変数の作成方法
.NET FrameworkのArrayListのオブジェクト変数の作成はCreateObject関数にて行います。
1 2 |
Dim ar As Object '// ArrayListオブジェクト Set ar = CreateObject("System.Collections.ArrayList") |
元の変数はObject型で定義していますが、Variant型でも構いません。
どちらもCreateObject関数で成功すると内部定義はArrayList型になります。
CreateObject関数のあとは必要に応じてArrayListクラスのメソッドやプロパティを利用します。
Microsoftのヘルプは以下になります。(2018/5/31確認済み)
https://msdn.microsoft.com/ja-jp/library/system.collections.arraylist(v=vs.110).aspx
以下で2通りの使い方を紹介します。
1つ目はCreateObject関数を使ってそのまま使う方法です。
2つ目はArrayList用のクラスを用意して使う方法です。
CreateObject関数を使ってそのまま使う方法
一般的に紹介される方法はこちらだと思います。CreateObject関数を使ってインスタンスを作成して、あとはメソッドやプロパティを利用するコーディング方法です。
この方法で利用は可能ですが、メソッドやプロパティのメンバが見えない欠点があります。
使えればOKという場合はこちらでもいいです。
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 |
Sub DNET_ArrayListTest1() Dim aryList As Object '// ArrayListオブジェクト Dim s '// 戻り値用 Dim obj As Object '// Clone用 '// .NET FrameworkのArrayListクラスを利用する Set aryList = CreateObject("System.Collections.ArrayList") '// 追加 Call aryList.Add("111") Call aryList.Add("222") Call aryList.Add("333") Call aryList.Add("444") '// 書き換え aryList.Item(0) = "AAA" '// 取得 s = aryList.Item(0) '// 要素数 s = aryList.Count '// 反転 Call aryList.Reverse '// ソート Call aryList.Sort '// 指定要素削除 Call aryList.Remove("AAA") '// 指定インデックス削除 Call aryList.RemoveAt(0) '// 複写 Set obj = aryList.Clone End Sub |
ArrayLlst用のクラスモジュールを用意する方法
ArrayListのメンバを明示するためにクラス化する方法です。
邪道と言われるかもしれませんが、プロパティやメソッドの入力がラクになり使い勝手が良くなります。
この方法はクラスモジュールと利用する側のモジュールを分けます。
まずクラスモジュールを作ります。クラス名はDNetArrayListです。
ArrayListのメソッドやプロパティを自作クラスのメンバ化するのが面倒な場合もあったりするので3行目のArrayListのインスタンスの変数arはPrivateではなくPublicにしています。 そのため上のコードのように直接使うことも可能です。
利用する側のモジュールはDNetArrayListクラスでなければ標準モジュールでもフォームモジュールでもなんでもいいです。
クラスモジュール:DNetArrayList
Microsoftのヘルプに書いてある全メンバは実装していません。必要最低限のプロパティやメソッドのみを実装しています。
追加したいプロパティやメソッドがある場合はクラスに追加するか、3行目の変数arに対して直接プロパティやメソッドを使ってください。
変数arに対して直接コーディングする方法は後述の利用例を参考にしてください。
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 |
Option Explicit Public ar As Variant '// ArrayListのインスタンス '// クラス初期化 Private Sub Class_Initialize() Call Init End Sub '// 初期化 Private Sub Init() Set ar = CreateObject("System.Collections.ArrayList") End Sub '// プロパティ '// 最大要素数設定 Public Property Let Capacity(i As Double) ar.Capacity = i End Property '// 最大要素数取得 Public Property Get Capacity() As Double Capacity = ar.Capacity End Property '// 要素数取得 Public Property Get Count() As Double Count = ar.Count End Property '// 固定サイズ状態取得 Public Property Get IsFixedSize() As Boolean IsFixedSize = ar.IsFixedSize End Property '// 要素設定 Public Property Set Item(i As Double, o As Variant) Set ar.Item(i) = o End Property '// 要素設定 Public Property Let Item(i As Double, o As Variant) ar.Item(i) = o End Property '// 要素取得 Public Property Get Item(i As Double) As Variant If (IsObject(ar.Item(i)) = True) Then Set Item = ar.Item(i) Else Item = ar.Item(i) End If End Property '// メソッド '// 追加 Public Function Add(o As Variant) As Integer Call ar.Add(o) End Function '// 全要素削除 Public Function Clear() Call ar.Clear End Function '// 簡易コピー Public Function Clone() Dim c As New DNetArrayList Set c.ar = ar.Clone Set Clone = c End Function '// 存在チェック Public Function Contains(o As Variant) As Boolean Contains = ar.Contains(o) End Function '// 要素インデックス取得 Public Function IndexOf(o As Variant) IndexOf = ar.IndexOf(o, 0) End Function '// 挿入 Public Sub Insert(i As Double, o As Variant) Call ar.Insert(i, o) End Sub '// 指定オブジェクト削除 Public Sub Remove(o As Variant) Call ar.Remove(o) End Sub '// 指定インデックス削除 Public Sub RemoveAt(i As Double) Call ar.RemoveAt(i) End Sub '// 反転 Public Sub Reverse() Call ar.Reverse End Sub '// ソート Public Sub Sort() Call ar.Sort End Sub |
DNetArrayListクラス利用例
コード自体は上の直接コーディングする方法とほとんど同じです。ただいくつか異なります。
2行目と4行目の型がObject型ではなくDNetArrayListクラスになっています。
また、CreateObject関数はクラス側に実装しているため利用するコードには不要なため存在しません。
40行目はクラスのプロパティ変数に対して直接Addメソッドを行っています。クラスに未実装のプロパティやメソッドを使いたい場合はこのような使い方も可能です。
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 |
Sub DNET_ArrayListTest2() Dim aryList As New DNetArrayList '// ArrayList用クラス Dim s '// 戻り値用 Dim obj As DNetArrayList '// Clone用 '// 追加 Call aryList.Add("111") Call aryList.Add("222") Call aryList.Add("333") Call aryList.Add("444") '// 書き換え aryList.Item(0) = "AAA" '// 取得 s = aryList.Item(0) '// 要素数 s = aryList.Count '// 反転 Call aryList.Reverse '// ソート Call aryList.Sort '// 指定要素削除 Call aryList.Remove("AAA") '// 指定インデックス削除 Call aryList.RemoveAt(0) '// 複写 Set obj = aryList.Clone '// 複写分のみ削除 Call obj.Clear '// プロパティ変数に直接追加 Call aryList.ar.Add("555") End Sub |