配列のサイズを宣言する前にサイズを知りたかった
だいぶ意味不明なタイトルですが。
VBAではサイズを指定せずに配列を宣言できます。
(指定して宣言することもできます)
' 文字列が入る配列(サイズ不明) Dim sArray() As String
その場合、後からサイズを指定できます。
' 文字列が入る配列(サイズ不明) Dim sArray() As String ' 配列のサイズを3にする ' ※下記のように指定すると「0~2」の3つ ReDim sArray(2)
また、配列の最大添字を調べる関数「UBound」というものがあります。
配列のサイズを調べたい場合によく使います。
' 文字列が入る配列(サイズ不明) Dim sArray() As String ' 配列のサイズを3にする ' ※下記のように指定すると「0~2」の3つ ReDim sArray(2) ' 配列の最大添字をデバッグに表示 ' ※「2」が表示される Debug.Print UBound(sArray)
ただし、以下のように、配列のサイズを指定しないままこの関数を使おうとすると
「インデックスが有効範囲にありません。」とかいうエラーになります。
' 文字列が入る配列(サイズ不明) Dim sArray() As String ' 配列の最大添字をデバッグに表示したかった ' <ここでエラー!> Debug.Print UBound(sArray)
IF文で「もし配列が空、というかサイズ未指定というか、要するに空なら」という処理を作りたい場合はどうすれば…と思って調べると、以下2つの方法をよく見かけます。
【①Not Not hoge】
よく「何故動くのか分かりませんが」と前置きされて書かれているこちらの方法。
すごい。意味がわからない。しかもきもい。
' 文字列が入る配列(サイズ不明) Dim sArray() As String ' 配列のサイズが指定済みかどうか If Not Not sArray Then MsgBox "サイズ指定済" Else ' こちらが出ます MsgBox "サイズ未指定" End If
【②Sgn(hoge)】
すごい。こっちも意味がわからない。
「Sgn関数にサイズ未指定の配列を渡すとゼロが返ってくるからそれで判定」ってやばい。
※Sgn関数は数値の符号を返す関数です
' 文字列が入る配列(サイズ不明) Dim sArray() As String ' 配列のサイズが指定済みかどうか If Sgn(sArray) <> 0 Then MsgBox "サイズ指定済" Else ' こちらが出ます MsgBox "サイズ未指定" End If
あとは自力で判定する関数を作るなりするか、APIを使うか…という感じです。
参考:VBAの動的配列で要素を宣言する前の状態をチェックする方法 - アイビースター
http://ivystar.jp/ms-office/how-to-check-the-status-of-before-declaring-an-element-in-the-dynamic-array-of-vba/
①も②も意味不明っぷりが結構すごいですが、ネットで調べた感じではこの方法が一般的な様子…?
技術系ブログに「なんで動くか分からないけど動くからこれで」って書かれることはそうそうないと思うんですがこれに関しては何故かそう書いてる人がやたら多い。やばい。
まあわたしもそれ見て何故か②を使っていたんですが。動くし。
…。
…動くと思ってたんですよ。
動いてたんですよ、自分のPCでは。
社内のExcelのバージョンは皆同じなはずなのに、何故かこの処理が動く人と動かない人がいることが判明するまでは、動くと思ってたんですよ…。
最終的には、サイズ未指定だとエラー扱いにしたいプログラムだったので、
単純に「On Error GoTo ラベル」で制御する方法にやっつけ修正しました…。
Public Sub hoge() ' 文字列が入る配列(サイズ不明) Dim sArray() As String ' エラー時はエラーラベルへ飛ばしてね宣言 On Error GoTo ErrorLabel ' 配列の最大添字をデバッグ表示 ' <ここでエラーになりエラーラベルへ飛ぶ> Debug.Print UBound(sArray) MsgBox "サイズ指定済" Exit Sub ' エラーラベル ErrorLabel: ' デバッグ表示はされず、これが出る MsgBox "サイズ未指定" End Sub
Sgn関数での判定が動くPC・動かないPCの違いは何だろうな。
ご存じの方がいらっしゃいましたら、情報をいただけると大変ありがたいです。