VBAでクラスモジュールを使い始めたとき、多くの人が最初につまずくのが
「インスタンス化って結局何?」
という点です。
Dim obj As New クラス名
Set obj = New クラス名
と書けはするものの、
「なぜ New が必要なのか」「いつ Set するのか」「普通の変数と何が違うのか」
が曖昧なまま使われているケースは少なくありません。
その結果、
- 意図しないタイミングで初期化される
- 1つのつもりが複数生成されている
- クラスを使っているのに、結局手続き型と変わらない
といった 設計ミス が起こります。
この記事では、
クラスのインスタンス化とは何かを言葉で整理し、
どう設定し、どんな場面で使うと意味があるのかを
実務視点で解説します。
目次
- ✅ クラスの「インスタンス化」とは何をしているのか
- ・よくある誤解
- ・VBAにおける正確な整理
- ✅ Dim と Set が分かれている理由
- ・Dim は「箱を用意するだけ」
- ・Set は「実体とひも付ける」
- ✅ 「As New」を使ったインスタンス化の注意点
- ・As New の挙動
- ・なぜ実務では避けられがちなのか
- ✅ クラスをインスタンス化する「意味」が生まれる場面
- ・意味のない例(よくある失敗)
- ・意味が出る例
- ✅ インスタンスを「1つ」使うケース
- ・代表的な実務例
- ✅ 複数インスタンスを使う場面
- ・典型的な実務シーン
- ✅ インスタンス化を前提にした設計の考え方
- ・判断の目安
- ✅ クラスと通常の変数・モジュールとの違い
- ✅ 実務でよくあるインスタンス化の失敗例
- ・Set し忘れ
- ・As New の多用
- ・クラスに処理を詰め込みすぎる
- ✅ まとめ:クラスのインスタンス化は「設計の起点」
✅ クラスの「インスタンス化」とは何をしているのか
クラスのインスタンス化は、
「設計図(クラス)から、実体(オブジェクト)を作ること」
を意味します。
この説明自体はよく聞きますが、VBAではここが曖昧なまま進みがちです。
・よくある誤解
- クラス=変数の延長
- インスタンス=宣言した瞬間にできている
- New はおまじない
こうした理解のまま使うと、
オブジェクト変数と実体の関係が整理できません。
・VBAにおける正確な整理
VBAでは、次の2つは明確に別物です。
- クラス:型・設計情報(Class Module)
- インスタンス:実際にメモリ上に存在するオブジェクト
Dim user As UserClass
この時点では、
「UserClass型の変数を用意しただけ」であり、
中身(実体)はまだ存在していません。
Set user = New UserClass
この瞬間に初めて、
UserClassのインスタンスが生成され、userがそれを参照します。
✅ Dim と Set が分かれている理由
VBAでは、オブジェクト変数は必ず
- Dim(宣言)
- Set(参照の代入)
が分かれています。
ここを理解せずに使うと、
Nothing エラーや想定外の初期化につながります。
・Dim は「箱を用意するだけ」
Dim customer As CustomerClass
これは
「CustomerClass型を入れられる箱を用意した」
状態です。
まだ中身は空(Nothing)です。
・Set は「実体とひも付ける」
Set customer = New CustomerClass
ここで初めて、
- インスタンスが生成され
- customer がその参照を持つ
という状態になります。
この 2段階構造 が、
VBAのオブジェクト変数の基本です。
✅ 「As New」を使ったインスタンス化の注意点
VBAには次のような書き方もあります。
Dim customer As New CustomerClass
一見すると便利ですが、
実務では注意が必要な書き方です。
・As New の挙動
- 初回アクセス時に自動でインスタンスが生成される
- Nothing になると、次回アクセス時に再生成される
つまり、
いつ生成されたのかがコードから読み取れません。
・なぜ実務では避けられがちなのか
- 初期化タイミングが不明瞭
- デバッグ時に状態を追いにくい
- 意図せず再生成されるリスク
保守性・可読性を重視するなら、
Dim customer As CustomerClass
Set customer = New CustomerClass
と 明示的に書く方が安全です。
✅ クラスをインスタンス化する「意味」が生まれる場面
クラスを使う意味は、
「値をまとめる」ことではありません。
意味が生まれるのは、
振る舞いと状態を一緒に扱いたいときです。
・意味のない例(よくある失敗)
' ただの変数置き場
Public Name As String
Public Age As Long
これだけなら、
Dictionary や構造体の方が簡単です。
・意味が出る例
- 初期化時に必ず通したい処理がある
- 値の整合性を内部で保証したい
- 処理単位としてまとめたい
' クラスモジュール:CustomerClass
Private customerName As String
Public Sub Initialize(name As String)
customerName = Trim(name)
End Sub
Public Function GetDisplayName() As String
GetDisplayName = "顧客:" & customerName
End Function
ここでは、
- データの扱い方
- 表示ロジック
が 1つの単位として閉じている ことに意味があります。
✅ インスタンスを「1つ」使うケース
クラス=複数使うもの、と思われがちですが、
1インスタンスだけでも意味があります。
・代表的な実務例
- 設定情報をまとめたクラス
- 処理全体の状態を保持する管理クラス
- ログ・結果保持用クラス
Dim appState As AppState
Set appState = New AppState
こうすることで、
- グローバル変数の乱立を防ぐ
- 状態管理を1か所に集約できる
という設計上のメリットがあります。
✅ 複数インスタンスを使う場面
クラスの本領が発揮されるのは、
同じ構造のものを複数扱うときです。
・典型的な実務シーン
- 行データを1件ずつオブジェクト化
- 複数条件・複数担当者の管理
- 処理単位を独立させたい場合
Dim customers As Collection
Set customers = New Collection
Dim customer As CustomerClass
Set customer = New CustomerClass
customer.Initialize "A社"
customers.Add customer
このようにすると、
- 1件ごとのロジックが分離され
- 処理の見通しが良くなります
✅ インスタンス化を前提にした設計の考え方
クラスを使うかどうかは、
「再利用するか」ではなく「責務が明確か」で判断します。
・判断の目安
- 処理が「名詞」で表現できるか
- 内部状態を外に漏らさずに済むか
- 手続きが肥大化していないか
インスタンス化は、
設計を整理するための手段です。
✅ クラスと通常の変数・モジュールとの違い
| 手段 | 向いている用途 |
|---|---|
| 標準モジュール | 単発処理・共通関数 |
| 変数 | 単純な値保持 |
| クラス | 状態+振る舞いを持つ単位 |
クラスを使うことで、
「処理のかたまり」を
意味のある単位として扱えるようになります。
クラスは、通常の変数や標準モジュールとは
「呼び出し方」と「使い方の前提」が大きく異なります。
クラスモジュールをオブジェクト変数として正しく扱うための考え方や、
Set を使った呼び出しの基本については、
「【VBA】クラスモジュールの使い方を解説|オブジェクト変数としての正しい呼び出し方」
で整理しています。
✅ 実務でよくあるインスタンス化の失敗例
・Set し忘れ
Dim obj As SampleClass
obj.DoSomething ' ← エラー
→ 必ず New してから使う
・As New の多用
意図しない再生成でバグの温床になります。
・クラスに処理を詰め込みすぎる
責務が曖昧になると、
結局メンテナンス性が落ちます。
実務で起きるインスタンス化のトラブルは、
クラスそのものよりも、オブジェクト変数と Set の理解不足が原因になっているケースがほとんどです。
なぜ Set が必要なのか、
変数とオブジェクト参照がどう違うのかを整理した内容は、
「【VBA】Setとは?オブジェクト変数の基本と参照の仕組み|初心者が必ず押さえるべき基礎文法」
で詳しく解説しています。
✅ まとめ:クラスのインスタンス化は「設計の起点」
- クラスは設計図、インスタンスは実体
- Dim と Set は役割が違う
- As New は便利だが注意が必要
- インスタンス化は「構造を整理するため」に行う
- クラスは状態と振る舞いをまとめるための道具
クラスのインスタンス化を正しく理解すると、
VBAコードは 「動くかどうか」から
「長く使えるかどうか」 という次の段階に進みます。
「なぜ New するのか」を説明できるようになったとき、
クラスは単なる難しい構文ではなく、
実務を支える設計ツールになります。