teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

2

12/26のコメントに対する回答を追記

2017/12/26 12:55

投稿

imihito
imihito

スコア2166

answer CHANGED
@@ -101,4 +101,53 @@
101
101
  Type Person
102
102
  Name As String
103
103
  End Type
104
- ```
104
+ ```
105
+
106
+ ---
107
+
108
+ 17/12/26追記
109
+
110
+ > Dim Tanaka As Collection
111
+ Set Tanaka = members.Item("Tanaka")
112
+ Dim Yamada As Collection
113
+ Set Yamada = members.Item("Yamada")
114
+ 上記4行をfor文で動的にしたくて
115
+ For ii = LBound(people) To UBound(people)
116
+ members.Add New Collection, people(ii)
117
+ Dim people(ii) As Collection
118
+ Set people(ii) = members.Item(people(ii))
119
+ Next ii
120
+ としました。
121
+
122
+ 結論から申し上げると**「VBAでは不可能」**です。
123
+
124
+ VBAではプロシージャの実行時に使用する変数を全て初期化するため、実行するまで名前の決まらない変数は作成できません。
125
+
126
+ 出来たとしても、エディタの支援を全て投げ捨てることになるため、ただやりにくいだけになるかと思います。
127
+
128
+
129
+ 雰囲気だけなら以下のような書き方もできますが、私個人としてはオススメしません。
130
+
131
+ ```vba
132
+ With members
133
+ 'members!Tanaka と members("Tanaka") は同じ意味
134
+
135
+ !Tanaka.Add 25, "age"
136
+ !Tanaka.Add 90, "number"
137
+
138
+ !Yamada.Add "test@test.com", "mail"
139
+ !Yamada.Add "tokyo", "addres"
140
+
141
+ MsgBox !Tanaka.Item("age")
142
+ MsgBox !Yamada.Item("mail")
143
+
144
+ End With
145
+ ```
146
+
147
+ ## おまけ:エラーの原因
148
+
149
+ `Dim people(ii) As Collection`は純粋に`people`という名前の変数の宣言だと解釈されます。
150
+ さらに`(ii)`となっているため、静的な配列(要素数が固定の配列)変数の宣言と解釈されます。
151
+ しかし`ii`は変数のため、定数ではありません(固定されていません)。
152
+ 結果として、「静的配列の変数宣言に定数を使っていない」と解釈され、「定数式が必要です。」のコンパイルエラーが発生します。
153
+ 実際は変数宣言も重複しているため、「定数式が必要です。」を解消しても「同じ適用範囲内で宣言が重複しています。」のコンパイルエラーが発生します。

1

エラーの理由追記

2017/12/26 12:55

投稿

imihito
imihito

スコア2166

answer CHANGED
@@ -71,10 +71,34 @@
71
71
 
72
72
  配列の添え字に文字列は使えないので
73
73
 
74
- ```
74
+ ```vba
75
75
  Set Member(people(ii)) = New Collection
76
76
 
77
77
  Set Member(ii) = New Collection
78
78
  ```
79
79
 
80
- としか書けません。
80
+ としか書けません。
81
+
82
+
83
+ ```vba
84
+ Member(people(ii)) As Collection
85
+ ```
86
+ の意図がいまいちわかりませんでしたが、もしかして型変換をしようとしているのでしょうか?
87
+
88
+ VBAでは値型のみ`CStr`などの関数で型変換できますが、それ以外は「その型の変数に入れる」ぐらいしか方法がありません。
89
+
90
+ なぜ`Type ブロック外では無効なステートメントです。`のエラーが発生したかをざっくり説明すると
91
+ ユーザー定義型のフィールド宣言の構文と同じ書き方をしたためです。
92
+
93
+ 上記の行には予約後の`As`が入っているため、変数宣言などの一種だと解釈されます。
94
+ しかし行頭に`Dim`などが存在しないため普通の変数宣言ではありません。
95
+ `As`を使いつつ、行頭に`Dim`などが無いパターンはユーザー定義型のフィールド宣言時のみとなります。
96
+ しかし、書かれている場所は`Type~End Type`(Typeブロック)で囲まれていないため、`Type ブロック外では無効なステートメントです。`のエラーが発生します。
97
+
98
+ ```
99
+ 'ユーザー定義型の定義
100
+ 'Personという名前でNameというString型のフィールドを持つ型
101
+ Type Person
102
+ Name As String
103
+ End Type
104
+ ```