VB6・VBAメモ:定数配列の代替案

VB6やVBAでは配列の定数を定義したい場合、
以下のように記述しても構文エラーが発生してしまいます。

Const c_StrArray() As String _
            = Array("abcde", "fghih", "klmno")

これは.NETでは対応しているらしいですが、
VB6やVBAでは配列を定数として定義することができないらしいです。

ですが、定数を1つ1つ定義するのはめんどくさいので
定数配列の代替案を2点メモしておきます。

まず考えられるのはGetプロパティやFunctionを使う方法です。

'代替案
Property Get c_StrArray(ByVal vIdx As Long) As String
	Dim wRet As String
	'----------------
	Select Case vIdx
	Case 0 : wRet = "abcde"
	Case 1 : wRet = "fghih"
	Case 2 : wRet = "klmno"
	End Select
	'----------------
	c_StrArray = wRet
End Property 

Sub Main()
	Dim i As Long
	For i = 0 To 2
		Debug.Print c_StrArray(i)
	Next i
End Sub

これは単純に引数を添え字として扱っているだけです。
ここでは読み取り専用の意味として「Property Get」で記述していますが「Function」でも問題はないです。

しかし、これでは配列を1行で書くことができないので私はあまり好きではありません。
(構造体の定数配列の場合はこれがベストかもしれませんが)

私が良く使う方法は下記のSplit()を使う方法です。

'代替案
Const c_StrArray AS String = "abcde,fghih,klmno"

Sub Main()
	Dim i As Long
	Dim wStrArray() As String

	wStrArray = Split(c_StrArray, ",")

	For i = 0 To UBound(wStrArray )
		Debug.Print wStrArray (i)
	Next i

	'以下の方法だとメモリリークするらしいので上記に修正しました。
	'For i = 0 To UBoundSplit(c_StrArray, ","))
	'	Debug.Print Split(c_StrArray, ",")(i)
	'Next i
End Sub

この方法の利点はUBound()で配列の要素数も取れるというところです。
※(追記)コメントでご指摘いただきましたが、「UBound(Split(c_StrArray, ","))」のように、
 UBound / LBound に配列の戻り値を渡すとメモリ リークが発生するらしいです。
 少し面倒になりますが、Split()の戻り値はローカル変数に格納して操作したほうが良さそうです。

欠点は区切り文字は定数に使用できないことですが、
これは「 」なり「/」なり状況に応じて変えれば良いので大した問題ではないかと思います。

また、文字列型以外を定数配列にしたい場合は、
都度CLng()等で型変換するしかないので少し面倒かもしれません。


なお、VB6のアドインで作成したリソースファイルから
文字列を呼び出すLoadResString()という関数もあるそうですが、
Split()が一番手軽なので私はこちらを利用しています。


コメント
その使い方だとメモリリークしますよ。
http://support.microsoft.com/kb/197190/ja


  • 2010/03/20 4:05 PM
うわっ、メモリリークしちゃうんですね!?
となるとワンクッション必要になっちゃうんですね。

VBは簡単ですけど、こういうところは面倒ですよね…。

指摘されなければ気づけない問題でした。
ありがとうございました!
  • 謎猫
  • 2010/03/21 11:35 PM
コメントする








    
この記事のトラックバックURL
トラックバック