【VBA入門】第6回:データを蓄積する本格的な入力フォームの作り方

前回(第5回)では、UserFormのボタンにVBAコードを書き込み、テキストボックスの内容をセルに転記することに成功しました。「ボタンを押すとセルに文字が入る」という感動を味わえたと思います。

しかし、前回のコードには重大な問題がありました。何度ボタンを押しても同じセルに上書きされてしまうのです。これでは顧客リストや家計簿のような実用的なツールは作れません。

今回実装する3つの機能

本記事では、以下の機能を実装して実務レベルのフォームを完成させます。

  1. 最終行の自動取得 - データを上書きせず、常に最下行に追加
  2. 入力項目のクリア - 登録後にテキストボックスを自動で空にする
  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設計をマスターしましょう!

\ 最新情報をチェック /

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です