スポンサーリンク

コード肥大化に悩む上級者の皆さんへ──Access アプリのリファクタ手順を丁寧に解説します

スポンサーリンク
Access
スポンサーリンク

こんにちは、なかぜんです。Access アプリに長く手を入れていると、「動いてはいるけれど、何をしているのか自分でも把握できない」ような膨大な VBA コードに直面すること、ありませんか?

今日はそんな“コードの迷宮”から脱出するための、上級者向けリファクタ手順をご紹介します。整理されて読みやすくなったコードは、あなた自身の自信にも、次の改修にも役立ちますよ。

スポンサーリンク

目次

  1. なぜ肥大化が問題か?メリットを再確認
  2. ステップ1:コード構造の可視化と目的の整理
  3. ステップ2:共通処理の抽出とモジュール分割
  4. ステップ3:ネーミングとコメントで意図を明示
  5. ステップ4:単体テスト的な動作確認ルーチン
  6. よくあるミスと注意点
  7. 応用ポイント:より洗練する工夫
  8. まとめと次のステップ

1. なぜ肥大化が問題か?メリットを再確認

「動いているから大丈夫」と思いがちですが、膨れ上がったコードには以下のようなリスクがあります:

  • 可読性低下:何をしているのか理解しづらくなり、改修ミスの温床に。
  • 再利用性の低さ:同じ処理を何度も別箇所に書いてしまい、修正時に手間が増える。
  • 保守の難易度アップ:他のメンバーが手を入れづらく、運用体制にも影響。

この状態から脱することで:

  • コードが読みやすく、自信をもって修正できる
  • 共通処理をまとめられ、コード量の削減&品質向上
  • 将来的な拡張や他チームとの共有がスムーズに

といったメリットが得られます。安心できる未来を想像しながら進めましょう。

2. ステップ1:コード構造の可視化と目的の整理

まずは現状のコードを“見える化”します。大まかな手順は:

  1. 全てのモジュール・フォーム・レポートを一覧化
  2. 各コードの目的をコメントや図で整理(フローチャートも効果的)
  3. 重複処理がありそうな箇所にマークをつける

たとえば、こんなコード片があったとします:

Private Sub cmdSave_Click()
    Dim rs As DAO.Recordset
    Set rs = CurrentDb.OpenRecordset("SELECT * FROM tblData WHERE ID=" & Me.txtID)
    If Not rs.EOF Then
        rs.Edit
        rs!Value1 = Me.txtValue1
        rs!Value2 = Me.txtValue2
        rs.Update
    End If
    rs.Close
    Set rs = Nothing
    Call msgSuccess "保存しました"
End Sub

これを読みながら、目的を可視化してみましょう:

  • テーブルへレコード取得 → 属するフィールドへの代入 → 更新 → 終了 → メッセージ表示

ここまではシンプルですが、もし他のフォームでも似たような処理があれば、共通化の対象になりそうですね。

3. ステップ2:共通処理の抽出とモジュール分割

違う画面で似たコードを見つけたら、標準モジュールに共通処理としてまとめましょう。例:

' 標準モジュール modCommon.bas
Public Sub SaveRecord(tblName As String, id As Long, _
                      ParamArray fieldsAndControls() As Variant)
    Dim db As DAO.Database
    Dim rs As DAO.Recordset
    Dim i As Long
    Set db = CurrentDb()
    Set rs = db.OpenRecordset("SELECT * FROM [" & tblName & "] WHERE ID=" & id)
    If Not rs.EOF Then
        rs.Edit
        For i = LBound(fieldsAndControls) To UBound(fieldsAndControls) Step 2
            rs(fieldsAndControls(i)) = Nz(fieldsAndControls(i + 1), rs(fieldsAndControls(i)))
        Next i
        rs.Update
    End If
    rs.Close
    Set rs = Nothing
    Set db = Nothing
End Sub

解説:

  • ParamArray を使うことで、可変長のフィールド名+値の組を扱えるように。
  • 更新しない場合の既存値保持に Nz を活用。
  • どのテーブルでも使える汎用的な保存処理になります。

フォーム内ではこのように書くと、ずいぶんすっきりします:

Private Sub cmdSave_Click()
    Call SaveRecord("tblData", Me.txtID, _
        "Value1", Me.txtValue1, _
        "Value2", Me.txtValue2)
    Call msgSuccess("保存しました")
End Sub

4. ステップ3:ネーミングとコメントで意図を明示

上級者にこそ大事なのが、ネーミングとコメントです。例:

' modCommon.bas
' 保存処理を汎用化する関数
Public Sub SaveRecord(tblName As String, id As Long, ParamArray ... )
    ' db取得
    ' レコードセット取得
    ' 編集 -
    ' フィールド代入ループ -
    ' 更新 -
    ' 後始末
End Sub

ポイント:

  • “SaveRecord” は何をするのか名前で伝える
  • 各ブロックにコメントを入れることで、意図を明示
  • 必要であれば引数の説明もコメントしておくと親切

5. ステップ4:単体テスト的な動作確認ルーチン

Access VBA に本格的なユニットテストは仕込みづらいですが、“個別動作確認用フォーム”を一つ用意すると効果的です。

例:

' フォーム frmTestSave にこんなボタンを配置
Private Sub btnTestSave_Click()
    SaveRecord "tblData", 123, "Value1", "テスト1", "Value2", "テスト2"
    MsgBox "テスト保存を実行しました。テーブルを確認してください。"
End Sub

こうすると、複雑な処理だけを切り出して動かせるので、修正後の動作確認がすごく楽になります。

6. よくあるミスと注意点

  • 共通化しすぎて可読性逆に低下
    インターフェースを複雑にしすぎると、結果読みにくくなることも。
  • 過度な汎用化
    すべてを汎用関数で賄おうとすると、引数が多くなりすぎて逆に使いにくくなる場合も。
  • リファクタ途中で機能破壊
    テストフォームでこまめに動作確認を入れるのが大切。

7. 応用ポイント:より洗練する工夫

  • エラーハンドリングの共通化
    標準モジュールに Try…Catch 的な処理(On Error GoTo ErrHandler)をまとめておく。
  • DAO から SQL パラメータ化への移行
    SQL を構築するときに、パラメータを使うことで SQL インジェクション対策や可読性向上。
  • クラスモジュールの活用
    DAO.Recordset まわりをラップするクラスを作れば、より OOP 的に管理できて拡張も楽になります。
  • 定数化・Enum への置き換え
    ハードコードされたフィールド名や ID は定数や列挙体にまとめると安全性アップ。

8. まとめと次のステップ

今回のリファクタ手順は:

  1. 可視化 →
  2. 共通処理抽出 →
  3. ネーミング・コメント整理 →
  4. 動作確認フォームによるテスト →
  5. 応用ポイントでさらに洗練

読みやすく、理解しやすいコードは、あなたの業務効率にも、チームとの協調にも貢献します。ぜひ「やってみたい!」と思っていただけたら嬉しいです。

次のステップとしては、DAO ベースから SQL パラメータ化への移行や、クラスモジュールによる設計改善などにも挑戦してみましょう。

最後までお読みいただきありがとうございました。なかぜんでした 🙂