VBA初心者にありがちなミスや勘違いを、現場での実例や経験に基づいてまとめてみました。コードを書く上での基本的な考え方から、可読性・保守性に関わる設計まで、初心者がやりがちな注意点をひとつずつ丁寧に解説していきます。
1. Option Explicit を記述していない
■ 問題点:
VBAでは、デフォルトでは変数を宣言しなくてもコードが動いてしまいます。そのため、タイプミスで意図しない変数が作られてしまい、エラーが発見しづらくなります。また、変数の型を宣言しないことで、予期せぬデータ型に自動変換され、数値計算や文字列処理が正しく行えないといった問題も起こります。
■ 対策:
すべてのモジュールの冒頭に Option Explicit を記述しましょう。これにより、未宣言の変数を使おうとした段階でコンパイルエラーになるため、バグを未然に防げます。変数の型を明示することで、意図しないデータの扱いを防ぎ、処理の安定性も向上します。
2. インデントが整っていない
■ 問題点:
コードの構造が視覚的に分かりにくくなり、If文やループの範囲が不明確になります。特に複雑な処理になると、読み間違いや修正時のミスに繋がります。
■ 対策:
If文、For文、With文などのブロックには必ずインデントを設定し、コードの階層構造を明確にしましょう。VBEのインデント機能やフォーマッタを活用すると一貫性が保てます。
3. マクロの記録をそのまま使っている
■ 問題点:
記録マクロは「選択」や「アクティブ化」などの不要な処理を多く含んでおり、読みづらく、冗長になります。また、意図しない動作の原因にもなります。
■ 対策:
記録マクロは「雛形」として活用し、不要な行や無駄な操作は削除して整理した上で使うようにしましょう。
4. 親オブジェクトを指定しないRangeやCellsの使用
■ 問題点:
初心者に多いミスの一つとして、Range や Cells を使用する際に親オブジェクト(通常は Worksheet)を明示せずに使ってしまうというものがあります。この場合、処理は ActiveSheet を対象として実行されるため、ユーザーが別のシートをアクティブにしていると、意図しないシートで処理が行われてしまいます。
たとえば、以下のようなコードは非常に危険です:
Range("A1").Value = "テスト"
これは「今アクティブなシート」のA1セルに書き込むという命令であり、どのシートかは明示されていません。
■ 対策:
必ず親オブジェクトを明示して記述しましょう。以下のように Worksheets またはシートのオブジェクト名を使って、処理対象を明確にします:
Worksheets("集計").Range("A1").Value = "テスト"
または、
sh01_集計.Range("A1").Value = "テスト"
このようにしておけば、コードを読む人にとっても処理の対象が一目瞭然ですし、アクティブシートに依存しない堅牢な設計になります。
5. ワークシートの参照方法が危険
■ 問題点:
Worksheets(1) のようなインデックス指定は、シート順の変更で意図しないシートを参照してしまう危険があります。また、シート名の直書きもユーザーによる変更に弱くなります。
■ 対策:
VBE上でシートのオブジェクト名(例:Sh01_設定)を指定し、Sh01_設定.Range(...) のように使うことで、順番や表示名の影響を受けずに安全に参照できます。
6. コメントが書かれていない/変更理由も残っていない
■ 問題点:
なぜその処理をしたのか、どんな意図があるのかをコメントで残さないと、後日見返した際に理解するのが非常に難しくなります。
■ 対策:
7. プロシージャが長すぎる
■ 問題点:
処理を1つのプロシージャに詰め込みすぎると、コードの見通しが悪くなり、保守性が大きく低下します。
■ 対策:
50行以内にまとめるのを目安に、処理ごとにサブルーチン化しましょう。役割の異なる処理は分割し、関数名で機能が分かるようにするのがコツです。
8. ネストが深すぎる
■ 問題点:
ループや条件分岐が入れ子になりすぎると、ロジックの追跡が困難になります。特に3重以上のネストは読みづらく、デバッグもしにくくなります。
■ 対策:
ネストの深い処理は別プロシージャに分けるなどして、処理の階層を浅く保ちましょう。ネスト構造は2〜3層以内が理想です。
■ 問題点:
列番号や判定条件などに直接数値を記述すると、何を意味するかが分かりづらくなり、変更にも弱くなります。
■ 対策:
Enumを使って意味のある名前を付けましょう。たとえば:
Public Enum Enum_Fファイル一覧
F01_番号 = 1
F02_ファイル名 = 2
F03_フルパス = 3
F04_日付 = 4
End Enum
このようにEnumを定義しておけば、Cells(i, F03_フルパス) のように可読性が向上し、構造変更にも柔軟に対応できます。
10. フルパスをコードにハードコーディングしている
■ 問題点:
ファイルやフォルダのパスをコードに直書きすると、環境が変わると動作しなくなり、メンテナンスが大変になります。
■ 対策:
ThisWorkbook.Path や、設定シートでの指定、ファイル選択ダイアログなどを使って、柔軟かつ再利用性の高い設計にしましょう。
11. RangeやCellsをアドレスで乱用している
■ 問題点:
Range("A1") や Cells(1,1) での固定参照は、行列の挿入や削除でずれてしまい、修正が困難になります。
■ 対策:
名前付き範囲(名前定義)や変数・Enumによる動的参照を使うことで、可読性・保守性ともに向上します。
12. ユーザーフォームを使いがち
■ 問題点:
初心者はVBAのプログラミングらしさや「アプリっぽさ」を求めて、安易にユーザーフォームを利用したがる傾向があります。しかし、ユーザーフォームは設計・レイアウトの自由度が低く、入力項目の変更やレイアウト調整が発生すると、再構築が面倒になります。
また、複数の入力欄やリストをフォーム上に構成するには、かなりの手間がかかり、処理の流れもコードに埋め込まれやすく、保守が困難になるケースも多いです。
■ 対策:
入力はシート上に入力欄(セル)を設け、そこで操作できるようにしましょう。Excelのグリッド構造はフォーム代わりに非常に便利で、入力項目が多くなっても簡単にレイアウト変更が可能です。
入力・実行ボタンをシートに設けることで、変更やメンテナンスもシンプルになり、VBAの初心者にとっても扱いやすい仕組みとなります。
■ 問題点:
元データが上書きされることで、処理前後の比較ができず、テストも困難になります。
■ 対策:
入力・処理・出力はシートを分け、各段階での確認・検証ができる構成を徹底しましょう。
13. 入力と出力を同じシートで処理している
■ 問題点:
一つのシートで入力・処理・出力をすべて行ってしまうと、処理前後の状態を比較することが難しくなり、特にテストや検証が困難になります。また、データの誤消去や誤上書きのリスクも高まります。
■ 対策:
「入力」「処理」「出力」の各役割を明確に分け、できるだけシートも分離して構成しましょう。これにより、
14. 変数名・関数名が分かりにくい
■ 問題点:
日本語は読みやすい反面、入力効率が下がり、IME切替も煩雑になるため、コーディング効率が落ちます。
■ 対策:
str_商品名, lng_出力件数 のように、ローマ字+日本語のハイブリッド命名を推奨します。型情報もプレフィックスで付けるとさらに明確になります。
↓参考
softex-celwear.hatenablog.com
15. 変数名・関数名をすべて日本語で書いてしまう
■ 問題点:
日本語は読みやすい反面、入力効率が下がり、IME切替も煩雑になるため、コーディング効率が落ちます。
■ 対策:
str_商品名, lng_出力件数 のように、ローマ字+日本語のハイブリッド命名を推奨します。型情報もプレフィックスで付けるとさらに明確になります。
16. 処理の部品化ができていない
■ 問題点:
初心者の多くは、毎回ゼロからコードを書いてしまいがちです。そのため、同じような処理でも毎回異なるロジックや命名で書かれてしまい、結果としてコード全体に一貫性がなくなり、読み直しや再利用が非常に困難になります。
また、毎回新しく処理を書くことで開発効率も悪化し、共通化すれば数行で済む処理を何度も書き直すことになり、工数も増加します。過去に作ったコードを活かせないため、成長や学習の蓄積も進みにくくなります。
■ 対策:
よく使う処理は関数やサブルーチンとして部品化し、共通モジュールやアドインに保存しておきましょう。処理名やパラメータ設計も再利用しやすい形に整えておくことで、次回以降の開発が圧倒的に楽になります。
一貫性のあるコードは、自分が後で読み直すときにも理解しやすくなり、チーム内での共有・メンテナンスもスムーズになります。
17. 汎用プロシージャに機能を詰め込みすぎる
■ 問題点:
処理を汎用化しようとするあまり、引数が多くなりすぎたり、内部で様々な条件分岐を入れて複雑になったりすると、逆に使い回しが難しくなります。
■ 対策:
18. 配列を使わず、セルからセルへの処理を繰り返している
■ 問題点:
初心者は処理をセル単位で直接行いがちですが、それでは入力→処理→出力の流れが曖昧になり、コードの構造も不明瞭になりがちです。また、処理速度が非常に遅くなります。
■ 対策:
基本設計は「入力→処理→出力」の3分構造を明確にし、処理部分は配列で一括取得・一括出力するようにしましょう。これにより処理速度も向上し、大量データでも快適に動作するようになります。実務レベルでは1万〜10万行超の処理も発生しうるため、セルからセルの逐次処理では限界が来ます。
■ 問題点:
グローバル変数(Public 変数)を多用すると、そのスコープが非常に広くなり、他のモジュールやプロシージャと意図せず干渉し合うリスクが高まります。
特に次のような課題があります:
-
可読性の低下:変数がどこで宣言されているかを探す必要があり、コード全体を俯瞰しないと追えなくなる
-
予期しないバグ:別のプロシージャがグローバル変数を書き換えた結果、意図しない動作が起きる
-
保守性の悪化:変数の用途や影響範囲が大きく、変更時の影響範囲がつかみにくい
■ 対策:
-
原則として、変数はローカルスコープで運用し、必要な場合は引数や戻り値で受け渡す
-
グローバル変数を使用する場合は、影響範囲や用途を明確にし、命名規則も工夫しておく(例:Pb_○○, Pri_〇〇)
-
複数のプロシージャが同じデータを使う必要があるなら、構造体やクラスモジュールの活用も検討する
20. すべての処理を1つのボタンで実行しようとしている
■ 問題点:
VBA初心者にありがちな傾向として、「1クリックで全自動」を目指してしまうことがありますが、それはかえってブラックボックス化を招きます。特に次のようなデメリットがあります:
■ 対策: