【VBA】スタックを実装する

概要
以前VBAでキューを実装しました。今回はVBAでスタックを実装してみます。
https://kazusa-pg.com/vba-queue/
スタックの概要
スタックとは、コンピュータプログラムで使われるデータ構造のひとつです。
最後に入れたデータが最初に取り出されるLIFO(Last In First Out)といわれるデータ構造になります。
スタックを使用すると、データを一番最後に追加したものから順に取り出すことができます。
スタックにデータを追加することを「プッシュ(Push)」、スタックからデータを取り出すことを「ポップ(Pop)」と呼びます。
例えば、数字のリストがあるとして、このリストをスタックとして使用することで
最後に追加された数字から順に取り出すことができます。
スタックの実装
クラスモジュールを使用して、スタックを実装します。下記の機能を実装してみます。
- 動的配列を利用してスタックを実装する。
- スタックにデータを入れるpushメソッドを実装する。
- スタックからデータを取り出すpopメソッドを実装する。
- スタック内のデータ数を取得するcountメソッドを実装する。
- スタックの内容をVariant型の配列として返すgetContentsメソッドを実装する。
- スタックにデータが無い時にpopを実行するとエラーをraiseする。エラーの番号は1001とする。
スタックのクラスモジュールは以下になります。
1Option Explicit
2
3Private ary() As Variant '配列をスタックとして利用
4Private size As Long 'スタックの現在のサイズ
5
6Private Sub Class_Initialize()
7 'コンストラクタ
8
9 ReDim ary(0)
10 size = 0
11
12End Sub
13Public Sub push(v As Variant)
14 'スタックの一番上にデータを追加する
15
16 size = UBound(ary) + 1
17 ReDim Preserve ary(size)
18
19 Dim vType As Long
20 vType = VarType(v)
21
22 Select Case vType
23 'オブジェクト、データアクセスオブジェクト、ユーザー定義型は
24 'Set構文を利用する
25 Case vbObject
26 Set ary(size) = v
27 Case vbDataObject
28 Set ary(size) = v
29 Case vbUserDefinedType
30 Set ary(size) = v
31 Case Else
32 ary(size) = v
33 End Select
34
35End Sub
36Public Function pop() As Variant
37 'スタックの一番上のデータを取り出す
38
39 If size = 0 Then
40 'スタックにデータが存在しないときは、エラー番号1001をRaiseする
41 Err.Raise 1001, "Stack", "スタックにデータが存在しません"
42 End If
43
44 Dim vType As Long
45 vType = VarType(ary(size))
46
47 Select Case vType
48 'オブジェクト、データアクセスオブジェクト、ユーザー定義型は
49 'Set構文を利用する
50 Case vbObject
51 Set pop = ary(size)
52 Case vbDataObject
53 Set pop = ary(size)
54 Case vbUserDefinedType
55 Set pop = ary(size)
56 Case Else
57 pop = ary(size)
58 End Select
59
60 size = size - 1
61 ReDim Preserve ary(size)
62
63End Function
64Public Function count() As Long
65 'スタックのデータ数を返す
66
67 count = size
68
69End Function
70Public Function getContents() As Variant
71 'スタックの内容を配列として返す
72 'インデックス1が一番下のデータ
73
74 getContents = ary
75
76End Function
スタッククラスのテスト
スタッククラスをテストするコードは以下になります。
1Option Explicit
2Sub test_Stack()
3
4 Dim s As Stack
5 Set s = New Stack
6
7 s.push 1
8 Dim c As Collection
9 Set c = New Collection
10 c.Add "valueテスト", "keyテスト"
11 s.push c
12 s.push "a"
13
14 MsgBox "スタックのデータ数は" & s.count & "個です。"
15
16 Dim ary() As Variant
17 ary = s.getContents
18
19 MsgBox "スタックから取り出したデータは" & s.pop & "です。"
20 Dim returnC As Collection
21 Set returnC = s.pop
22 MsgBox "スタックから取り出したデータは" & returnC("keyテスト") & "です。"
23 MsgBox "スタックから取り出したデータは" & s.pop & "です。"
24 MsgBox "スタックから取り出したデータは" & s.pop & "です。"
25
26 Set s = Nothing
27
28End Sub
1 s.push 1
2 Dim c As Collection
3 Set c = New Collection
4 c.Add "valueテスト", "keyテスト"
5 s.push c
6 s.push "a"</pre>
1→collection(value=”valueテスト”,key=”keyテスト”)→”a”の順でスタックにデータを3個追加します。
1MsgBox "スタックのデータ数は" & s.count & "個です。"
Stackクラスのcountを実行すると、現在のスタックの個数を表示します。
先程データを3つ追加したので3個と表示されます。

1 Dim ary() As Variant
2 ary = s.getContents
getContentsを利用して、スタックの内容を配列に格納しています。
1 MsgBox "スタックから取り出したデータは" & s.pop & "です。"
2 Dim returnC As Collection
3 Set returnC = s.pop
4 MsgBox "スタックから取り出したデータは" & returnC("keyテスト") & "です。"
5 MsgBox "スタックから取り出したデータは" & s.pop & "です。"
6 MsgBox "スタックから取り出したデータは" & s.pop & "です。"
スタックからデータを取り出しています。 最後に追加したものから順々に取り出していきます。 “a”→collection(value=”valueテスト”,key=”keyテスト”)→1
collection型はMsgboxで直接表示できないので、一旦変数に代入し、キーを指定して値を表示しています。



スタックに値がない状態でpopを実行するとエラー番号は1001をraiseします。
