【VBA入門】第6回:データを蓄積する本格的な入力フォームの作り方
前回(第5回)では、UserFormのボタンにVBAコードを書き込み、テキストボックスの内容をセルに転記することに成功しました。「ボタンを押すとセルに文字が入る」という感動を味わえたと思います。
しかし、前回のコードには重大な問題がありました。何度ボタンを押しても同じセルに上書きされてしまうのです。これでは顧客リストや家計簿のような実用的なツールは作れません。
今回実装する3つの機能
本記事では、以下の機能を実装して実務レベルのフォームを完成させます。
- 最終行の自動取得 - データを上書きせず、常に最下行に追加
- 入力項目のクリア - 登録後にテキストボックスを自動で空にする
- 入力チェック - 空欄での登録を防ぐバリデーション機能
1. データの最終行を自動で見つける
前回のコードの問題点
Private Sub CommandButton1_Click()
Range("A2").Value = TextBox1.Value ' 常にA2に上書き
End Sub
このコードでは、何度ボタンを押してもA2セルにしか書き込まれません。
End(xlUp)の魔法
VBAで最終行を取得する際、必ず覚えるべき構文があります。
Cells(Rows.Count, 1).End(xlUp).Row
この構文の仕組み:
| 部分 | 意味 |
|---|---|
Rows.Count | エクセルの全行数(1,048,576行) |
Cells(Rows.Count, 1) | A列の最下行セル(A1048576) |
.End(xlUp) | そこから上方向にデータがある最初のセルを探す |
.Row | そのセルの行番号を取得 |
これは、エクセルで「Ctrl + ↑」を押したときの動作と同じです。最下行から上に向かって、データが入っている最後の行を見つけます。
新しいデータは「最終行の1つ下」に書き込みたいので、+ 1を追加します。
2. データを蓄積するコードの実装
サンプルシナリオ
今回は家計簿を想定し、以下の項目を入力します。
- A列: 日付(自動入力)
- B列: 商品名(TextBox1)
- C列: 金額(TextBox2)
改良版コード
Private Sub CommandButton1_Click()
Dim lastRow As Long
' A列の最終行を取得し、その1つ下の行を計算
lastRow = Cells(Rows.Count, 1).End(xlUp).Row + 1
' データを書き込む
Cells(lastRow, 1).Value = Date ' 今日の日付
Cells(lastRow, 2).Value = TextBox1.Value ' 商品名
Cells(lastRow, 3).Value = TextBox2.Value ' 金額
MsgBox "登録しました!"
End Sub
コードのポイント
- Dim lastRow As Long: 行番号を格納する変数。
Long型は大きな整数に対応 - Date関数: 現在の日付を自動取得
- Cells(行, 列):
Range("A2")より柔軟。変数で行番号を指定できる
これで、ボタンを押すたびに2行目、3行目、4行目…と自動的にデータが積み上がります。
3. ユーザー体験を向上させる「クリア処理」
登録後もテキストボックスに文字が残っていると、次のデータ入力時に不便です。自動でクリアする処理を追加しましょう。
クリア処理の追加
' データ転記後に追加
TextBox1.Value = "" ' 空文字で内容をクリア
TextBox2.Value = ""
TextBox1.SetFocus ' カーソルを商品名欄に戻す
MsgBox "登録しました!"
End Sub
SetFocusの効果
SetFocusメソッドは、入力カーソルを指定のコントロールに移動させます。これにより、ユーザーはマウスを使わずにキーボードだけで連続入力できます。
地味ですが、実務では非常に重要な「おもてなし機能」です。
4. 入力チェックでエラーを防ぐ
空欄のまま登録ボタンを押されると、日付だけの空っぽの行ができてしまいます。これを防ぐ「バリデーション」を実装します。
完成版コード
Private Sub CommandButton1_Click()
' --- 1. 入力チェック ---
If TextBox1.Value = "" Or TextBox2.Value = "" Then
MsgBox "商品名と金額を入力してください。", vbExclamation, "入力エラー"
Exit Sub ' ここで処理を終了
End If
' --- 2. 最終行の取得とデータ転記 ---
Dim lastRow As Long
With Worksheets("Sheet1") ' シート名を明示的に指定
lastRow = .Cells(.Rows.Count, 1).End(xlUp).Row + 1
.Cells(lastRow, 1).Value = Date
.Cells(lastRow, 2).Value = TextBox1.Value
.Cells(lastRow, 3).Value = TextBox2.Value
End With
' --- 3. クリア処理 ---
TextBox1.Value = ""
TextBox2.Value = ""
TextBox1.SetFocus
MsgBox "データを登録しました。"
End Sub
重要な構文の解説
Exit Sub
- If文の条件に該当した場合、その場でプロシージャを終了
- これがないと、警告を出した後も登録処理が実行されてしまう
With文
Worksheets("Sheet1")を繰り返し書かずに済む- シートを明示することでバグ防止にも効果的
vbExclamation
- MsgBoxに警告アイコンを表示するオプション
- ユーザーに「注意が必要」と視覚的に伝える
実践チェックリスト
以下を確認して、コードが正しく動作するかテストしてください。
- [ ] 空欄で登録ボタンを押すと、警告メッセージが表示される
- [ ] データを入力して登録すると、最下行の次の行に追加される
- [ ] 登録後、テキストボックスが自動でクリアされる
- [ ] 連続して複数のデータを登録できる
- [ ] カーソルが自動で最初のテキストボックスに戻る
まとめ
本記事で実装した3つの機能は、VBAで業務ツールを作る際の基本パターンです。
| 機能 | キーワード |
|---|---|
| 最終行取得 | End(xlUp).Row + 1 |
| クリア処理 | Value = "" と SetFocus |
| 入力チェック | If ... Then Exit Sub |
これらは在庫管理、アンケート集計、顧客管理など、あらゆるデータ入力ツールで必須のテクニックです。ぜひ自分のプロジェクトでも活用してください。
次回予告:選択式入力でミスを防ぐ
現在のフォームでは商品名を手入力するため、「りんご」と「リンゴ」のような表記揺れが発生する可能性があります。
次回(第7回)では、**ComboBox(コンボボックス)やListBox(リストボックス)**を使って、選択肢から選ぶ形式の入力方法を解説します。
ユーザーの手間を減らし、データの品質を高めるUI設計をマスターしましょう!
