0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

VBAでAs Newするときの注意事項(別インスタンスにならない問題)

Posted at

ループ内で毎回クラスを初期化するとき、VBAでループ内でAs Newをしても、ループ2回目以降、hogehogeの内容は別インスタンスになりません。
この記法はVB.NETと大きく違う部分です。注意しましょう。

駄目な例

以下の例は、Class1をループ内で初期化することを目論見、Forループ内でAs Newしつつ、Collectionsに値を格納していくサンプルコードです。

クラス

Class1
' ===== クラスモジュール: Class1 =====
Option Explicit

Public a As Long

モジュール

Module1
' ===== モジュール: Module1 =====
Sub test
    Dim i As Long
    Dim j As New Collection

    'Collectionの中身を入れる
    For i = 1 to 10
        Dim hogehoge As New Class1
        '↑VB.NETではこの記法で別インスタンスになるが、
        'VBAではこれを実施しても別インスタンスにならない
        hogehoge.a = i
        j.Add hogehoge
    Next i
    
    'Collectionの中身を確認
    For i = 1 to 10
        Debug.Print hogehoge.a
    Next i
End Sub

実行結果(イミディエイト)

10
10
10
10
10
10
10
10
10
10

どうすればいいのか

正しくは以下のようにしましょう。
For ループの中で別インスタンスを格納したい場合には、VBAでは必ず「Set」することが必要です。
As Newすれば別インスタンスが格納される という先入観で作ってしまうと間違いの元になります。

訂正後のモジュール

Module1
' ===== モジュール: Module1 =====
Sub test
    Dim i As Long
    Dim j As New Collection
    Dim hogehoge As Class1           '先に型だけ宣言する

    'Collectionの中身を入れる
    For i = 1 to 10
        Set hogehoge = New Class1
        '↑別インスタンスにしたいなら必ず毎回Setする!
        hogehoge.a = i
        j.Add hogehoge
    Next i

    'Collectionの中身を確認
    For i = 1 to 10
        Debug.Print hogehoge.a
    Next i
End Sub

訂正後の実行結果(イミディエイト)

1
2
3
4
5
6
7
8
9
10
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?