オブジェクト変数の宣言方法
VBAでオブジェクト変数を宣言する際、2通りの書き方があります。
-
宣言とオブジェクトのSetを分けて2行で書く場合
Dim x As MyClass Set x = New MyClass
-
宣言と同時にNewして1行で書く場合
Dim x As New MyClass
どちらも正しいコードとして処理されますが、何か違いがあるのか調べてみました。
2つの宣言方法の違い
Microsoftは、VB.NETでオブジェクト変数の宣言と同時にNewして1行で書くコードは、オーバヘッドが大きいので使うべきではないと以下のページで書いているようです。
VB 6.0 ユーザーのための VB .NET 移行ガイド - Dim x As New MyClass | Microsoft Docs
違いについて次の表にまとめてみました。
比較項目 | 2行で書いた場合 | 1行で書いた場合 |
---|---|---|
Nothingを設定してオブジェクトを破棄した時 | 再度Newしない限りNothingのまま | オブジェクトの存在が必ず保証されるため、再利用すると自動で再作成される |
オーバーヘッドの有無 | 無 | 有(オブジェクトが利用されるたびに毎回チェックが入る) |
実際の挙動の違い
実際にコードを実行して、挙動の違いを調べてみました。
2行で書いた場合
2行で書いた場合は、「Set c = Nothing」でオブジェクトを破棄すると、「Is Nothing」の比較結果はTrueとなります。
また、Nothingでオブジェクトを破棄した後は、「c.Add」はエラーとなります。
Sub 宣言とオブジェクトのSetを分けて2行で書く場合()
'オブジェクト変数の宣言(2行)
Dim c As Collection
Set c = New Collection
'Nothingを設定してオブジェクトを破棄
Set c = Nothing
'変数がNothingかどうか比較
If c Is Nothing Then
MsgBox "cはNothign" '★Nothingと判定される
Else
MsgBox "cはNothignではない"
End If
'コレクションを追加
c.Add "コレクションを追加" '★オブジェクトは破棄されているのでAddはできない
MsgBox c.Item(1)
End Sub
1行で書いた場合
1行で書いた場合、オブジェクトの存在が必ず保証されるため、再利用すると再作成されるとのことです。
次のコードを実行した場合、「Set c = Nothing」でオブジェクトを破棄しても、「Is Nothing」の比較結果はFlaseとなります。
また、オブジェクトを破棄しているにもかかわらず「c.Add」ができてしまいます。
Nothingを設定してオブジェクトを明示的に破棄しても、そのオブジェクトを参照したり利用したりすると自動でオブジェクトが再作成されてしまうようです。
Sub 宣言と同時にNewして1行で書く場合()
'オブジェクト変数の宣言(1行)
Dim c As New Collection
'Nothingを設定してオブジェクトを破棄
Set c = Nothing
'変数がNothingかどうか比較
If c Is Nothing Then
MsgBox "cはNothign"
Else
MsgBox "cはNothignではない" '★Nothingではないと判定される
End If
'コレクションを追加
c.Add "コレクションを追加" '★オブジェクトは破棄されているのにAddできてしまう
MsgBox c.Item(1)
End Sub
結論
細かいことを気にしなければどちらを使ってもよいが、宣言とSetを分けて2行で書く方が無難。