プチIT化

【VBA配列定義】Array:配列には割り当てられません。というエラーはなぜ出るか

こんにちは、わたあめです。今日はExcelのマクロネタです。1次元配列を一度に(一行でまとめて)定義しようと、Array関数を利用して以下のようなVBAマクロを作成しました。

Sub test()

Dim testMonth(12) As Variant
testMonth = Array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)

End Sub

が、実行すると以下のとコンパイルエラーが出てしまいました。

配列には割り当てられません。

Integer型とかの配列の要素ひとずつ定義すれば問題ないという事なのですが、今回はArray関数使いたいと、調査することにしました。それでは、いってみましょう!

原因

Variant型の定義方法が間違っていたからでした。ブログネタにする?という凡ミス過ぎて申し訳ありません…。解決方法としては、定義の時に配列の数を指定しなければOKでした。

書き方として正しいのは以下です。

Sub test()

Dim testMonth As Variant
testMonth = Array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)

End Sub

"testMonth(12)"を"testMonth"にしただけです。配列として宣言してないが、配列と同じように操作できるようです。ちなみに"testMonth()"と括弧の中に数値を入れないバージョンでも問題なく動きましたよ。

わたあめ
わたあめ
なぜか?と言うのを次章から深堀してみたよ。

Array関数を使った定義について

リファレンスを参照してみると、Array関数は引数のarglistにVariant型の要素を扱うように書かれていました。つまり、Array関数ではVariant型を扱うと決まっているのです。

Integer型などで定義した場合は、「実行時エラー13:型が一致しません」というエラーになりました。

で、Variant型は動的配列なので要素数は指定しないでOKみたいなんです。むしろ今回は指定してしまったがためにエラーとなってしまったという。

わたあめ
わたあめ
ついつい他の配列と同じように要素数を定義しがちだけど、気を付けよう!(自戒)

おまけ:Array関数のメモリアドレスの確認

気になったので、VarPtr関数を利用して、今回Arrayで定義したメモリアドレスを表示してみました。

testMonth(0) 438529664
testMonth(1) 438529680
testMonth(2) 438529696
testMonth(3) 438529712
testMonth(4) 438529728
testMonth(5) 438529744
testMonth(6) 438529760
testMonth(7) 438529776
testMonth(8) 438529792
testMonth(9) 438529808
testMonth(10) 438529824
testMonth(11) 438529840

+16ずつアドレスがカウントアップされています。数値のVariant型はひとつの領域が16Byteなので+16。Variant型もアドレスは連続してましたね。(毎回なのかな?)

ちなみに、Dimするときに"testMonth"と"testMonth()"と定義の仕方が二通りできました。メモリのアドレス確保とかが違うのかな?と思いきや、アドレスは変わらず。値の呼び出し方も一緒だから、厳密に何が違うのかな、と疑問に思ったりです。

さいごに

関数の使い方、何となくだとエラーに引っ掛かっちゃいますね。配列定義する関数でしょ?という感じで適当に書いてしまったことが原因でのエラーでした。

ところで、今回つかったVariant型。柔軟な型ですが、今回のように数値だけと決まっている場合はめんどくさがらずにInteger型できちんと宣言とかした方が綺麗ですよね。ずぼらです。(よくない)

それでは、また!

flier(フライヤー)