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?

[備忘録] Excel VBAでの標準/クラスモジュールの使い分け

Last updated at Posted at 2025-05-28

Excel VBAの標準モジュールとクラスモジュールの違いを、ポイントに絞って備忘録します。あくまで私個人の判断基準です。ご参考になれば幸いです。

vba-modules-diagram.png

根本的な違い

標準モジュール クラスモジュール
性質 静的(1つだけ存在)※ 動的(複数作成可能)
状態 グローバル共有 インスタンス毎に独立
用途 共通処理・ユーティリティ データ + 処理のセット
初期化 なし Class_Initialize/Terminate
イベント なし WithEvents対応

※モジュール自体が静的という意味(Static変数とは別概念)


具体例で理解する

標準モジュール:共通のツール箱

' UtilityModule.bas
Option Explicit
' Option Private Module  ' 他のプロジェクトからの参照を制限

' アプリケーション全体で共有される
Public g_ProcessCount As Long

' 誰でも使える道具(関数)
Public Function FormatMoney(value As Double) As String
    FormatMoney = "¥" & Format(value, "#,##0")
End Function

Public Sub WriteLog(message As String)
    ' ログファイルに出力(共通処理の例)
    Debug.Print Now & ": " & message
End Sub

Public Sub IncrementCount()
    g_ProcessCount = g_ProcessCount + 1
    WriteLog "処理回数: " & g_ProcessCount
End Sub

使い方: 直接呼び出し

Debug.Print FormatMoney(1000)  ' ¥1,000
IncrementCount()               ' グローバルカウンターが増える

クラスモジュール:独立したオブジェクト

' BankAccount.cls
Option Explicit

Private m_Balance As Double
Private m_AccountNumber As String

' 初期化処理
Private Sub Class_Initialize()
    m_Balance = 0
    Debug.Print "口座オブジェクト作成"
End Sub

' 終了処理(リソース解放)
Private Sub Class_Terminate()
    Debug.Print "口座オブジェクト(" & m_AccountNumber & ")削除"
End Sub

Public Property Let AccountNumber(value As String)
    m_AccountNumber = value
End Property

Public Property Get Balance() As Double
    Balance = m_Balance
End Property

Public Sub Deposit(amount As Double)
    m_Balance = m_Balance + amount
End Sub

Public Sub Withdraw(amount As Double)
    If amount <= m_Balance Then
        m_Balance = m_Balance - amount
    End If
End Sub

' イベント発生例
Public Event BalanceChanged(NewBalance As Double)

Private Sub NotifyBalanceChange()
    RaiseEvent BalanceChanged(m_Balance)
End Sub

使い方: インスタンス作成して使用

Dim account1 As New BankAccount
Dim account2 As New BankAccount

account1.AccountNumber = "001"
account1.Deposit 1000

account2.AccountNumber = "002"  
account2.Deposit 2000

' それぞれ独立した残高を持つ
Debug.Print account1.Balance  ' 1000
Debug.Print account2.Balance  ' 2000

' Collection で複数管理も可能
Dim accounts As New Collection
accounts.Add account1, "001"
accounts.Add account2, "002"

使い分けの判断

標準モジュールを使う場面

' ✅ 状態を持たない処理
Public Function CalculateTax(price As Double) As Double
    CalculateTax = price * 0.1
End Function

' ✅ アプリケーション全体の設定・定数
Public Const APP_VERSION As String = "1.0"
Public g_LastSavedFile As String

' ✅ エラーハンドリング
Public Sub HandleError(errNum As Long, errDesc As String)
    WriteLog "エラー " & errNum & ": " & errDesc
End Sub

クラスモジュールを使う場面

' ✅ データと処理がセット
' 顧客情報 + 顧客の操作
' 注文情報 + 注文の処理
' ファイル情報 + ファイル操作

' ✅ 同じ種類のものを複数扱う
' 複数の顧客、複数の注文、複数のファイル

' ✅ イベント駆動が必要
' WithEvents を使った通知パターン

実践例:同じ処理での比較

データ処理を例に、実装の違いを見てみましょう。

標準モジュール版

' DataProcessor.bas
Public g_ProcessedCount As Long  ' 全体で共有

Public Sub ProcessData(data As String)
    ' 処理実行
    g_ProcessedCount = g_ProcessedCount + 1
    Debug.Print "処理済み件数: " & g_ProcessedCount
End Sub

問題点:

  • 複数の処理を同時に行うと、カウンターが混在する
  • 前の処理の影響を受ける

クラスモジュール版

' DataProcessor.cls
Private m_ProcessedCount As Long  ' インスタンス毎に独立

Public Property Get ProcessedCount() As Long
    ProcessedCount = m_ProcessedCount
End Property

Public Sub ProcessData(data As String)
    ' 処理実行
    m_ProcessedCount = m_ProcessedCount + 1
    Debug.Print "処理済み件数: " & m_ProcessedCount
End Sub

利点:

Dim processor1 As New DataProcessor
Dim processor2 As New DataProcessor

processor1.ProcessData "データA"  ' processor1のカウント: 1
processor2.ProcessData "データB"  ' processor2のカウント: 1

' それぞれ独立してカウント
Debug.Print processor1.ProcessedCount  ' 1
Debug.Print processor2.ProcessedCount  ' 1

まとめ

選択の指針(判断フローチャート)

データや状態を保持する必要がある?
├─ No  → 標準モジュール(ユーティリティ関数)
└─ Yes → 複数のインスタンスが必要?
          ├─ No  → 標準モジュール(グローバル変数)
          └─ Yes → クラスモジュール

パフォーマンス面の注意点

標準モジュール

  • ✅ 呼び出しコストが低い(1回ロードで使い回し)
  • ❌ グローバル変数の乱用でメモリリーク的バグが発生しやすい

クラスモジュール

  • ✅ 独立した状態で安全
  • ❌ インスタンス作成にわずかなコストあり

覚えておくべき1つのルール

「複数作る可能性があるか?」

  • No → 標準モジュール
  • Yes → クラスモジュール

あくまで私個人の判断基準です。ご参考になれば幸いです。

参考

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?