VBA

【VBA】配列が空かどうかを判定する関数とエラー回避する関数

記事内に商品プロモーションを含む場合があります

こんにちは、hokkyokunです。
配列はプログラミングの基本です。

私はたくさん業務効率化用のプログラムを書いてきましたが
配列を使わないプログラムはほとんどないです。

VBAの配列ってちょっと苦手…

エラーも結構生じるし
あんまり使いたくないな…

動的配列とか静的配列とか
難しい…

要素を追加するためには
要素数を変更しなければいけない

こういう不満、あると思います。

VBAの配列は結構不便なので
色々とオリジナル関数を使って作業効率をアップさせています。

今回はその起点となる
配列が空の状態かどうかを判定する関数です。

空(から)の状態を分析

配列に要素が何も入っていない状態=空と定義すると

  1. エラーが生じる状態
  2. エラーが生じない、Emptyが入った状態

の二つの状態があります。

この内重要なのは
①のエラーが生じる空の状態を把握することです。

②のEmptyが入った状態は
基本的には静的配列(宣言時に要素数を指定する配列)を扱わない限り
あまり出会いません

よって②は基本的に無視していいです。
(おまけでEmptyが入った状態を判断する関数を掲載しています。)

  • 配列が空の状態には二種類ある
    エラーが生じるか生じないか
  • エラーが生じない空は静的配列を使わなければ起きない
    静的配列は基本的に使わなくていい
  • よってエラーが生じる配列が空の状態を把握すればOK

なぜ空の状態を把握する必要があるのか

配列に要素を追加する
プログラムを考えてみます。

①要素が空でない状態の場合

Sub test()
    Dim arrs As Variant
    Dim num As Long
    
    '適当な要素を入れておく
    arrs = Array("リンゴ", "バナナ", "パイナップル")
    
    num = UBound(arrs)
    
    ReDim Preserve arrs(num + 1)
    arrs(num + 1) = "メロン"
    
End Sub

これは正常に動きます。

②配列が空の状態(エラーが生じる場合)

一方で、配列が空の状態(エラーが生じる場合)で
上記と同じプログラムを動かしてみます。

Sub test2()
    Dim arrs As Variant
    Dim num As Long
    
    num = UBound(arrs)
    
    ReDim Preserve arrs(num + 1)
    arrs(num + 1) = "メロン"

End Sub

この場合、以下のようなエラーが生じます。

原因は配列の要素数を定義しないまま
要素を追加したためです。

  • 空かどうかの状態を把握する必要があります。
  • これらを把握しないと
    エラーが生じる可能性が高くなります。

空の状態を把握しないと
要素の追加など、派生する処理がうまくいかない可能性が出てくる

スポンサーリンク




エラーの内訳

配列が空の状態には二種類あり、
エラーが生じる配列が空の状態の把握が重要と書かせていただきました。

これらの内訳を確認してみます。

エラー1:宣言時に()をつけて、要素数を宣言しない

宣言時に変数の後ろに()をつけるが
要素数を入れない場合です。

配列だと認識されているようですが、
指定したインデックスが一つもないので何を入れてもエラーが出ます。

Sub test_err()

Dim arrs() As Variant
Debug.Print arrs(0)

End Sub
実行時エラー9が出てプログラムが止まります。

実行時エラー ’9′
インデックスが有効範囲にありません。

が出てプログラムが止まります。

エラー2:()をつけないで要素を取り出す

変数宣言時に変数の後ろに()をつけないでみます。

この場合、配列という判断をしてくれないので、
「型が一致しない」と怒られます。

Sub test_err()

Dim arrs As Variant
Debug.Print arrs(0)

End Sub

実行時エラー ’13’
型が一致しません。

が出てプログラムが止まります。

基本的にエラーが生じる配列が空の状態はこの二種類です。
この二つの状態を把握すればOKです。

  • エラーが生じる配列が空の状態は以下の二つ
    変数宣言時に()をつけて要素数を宣言しない
    変数宣言時に()をつけない

おまけ

これはエラーにならない

エラーになりそうでならないパターンです。

宣言時に要素数を宣言するが、
要素を入れないまま要素を取り出す。

何を言ってるかわかりずらいですが、以下のようなコードです。

Sub test_err()
    Dim arrs(0) As Variant
    Debug.Print arrs(0)
    '>> Empty値を呼び出すだけで、エラーは生じない
    
End Sub

静的配列:宣言時に()を付けて、宣言した要素数以上で指定

今度は()を付けたけど、
宣言した要素数以上の数を指定して取り出してみます。

Sub test_err()

Dim arrs(1) As Variant
Debug.Print arrs(99)

End Sub
実行時エラー9が出てプログラムが止まります。

実行時エラー ’9′
インデックスが有効範囲にありません。

が出てプログラムが止まります。
同様です。

お分かりになりますでしょうか
これは静的配列として扱っています。

繰り返しになりますが、
静的配列は業務効率化のツールとしてVBAを使うなら全く使う必要はありません。

よって、基本的にはこのエラーは想定しません。

関数(コピペOK)

オリジナル関数を二つ作成しました。

一つは繰り返し重要になる
エラーが生じる配列が空の状態の把握関数

もう一つはEmptyが入った状態を把握する関数です。

基本的には①を使って状態を把握し、
要素の追加などの処理をエラーを発生させず進めていきます。

  • Is_correct_array関数
    エラーが生じる配列が空の状態を把握する関数
  • Is_empty_array関数
    配列に含まれる要素が全てEmptyであるかどうかを判断する関数
  • Is_correct_array関数を使って
    様々な配列の処理を円滑に進める

Is_correct_array関数:エラー回避関数

配列がエラー状態なのかどうかを判断します。

  • 関数名
    Is_correct_array( arrs )
  • 引数
    arrs : 配列(データ型はVariant)
  • 戻り値
    ブール型(エラーが生じない=True、エラーが生じる=False)
Function Is_correct_array(ByVal arrs As Variant)
    Dim a As Long
    
    'なんでもいいが、エラーを生じさせる
    On Error GoTo err
    a = UBound(arrs)

    'エラーが生じたときエラー番号で9か13の場合はFalse
err:
    If err.Number = 9 Or err.Number = 13 Then
        Is_correct_array = False
    Else
        Is_correct_array = True
    End If
    
End Function

実行してみます。

Sub test_Is_correct_Array()
    Dim arrs() As Variant
    Debug.Print Is_correct_array(arrs)
    '>> 実行時エラー '9'
    '>> False
    
    Dim arrs2 As Variant
    Debug.Print Is_correct_array(arrs2)
    '>> 実行時エラー '13'
    '>> False
End Sub

スポンサーリンク



Is_empty_array関数:要素がすべてEmpty値かどうかの判定

同じことの繰り返しになりますが、
エラーの生じる空の状態か、Emptyが入っている空の状態かのパターンがあります。

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

全ての要素がEmpty値がどうかの判断が必要な場合は
こちらを使用してください。

  • 関数名
    Is_empty_array(arrs )
  • 引数
    arrs : 配列(データ型はVariant)
  • 戻り値
    ブール型(全てEmpty=True、そうではない=False)
'エラーが出ない状態でも配列の要素すべてEmpty値はありえます。
'すべての要素がEmpty値の場合を判定します。
Function Is_empty_array(arrs As Variant)
    Dim arr As Variant
    
    'ここでは配列の宣言が不十分な状態を配列が定義されていないと表現します。
    If Not Is_correct_array(arrs) Then
        Debug.Print "配列が定義されていません"
        Is_empty_array = False
        Exit Function
    End If
    
    Is_empty_array = True
    '一つでも要素がEmptyではない場合はFalseにする
    For Each arr In arrs
        If TypeName(arr) <> "Empty" Then
            Is_empty_array = False
            Exit For
        End If
    Next
End Function

実行してみます。

Sub test_is_empty_Array()
    Dim arrs(2) As Variant
    Debug.Print Is_empty_array(arrs)
    '>> 要素すべてがEmpty値
    '>> True
    
    arrs(0) = 1
    Debug.Print Is_empty_array(arrs)
    '>> 要素すべてがEmpty値ではない。
    '>> False
    
    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

スポンサーリンク




まとめ

いかがでしたでしょうか。
まとめてみます。

まとめ
  • 配列が空の状態には二種類ある
    ①エラーが発生する状態
    ②エラーが出ずEmptyが要素として入った状態
  • ①エラーが生じる空かどうかの判定
    Is_correct_array関数
  • ②エラーが出ず、Emptyが入った状態かどうかの判定
    Is_empty_array関数

配列を便利に使いやすくする関数を作っています。

VBAの学習方法をまとめました。

VBA(マクロ)のおすすめの学習方法 こんにちはhokkyokunです。 VBAを学ぶことで確実に業務は効率化し、余裕をもって仕事をすることができるようになります。 ...
【Udemyは講師で選べ!】UdemyがVBA学習に最適な理由とおすすめのVBA講師 こんにちはhokkyokunです。 巨大学習プラットホームUdemyの中からVBAに関する動画について講師に焦点を当ててまとめま...