7

この記事は最終更新日から1年以上が経過しています。

@nukie_53

オブジェクト型配列→Variant型の罠

VBAではVariant型に配列を代入することができる。
このとき、値型配列では正しく型が伝播され、特に問題は起きない。

Sub 値型配列の場合、正しく型が伝播する()
    Dim Lngs() As Long
    ReDim Lngs(0 To 1)

    Dim tmp As Variant
    tmp = Lngs

    Debug.Print VBA.TypeName(Lngs)  'Long()
    Debug.Print VBA.TypeName(tmp)   'Long()

    tmp(0) = 1
    'tmp(1) = "a"    ’エラー Long型にStringは入らないので

    Lngs = tmp
    Stop
End Sub

対して、具象オブジェクト型配列をVariant型に入れるとObject型配列として扱われ、具象型によるフィルターが効かなくなる(Variant型ではそこまでの情報を保持できないため)。

Sub 動的オブジェクト配列の罠()
    Dim cols() As VBA.Collection
    ReDim cols(0 To 1)

    Set cols(0) = New VBA.Collection
    'Set cols(1) = Err   'エラー 型が一致しません。→OK

    Dim tmp As Variant
    tmp = cols

    Debug.Print VBA.TypeName(cols)  'Object()
    Debug.Print VBA.TypeName(tmp)   'Object()

    Set tmp(0) = New VBA.Collection
    Set tmp(1) = VBA.Err

    cols = tmp  '←!?


    Set cols(0) = cols(1)   '←!?
                  '↑ErrObject
    Stop
End Sub

DynamicObjectArray.png

まとめ

Variant型は便利だが、具象オブジェクト型配列を入れる場合注意が必要。
汎用性を落として良い場面では、引数の型・戻り値の型を対象オブジェクト型の配列として宣言すること。
Genericコレクションが欲しい。

7
ユーザー登録して、Qiitaをもっと便利に使ってみませんか。
  1. あなたにマッチした記事をお届けします
    ユーザーやタグをフォローすることで、あなたが興味を持つ技術分野の情報をまとめてキャッチアップできます
  2. 便利な情報をあとで効率的に読み返せます
    気に入った記事を「ストック」することで、あとからすぐに検索できます
nukie_53
Excel・PowerPoint の VBA、Windows PowerShell がメインの人です。 Word・Outlook の VBA も多少は読めます。 データベース関連や、管理用途の PowerShell は経験なし。 PowerShell の延長で、C# も雰囲気は読める感じです。
この記事は以下の記事からリンクされています

コメント

この記事にコメントはありません。
あなたもコメントしてみませんか :)
ユーザー登録
すでにアカウントを持っている方はログイン
記事投稿イベント開催中
自社サービスの技術スタック公開
~
開発環境を豊かにする開発事例
~