VBAで作ったツールは、現場でいじられて壊れる
VBAで業務ツールを作って現場に渡す。しばらくすると「なんか動かなくなった」と言われる。見に行くと、シートの列が増えていたり、セルの書式が変わっていたり、「ちょっとここに項目を足したくて」と構成が変わっている。
Excelで作った業務ツールは、使う人の「ちょっとした変更」が積み重なって壊れていく。設計が甘いとVBAツールでも同じことが起きるが、設計次第で 「いじる気にならない」 状態にすることができる。
コントロールできるのは自分のVBAだけ
まず前提として、VBAが壊れる経緯にも2つのパターンがある。
他人が作ったVBA、他人から受け取ったVBA。 これはコントロールできない。中を読んでも意図がわからないコードが入っていたり、特定のシート構成を前提にしていたりする。壊れたら作り直すか、諦めるしかない。
自分が作るVBA。 こちらだけが設計でコントロールできる。
「VBAが壊れないようにするには」と聞くと、コメントを丁寧に書くとか、コーディング規約を作るとか、そういう話を想像するかもしれない。もちろんそれも無意味ではないが、中小製造業の現場で効くのはもっと構造的な方法になる。
核心は「シートに状態を持たせない」こと
壊れにくいVBAツールの設計は、一言で言えば 「シートに状態を持たせない」 ことに尽きる。
以前の記事で、Excelのシートをデータシート・UIシート・出力シートに役割分離すると書いた。今回の話はその延長にあるが、もう一歩踏み込む。
「シートに状態を持たせない」とは、ユーザーがシートに情報を蓄積していく使い方をさせないということ。書式設定も、罫線も、セルの配置も、全部VBAが生成する。ユーザーはボタンを押すだけ。VBAが毎回ゼロからシートを組み立てる。
こう設計しておくと、状況が大きく変わる。 VBAのコードさえあれば、同じものが再現できる から。シートの状態に依存していないので、「このセルにこの値が入っている前提で動く」という暗黙の前提がない。
極端な例:ボタン1つ、保存すら不要
最もシンプルなパターンを先に見せる。
表紙シートが1つだけあって、ボタンが1つ。押すと、外部のデータソース(CSVや別のExcelファイル、あるいはデータベース)からデータを取得して、帳票なりレポートなりを生成する。
この構成だと、ブック自体に保存する必要がない。データは外部にあるし、出力は毎回VBAが作り直す。ブックは「実行環境」であって「データの置き場」ではない。
極端な話、ブックが壊れても、VBAのコードさえ別に控えがあれば、新しいブックにコードを入れてボタンを配置するだけで復旧できる。
現実的なパターン:表紙・雛形・data の3シート構成
とはいえ、毎回外部からデータを取ってくる仕組みを作るのは、小規模な業務にはやりすぎになることが多い。データベースやCSV連携の仕組みまで作ると、VBA単体で済む話ではなくなる。
現実的によく使うのは、3つのシートで構成するパターンになる。
表紙シート。 ユーザーが操作する唯一のシート。ボタンがあり、必要なら入力欄もここに置く。
帳票雛形シート。 印刷用のテンプレート。レイアウトや書式はここで定義しておき、VBAがデータを流し込む。ユーザーは直接触らない。
dataシート。 データの蓄積場所。マスタや実績データをここに持つ。VBAを通じて読み書きする。ユーザーは直接触らない。
表紙にボタンを押すと、dataシートからデータを読み取り、帳票雛形にデータを入れて出力する。ユーザーが触るのは表紙だけ。雛形とdataは「VBAの管轄」として分離する。
「ちゃんと作ると、人はいじらない」
この構成にすると、面白いことが起きる。 使う人が怖くていじれなくなる。
関数だけで作ったシートは、みんな気軽にいじる。セルをコピーしたり、列を挿入したり、「ちょっとここ変えたいんだけど」と手を入れる。関数は壊しても影響範囲が見えやすいから、触る心理的ハードルが低い。そして、その「ちょっとした変更」が積み重なって、いつの間にか誰にも直せないシートができあがる。
一方、表紙・雛形・dataときれいに分かれていて、ボタンを押せば全部動くツールは、逆に触る気にならない。仕組みがちゃんとしているのが見てわかるから、下手にいじったら壊れそうだと感じる。
これは結果として 「いじられない設計」 になる。属人化対策のドキュメントを書くより、はるかに効果がある。
気をつけるなら、表紙に「雛形シートとdataシートは直接編集しないでください」と一言書いておくくらいで十分だと思う。逆に言えば、その一言で済む程度の構造にすることが設計の目標になる。
関数シートとの本質的な違い
以前の記事で、関数の限界について書いた。関数は「見る」ことしかできず、「処理する」にはVBAが必要だという話。
今回の話はそれとつながっている。関数で作ったシートは、データと処理と表示が全部同じシートに載っている。だから誰でもどこでも触れるし、どこを触っても影響がある。
VBAで構造を分離したツールは、データと処理と表示が分かれている。ユーザーが触れるのは表示(表紙)だけ。処理はVBAの中にあり、データはdataシートに閉じている。この分離が、「いじられない」効果を生む。
VBAを改造されたら終わりだが
この設計の唯一の弱点は、VBAそのものを改造されるケースになる。VBEを開いてコードを直接書き換えられると、設計の意図が崩れる。
ただし、中小製造業の現場でVBEを開いてコードを書き換える人は、かなり限られる。関数を触る人は多いが、VBAを触る人はほとんどいない。それ自体が一種の防御になっている。
自分はこの領域に関しては性善説でいいと思っている。お金や個人情報を直接扱うシステムなら話は別だが、生産管理や帳票出力といった業務ツールの範囲なら、悪意を前提にした対策は過剰になる。数十人規模の会社で、わざわざVBEを開いてコードを壊しにくる人はいない。どうしても気になるならVBAプロジェクトにパスワードをかけることもできるが、そこまでする場面はほとんどないだろう。
まとめ:「いじらせない」のではなく「いじる気にさせない」
「シートに状態を持たせない」設計にしておくと、以下のことが変わる。
- 使う人がいじらない。 構造がしっかりしていると、心理的に触れなくなる
- ボタンを押せば同じ結果が出る。 シートの状態に依存しないから、誰が押しても同じ
- 壊れても復旧しやすい。 VBAのコードが残っていれば再構築できる
ルールやドキュメントで「触るな」と言うより、触る余地のない構造を作る方が、中小製造業の現場には合っている。
そしてこの設計は、属人化への対処にもなる。作った人が辞めても、VBAのコードさえ残っていれば同じものが再現できる。以前の記事で「脱属人化ではなく属人化のトリアージ」と書いたが、「いじられない設計」は結果として属人化のダメージも最小限に抑える。
このシリーズの他の記事: