巨大なスパゲッティコードを解体せよ:20行の境界線がもたらすアーキテクチャの真実
Excel VBAという、一見すると愛好家の玩具に見える環境で、なぜ数万行のシステムが「動くゴミ」と化すのか。それは、多くのプログラマが「プロシージャの肥大化」を過小評価しているからだ。
単一のメソッドが100行を超えるとき、そこにはバグが潜む余地ではなく、バグが「生成される」環境が出来上がる。メモリ管理、例外の局所化、そして単体テストの不可能性。これらを克服するための第一歩は、「1プロシージャ20行縛り」という極端な規律にある。
なぜ「20行」なのか:認知的負荷とメモリの物理的相関
VBAはガベージコレクションが極めて脆弱な環境だ。プロシージャが長大化するということは、ローカル変数のスコープが肥大化し、メモリ上のスタック領域を不必要に占有し続けることを意味する。
20行という制限は、単なるコードの美学ではない。「その処理が何を返し、何に依存しているのか」を人間がメモリを消費せずに把握できる限界値なのだ。
リファクタリングの極意:責務の分離と状態の局所化
以下の例を見てほしい。典型的な「ダメなVBA」の構造だ。
‘ 【アンチパターン】すべてを詰め込んだ巨大メソッド
Sub ProcessData()
Dim ws As Worksheet: Set ws = Sheets(“Data”)
‘ … 50行続く処理 …
‘ … データ加工 …
‘ … APIコール …
‘ … ファイル保存 …
Set ws = Nothing ‘ 解放が遅すぎる
End Sub
これを「20行縛り」で解体すると、コードは「命令」ではなく「対話」へと昇華する。
‘ 【リファクタリング後の構造】
Public Sub MainProcess()
Dim data As Variant
data = FetchData(“Data”)
If Not IsEmpty(data) Then ProcessAndSave data
End Sub
Private Sub ProcessAndSave(ByVal data As Variant)
‘ 責務の明確化:加工と出力を分ける
Dim processed As Variant
processed = TransformData(data)
ExportToCSV processed, “C:\Temp\output.csv”
End Sub
メモリ最適化とオブジェクトのライフサイクル管理
VBAでシステム開発を行う際、最大の敵は「メモリリーク」だ。特にCOMオブジェクトの解放を怠ると、Excelはサイレントに腐敗していく。20行に分割することで、オブジェクトの寿命(Lifetime)を可視化せよ。
‘ 必要なスコープのみでオブジェクトを生成・破棄する
Private Function GetWorksheet(ByVal sheetName As String) As Worksheet
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets(sheetName)
‘ ここでバリデーションを行い、不正なら即座に終了する
If ws Is Nothing Then Err.Raise 91, , “Sheet not found.”
Set GetWorksheet = ws
End Function
このように「取得」と「利用」を分離することで、`Set ws = Nothing` を呼び出し元で管理する必要がなくなり、`With` ステートメントの深いネストという悪夢から解放される。
レガシー環境とAPI呼び出しの安定性
大規模な社内システム連携では、Windows API(`kernel32`や`user32`)を直接叩く必要がある場面がある。これらを巨大なプロシージャに混ぜ込むのは自殺行為だ。
API定義は専用のモジュールに隔離し、ラッパー関数として20行以内に納める。これにより、将来的に64bit環境へ移行する際の修正コストを劇的に下げることができる。
If VBA7 Then
Private Declare PtrSafe Function Sleep Lib “kernel32” (ByVal dwMilliseconds As Long) As Long
Else
Private Declare Function Sleep Lib “kernel32” (ByVal dwMilliseconds As Long) As Long
End If
‘ API呼び出しの抽象化:呼び出し側はAPIの存在を意識しなくて良い
Public Sub SafeWait(ByVal ms As Long)
If ms > 0 Then Sleep ms
End Sub
シニアエンジニアへの提言
VBAで「保守性の高いコード」を書くとは、「自分自身が半年後にこのコードを読んだとき、何一つとして疑問を抱かせない」状態を作ることだ。
1. プロシージャは20行以内。 これを超えたら、そのメソッドは「複数の責務」を抱え込んでいる。
2. 変数のスコープを最小化せよ。 プロシージャレベルの変数は極力減らし、引数と戻り値で状態を制御する。
3. エラーハンドリングを標準化せよ。 長いコードは例外処理を複雑にする。短いコードは、エラーハンドリングを「ガード節」としてシンプルに記述できる。
VBAはレガシーな言語だが、アーキテクチャの原則は現代のモダン言語と何ら変わらない。コードを細分化することは、Excelという広大なキャンバスの上で、精密な時計の歯車を組み上げる作業そのものなのだ。
今日、あなたのプロジェクトにある最も長いメソッドを一つ選び、20行に刻むことから始めてほしい。その瞬間、コードが「呼吸」を始めるのがわかるはずだ。
