19
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ZOZOテクノロジーズ #3Advent Calendar 2019

Day 1

VBScriptで「まともな」配列を使う方法

Last updated at Posted at 2019-11-30

VBScriptの配列は色々と制限が多いので、RubyやPythonなどの他のスクリプト言語を使ったことがある人は他の言語では簡単にできることがVBScriptでは出来なくイライラする事が多いと思います。
C言語で配列(と言う名前の実質ポインターのシンタックスシュガー)を扱ったことがある人なら、それと似た感じといえば通じる辛さです。

特に動的配列を扱うことが苦手な印象をうけます。
例えば、以下のように Dim arr(2) と宣言した要素数3の配列の要素数を後から増やしたくなったときに辛い思いをします。

Dim arr(2)
arr(0) = "hoge"
arr(1) = "fuga"
arr(2) = "piyo"

arr(3) = "hogehoge" ' ここで要素を増やすことが出来ない

また、配列の要素数の指定は定数にする必要があるのも面倒です。

Dim str, num
str = InputBox("input number")
num = CInt(str)

Dim arr(num) ' ERROR! 要素数を変数として与えることが出来ない

配列を宣言するときに、要素数を指定しなければある程度は柔軟に要素数を変えることも出来ますが、ReDimするときにPreserveを指定し忘れて要素をすべて消したことのある経験をしたことのある人は少なくないと思います。
また、要素数の変更が柔軟になったとしても、RubyやPythonの配列の足元にも及びません。

解決策

.NET FrameworkのArrayListを使う。
あまり知られていないテクニックですが、VBScriptのCreateObjectで.NET Frameworkのオブジェクトを生成することが可能です。
そのため、.NET Framework側のデータ構造を使うことが出来ます。
System.Collectionsの名前空間を見ると沢山のデータ構造がありますが、今回は一番汎用的に使えそうなArrayListを使ってみることにします。

Dim arr
Set arr = CreateObject("System.Collections.ArrayList")

' 末尾に要素追加
arr.add "hoge"
arr.add "fuga"

' ソート
arr.Sort

' 特定の要素を取得
Dim s
s = arr(1)

' 要素を順番に取得
Dim element
For Each element In arr
  Wscript.Echo element
End For

' VBScriptの配列に変換
Dim vbsarr
vbsarr = arr.ToArray()

ArrayListを生成するところだけちょっと面倒くさいですが、他の部分はほぼ違和感なく使うことが出来ています。
生成をする部分は短い名前のヘルパー関数を作ると便利になるかもしれません。

System.CollectionsにはArrayList以外のデータ構造もたくさんあるので、これらを活用することによって、VBScriptの貧弱なデータ構造をリッチにすることが出来ます。
他にもScripting.Dictionaryが貧弱だと感じている人はSystem.Collections.HashTableを使うことで他のスクリプト言語とほぼ同等の機能をもった連想配列を使うことが出来ます。

19
6
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?