「台帳の最終行を探して、1セルずつデータを入力している」。「名簿に新しい人を追加するたびに、入力する列を間違えてヒヤッとする」。こんな作業を毎回手でやっていませんか。
シートに直接入力する方式は、手軽な反面ミスが起きやすいものです。入力する行や列を間違えたり、必須項目を空のまま登録してしまったりします。件数が増えるほど、このリスクも積み上がっていきます。
そんなときに役立つのが、VBAのユーザーフォーム(UserForm)です。専用の入力画面を用意すれば、決まった項目を埋めてボタンを押すだけで、台帳の末尾に1行きれいに追加できます。この記事では、入力フォームをゼロから作る手順を3ステップで解説します。フォームのデザイン・ボタンの処理・シートへの書き込みの順で進めます。コピペでそのまま動く完成コードも用意しました。
VBAユーザーフォームの作り方でできること
まずは、ユーザーフォームを使うと入力作業がどう変わるのかを見ておきましょう。
ユーザーフォームとは、VBAで作る独自の入力画面のことです。テキストボックスやボタンを自由に配置して、アプリのような専用フォームを作れます。
シートに直接入力する方式と比べると、次のようなメリットがあります。
- 決まった項目だけを順番に入力できるので、列のズレが起きない
- 「未入力ならボタンを止める」など、入力チェックを仕込める
- ボタン1つで台帳の末尾に行を追加できる
- 入力する人が、Excelの構造を知らなくても使える
手入力とユーザーフォームの違いを、簡単な表で比べてみます。
| 項目 | シートに直接入力 | ユーザーフォーム |
|---|---|---|
| 入力位置のミス | 起きやすい | 起きない |
| 必須チェック | 自分で目視 | 自動でチェック |
| 操作のしやすさ | Excelの知識が必要 | 項目を埋めるだけ |
一度フォームを作ってしまえば、あとは項目を埋めてボタンを押すだけです。この「専用の入力窓口」を作れるのが、ユーザーフォームの強みですね。
なお、ユーザーフォームはVBAの中では中級者向けの機能です。マクロをまだ触ったことがない方は、先にExcel VBAマクロ入門で基本を押さえておくとスムーズです。
VBEの起動とユーザーフォームを作る準備
フォームを作る前に、VBE(Visual Basic Editor)という編集画面を開きます。VBEは、VBAのコードやフォームを作るための専用エディタです。
VBEの開き方
VBEを開く方法は2つあります。一番早いのは、Excelの画面で Alt + F11 を押す方法です。これだけでVBEが立ち上がります。
もう1つは、リボンの「開発」タブから開く方法です。「開発」タブの「Visual Basic」ボタンをクリックします。
「開発」タブが見当たらない場合は、表示設定が必要です。次の手順で追加してください。
- 「ファイル」→「オプション」を開く
- 「リボンのユーザー設定」を選ぶ
- 右側の一覧で「開発」にチェックを入れる
- 「OK」を押す
これで「開発」タブがリボンに表示されます。
ユーザーフォームの挿入
VBEが開いたら、フォームを追加します。メニューの「挿入」→「ユーザーフォーム」を選んでください。
すると「UserForm1」という灰色の四角い画面が現れます。これがフォームの本体です。同時に「ツールボックス」という、部品を並べた小さなウィンドウも表示されます。
ツールボックスが表示されない場合は、メニューの「表示」→「ツールボックス」で出せます。このツールボックスから、テキストボックスやボタンをフォームに貼り付けていきます。
.xlsmで保存することに注意
フォームやマクロを作ったブックは、必ず .xlsm(マクロ有効ブック)形式で保存します。普段の .xlsx 形式では、マクロが保存できません。
.xlsx のまま保存しようとすると、警告が出ます。このまま保存すると、作ったフォームが消えてしまいます。
保存時は「名前を付けて保存」で、ファイルの種類を「Excel マクロ有効ブック(.xlsm)」に変えてください。詳しい違いは.xlsxと.xlsmの違いで解説しています。
ステップ1:ユーザーフォームをデザインする
ここからは、実際に入力フォームを組み立てていきます。今回は、顧客名簿への登録を例にします。「名前」「電話番号」「区分」の3項目を入力するフォームを作ってみましょう。
部品をフォームに配置する
ツールボックスから、次の部品をフォームにドラッグして貼り付けます。
| 部品 | 役割 | 配置する数 |
|---|---|---|
| ラベル(Label) | 項目名の表示 | 3個 |
| テキストボックス(TextBox) | 文字の入力欄 | 2個 |
| コンボボックス(ComboBox) | 一覧から選ぶ入力欄 | 1個 |
| コマンドボタン(CommandButton) | 登録・閉じるの実行 | 2個 |
ラベルは「名前」「電話番号」「区分」という見出し用です。その右にテキストボックスやコンボボックスを並べると、見やすいフォームになります。
部品は、ツールボックスでアイコンをクリックしてから、フォーム上でドラッグすると配置できます。
部品に名前(オブジェクト名)を付ける
配置した部品には、コードから呼び出すための名前を付けます。これを「オブジェクト名」と呼びます。
部品をクリックして選び、画面左下の「プロパティ」ウィンドウで「(オブジェクト名)」の欄を書き換えます。今回は次のように設定します。
| 部品 | オブジェクト名 | 役割 |
|---|---|---|
| テキストボックス1 | txtName | 名前の入力欄 |
| テキストボックス2 | txtTel | 電話番号の入力欄 |
| コンボボックス | cmbType | 区分の選択欄 |
| コマンドボタン1 | btnAdd | 登録ボタン |
| コマンドボタン2 | btnClose | 閉じるボタン |
オブジェクト名は、あとからコードで使います。TextBox1 のような初期名のままでも動きます。ただ、txtName のように役割がわかる名前にしておくと、コードがぐっと読みやすくなります。
ボタンに表示する文字(登録・閉じる)は、プロパティの「Caption」で設定できます。
ステップ2:ボタンのイベント処理を書く
部品を配置したら、次はボタンを押したときの動きを書きます。VBAでは、これを「イベント処理」と呼びます。
コンボボックスに選択肢をセットする
まず、区分を選ぶコンボボックスに、選択肢を入れておきます。フォームが開いたタイミングで選択肢をセットしたいので、フォームの「Initialize」イベントを使います。
フォーム上の何もない部分をダブルクリックすると、コードを書く画面に切り替わります。そこに次のコードを書きます。
Private Sub UserForm_Initialize()
'--- 区分コンボボックスに選択肢を追加 ---
cmbType.AddItem "法人"
cmbType.AddItem "個人"
cmbType.AddItem "その他"
End Sub
AddItem は、コンボボックスに選択肢を1つ追加する命令です。3行書けば、3つの選択肢が並びます。これで、フォームを開いたときに区分が選べるようになります。
閉じるボタンの処理を書く
次は、簡単な「閉じる」ボタンから書いてみましょう。フォーム上の「閉じる」ボタンをダブルクリックすると、コード画面に切り替わります。そこに1行だけ書きます。
Private Sub btnClose_Click()
Unload Me '自分自身(フォーム)を閉じる
End Sub
Unload Me は、フォームを閉じる命令です。Me は「このフォーム自身」を指します。これで閉じるボタンが完成です。
登録ボタンの処理を書く(メイン)
いよいよメインの「登録」ボタンです。ここでシートへの書き込みを行いますが、その前に入力チェックを入れておきます。「閉じる」と同じように、登録ボタンをダブルクリックしてコードを書きます。
Private Sub btnAdd_Click()
'--- 名前が未入力ならメッセージを出して処理を止める ---
If txtName.Value = "" Then
MsgBox "名前を入力してください"
txtName.SetFocus '名前の入力欄にカーソルを戻す
Exit Sub
End If
'--- 書き込み先シートの最終行の次の行を取得 ---
Dim ws As Worksheet '書き込み先のシート
Set ws = Worksheets("名簿")
Dim newRow As Long '新しく書き込む行番号
newRow = ws.Cells(Rows.Count, 1).End(xlUp).Row + 1
'--- フォームの入力値を各列に書き込む ---
ws.Cells(newRow, 1).Value = txtName.Value '名前をA列へ
ws.Cells(newRow, 2).Value = txtTel.Value '電話番号をB列へ
ws.Cells(newRow, 3).Value = cmbType.Value '区分をC列へ
MsgBox "登録しました"
'--- 次の入力に備えて入力欄をクリアする ---
txtName.Value = ""
txtTel.Value = ""
cmbType.Value = ""
txtName.SetFocus '名前の入力欄にカーソルを戻す
End Sub
このコードが、フォームの心臓部です。「名前」シートを用意し、A列に名前、B列に電話番号、C列に区分が並ぶ前提になっています。登録ボタンを押すと、名簿の末尾に1行追加されます。
自分の環境に合わせて変えるのは、次の2か所です。
Worksheets("名簿")… 書き込み先のシート名ws.Cells(newRow, 1)などの列番号 … どの列に書き込むか
コードの仕組みを理解する
このコードのポイントは、3つのパートに分かれている点です。順番に見ていきましょう。
1つ目は、入力チェックです。If txtName.Value = "" Then で、名前が空かどうかを判定します。空ならメッセージを出して Exit Sub で処理を止めます。これで、名前なしの行が登録されるのを防げます。条件分岐の基本はVBA If文の使い方で解説しています。
2つ目は、書き込む行の決定です。ここで使う Cells(Rows.Count, 1).End(xlUp).Row は、定番のテクニックです。「A列の一番下から上に詰めて、最初にデータがある行」を返します。これに + 1 を足すことで、末尾の次の行(空いている行)が分かります。最終行の取得方法はVBA最終行の取得でも詳しく解説しています。
3つ目は、シートへの書き込みです。ws.Cells(newRow, 1).Value のように、行番号と列番号でセルを指定します。txtName.Value のフォームの入力値を、各セルに代入していきます。
Cells(newRow, 1) の 1 はA列、2 はB列という対応です。行と列を数字で指定する書き方は、VBA RangeとCellsの違いで詳しく解説しています。
ステップ3:フォームを呼び出すマクロを作る
ここまでで、フォーム本体は完成しました。ただ、このままではフォームを画面に出せません。最後に、フォームを開くためのマクロを用意します。
フォームを開くコードは、標準モジュールに書きます。VBEのメニューで「挿入」→「標準モジュール」を選び、次のコードを書いてください。
Sub フォームを開く()
UserForm1.Show 'ユーザーフォームを画面に表示する
End Sub
UserForm1.Show が、フォームを画面に表示する命令です。UserForm1 の部分は、フォームのオブジェクト名に合わせます。フォーム名を変えていなければ、このままで動きます。
このマクロを実行すると、入力フォームが画面に表示されます。項目を埋めて登録ボタンを押せば、名簿シートに行が追加されます。
ボタンからフォームを開けるようにする
毎回マクロの一覧から実行するのは面倒です。シート上にボタンを置いて、クリックでフォームが開くようにしておくと便利です。
- 「開発」タブの「挿入」→「ボタン(フォームコントロール)」を選ぶ
- シート上でドラッグしてボタンを描く
- マクロの登録画面で「フォームを開く」を選んで「OK」を押す
- ボタンの文字を「名簿に登録」などに変える
これで、ボタンを押すだけで入力フォームが立ち上がります。名簿を使う人が、コードを意識せずに登録できるようになります。
VBAユーザーフォームでよくあるエラーと対処法
ユーザーフォーム作りでつまずきやすいエラーを、3つにしぼって紹介します。
「変数が定義されていません」と出る
オブジェクト名のタイプミスが原因のことがほとんどです。コードで txtName と書いているのに、部品のオブジェクト名が TextBox1 のままだと、このエラーになります。
プロパティウィンドウで、部品の「(オブジェクト名)」を確認してください。コードに書いた名前と、部品の名前が一致している必要があります。大文字小文字や全角半角の違いも見落としやすいポイントです。
なお、変数の宣言を必須にする Option Explicit を使うと、タイプミスをこの段階で見つけやすくなります。詳しくはVBA変数の使い方をご覧ください。
実行時エラー9:インデックスが有効範囲にありません
これは、指定したシート名が存在しないときに出ます。Worksheets("名簿") と書いているのに、実際のシート名が「顧客名簿」だと、このエラーになります。
シート名のタイプミス、全角と半角の違い、余分なスペースがよくある原因です。実際のシート名を、コードにそのままコピーすると確実です。
フォームが表示されない・反応しない
UserForm1.Show を書いたマクロを実行しているか、まず確認してください。フォームのコードを書いただけでは、フォームは表示されません。フォームを開くマクロを、別途実行する必要があります。
また、ボタンを押しても反応しない場合は、イベント処理の名前を確認します。Private Sub btnAdd_Click() の btnAdd の部分に注目してください。ここがボタンのオブジェクト名と一致しているかをチェックします。
その他のエラーについては、VBAマクロのエラー解決ガイドで頻出エラー別にまとめています。
入力途中で誤って閉じても安心な設計に
実務で使うなら、登録ミスを防ぐ仕組みを足しておくと安心です。たとえば、電話番号が数字以外を含むときに警告を出すなど、項目ごとのチェックを追加できます。
入力チェックは If 文を増やすだけです。エラーが出ても処理が止まらないようにするには、エラーハンドリングを組み合わせます。On Error GoTo の使い方はVBAのエラーハンドリング完全ガイドでくわしく解説しています。
まとめ
ExcelのVBAユーザーフォームで入力フォームを作る方法を、3ステップで解説しました。最後にポイントを整理します。
- ステップ1:ツールボックスから部品を配置し、わかりやすいオブジェクト名を付ける
- ステップ2:登録ボタンのイベント処理に「入力チェック→最終行取得→書き込み」を書く
- ステップ3:
UserForm1.Showでフォームを開くマクロを作り、シートのボタンに登録する - 末尾への行追加は
Cells(Rows.Count, 1).End(xlUp).Row + 1で書き込む行を決める - フォームやマクロを作ったブックは必ず
.xlsm形式で保存する
まずは「名前」「電話番号」「区分」のシンプルなフォームから、自分の台帳の項目に合わせて作ってみてください。動くフォームが1つできれば、項目を増やすのも簡単です。
VBAの基本構文をテーマ別に学び直したい方は、こちらの記事もあわせてどうぞ。
- 条件分岐の基本はVBA If文の使い方
- セル操作の基本はExcel VBAでRangeを使う方法
- 最終行取得はExcel VBAで最終行を取得する方法
- 別シートへの転記はVBAで複数シート間のデータを転記・集約する方法
VBA全体を体系的に学びたい方もいるでしょう。入門ハブ記事のExcel VBAで仕事を自動化する方法も参考にしてください。
