VBA

【VBA】配列が空かどうか判定する関数(エラー回避。コピペOK)

  • 配列が空かどうか判断します。
  • 配列から要素を取り出す際のエラーを回避できます。
  • 配列が全部Empty値かどうかも判断します。

こんにちは、hokkyokunです。

空の配列から要素を取り出そうとするとエラーが出て、
処理が止まってしまうことがあります。
エラーが出る前に、配列に要素が存在するかどうかを確認する関数です。

よくあるエラー

よくあるエラーとして、
配列の要素数を宣言しないままに
中身を呼び出すことです。

代表的なものを以下に示しました。
これを実行するとエラーが生じます。

Sub test_err()
    Dim arrs(0) As Variant
    Debug.Print arrs(0)
    '>> Empty値を呼び出すだけで、エラーは生じない
    
    Dim arrs2() As Variant
    Debug.Print arrs2(0)
    '>> 実行時エラー '9'
    '>> インデックスが有効範囲にありません。
    
    Dim arrs3 As Variant
    Debug.Print arrs3(0)
    '>> 実行時エラー '13'
    '>> 型が一致しません。
End Sub

配列空の状態には複数ある

処理をとめずにうまくプログラムを遂行するためには
配列が空かどうかを判断する必要があります。

配列は空であっても状態によってその反応が異なります。

  1. Dim arrs(0)と要素数を宣言している場合
    要素を呼び出してもエラーが生じない
    Empty値が格納されている状態
  2. Dim arrs()と要素数は宣言せず、()をつけた場合
    要素を呼び出すと実行時エラー9となる
  3. Dim arrs と()をつけない場合
    要素数を呼び出すと実行時エラー13となる

コード(コピペOK)

1.のエラーが生じない配列の状態は
あえてEmpty値を格納している場合もあるので、
ここではエラーが生じる場合の配列の状態を判定します。

'配列が空かどうか
'配列がすべてEmpty値であってもTrueとなります。
'ここでは、エラーを回避するために、配列の宣言が不十分な状態を回避することを目的とします。
Function Is_exist_array(arrs As Variant)
    Dim a As Long
    On Error GoTo err
    a = UBound(arrs)
err:
    If err.Number = 9 Or err.Number = 13 Then
        Is_exist_array = False
    Else
        Is_exist_array = True
    End If
End Function

実行してみます。

Sub test_is_exist_Array()
    Dim arrs(0) As Variant
    Debug.Print Is_exist_array(arrs)
    '>> 配列はEmptyだが要素数を宣言をしているのでTrue
    
    Dim arrs2() As Variant
    Debug.Print Is_exist_array(arrs2)
    '>> 実行時エラー '9'
    '>> False
    
    Dim arrs3 As Variant
    Debug.Print Is_exist_array(arrs3)
    '>> 実行時エラー '13'
    '>> False
End Sub

コード2(要素がすべてEmpty値)

エラーが生じない場合でも
全ての要素がEmptyの場合もあります。

この場合は

  • 要素がうまく入れられていない場合
  • あえてEmpty値を入れている場合

の二パターンがあると思います。
全ての要素がEmpty値がどうかはこちらを使用してください。

'エラーが出ない状態でも配列の要素すべてEmpty値はありえます。
'すべての要素がEmpty値の場合を判定します。
Function Is_empty_array(arrs As Variant)
    Dim arr As Variant
    
    'ここでは配列の宣言が不十分な状態を配列が定義されていないと表現します。
    If Not Is_exist_array(arrs) Then
        MsgBox ("配列が定義されていません")
        Is_empty_array = False
        Exit Function
    End If
    
    For Each arr In arrs
        If TypeName(arr) = "Empty" Then
            Is_empty_array = True
            Exit Function
        End If
    Next
End Function

実行してみます。

Sub test_is_empty_Array()
    Dim arrs(0) As Variant
    Debug.Print Is_empty_array(arrs)
    '>> 要素すべてがEmpty値
    '>> True
    
    Dim arrs2() As Variant
    Debug.Print Is_empty_array(arrs2)
    '>> 実行時エラー '9'の配列が空の状態
    '>> False
    
    Dim arrs3 As Variant
    Debug.Print Is_empty_array(arrs3)
    '>> 実行時エラー '13'の配列が空の状態
    '>> False
End Sub