【簡単Excelマクロ・VBA】ユーザーフォーム|UserForm|Excelオブジェクトの操作 #004
いつもありがとうございます。
ノンプログラマー向け「Excelマクロ・VBA解説シリーズ」へようこそ。
本稿では、ユーザーフォームを操作する方法を解説いたします。
ユーザーフォームは、ユーザーとコミュニケーションするためのインターフェースで、さまざまなコントロールを使って柔軟にカスタマイズできます。
たとえば、テキストボックスでユーザーからの入力を受け取ったり、ドロップダウンリストで選択肢を提供したり、オプションボタンやチェックボックスを使って選択肢を簡単に選ばせたりすることができます。
ことばの意味
- ノンプログラマー・・・プログラミングを本職としない人たちのことです。
- マクロ・・・VBAを使って作成される「機能」のことです。
- VBA・・・Visusal Basic for Application の略で、プログラミング言語のことです。
- コントロール・・・ボタンやテキストなどのユーザーフォーム上に配置される部品のことです。
関連記事
VBAにおけるExcelオブジェクト操作の全体像
VBAにおける「Excelオブジェクトの操作」の全体像は以下の記事で解説しております。
本稿では「Excelオブジェクトの操作」の一部である「ユーザーフォームを操作する方法」を解説いたします。
VBAでユーザーフォームを操作する方法
ユーザーフォームのコントロール(部品)の一覧
下表に、ユーザーフォームに実装することのできるコントロールの代表例を示します。本稿では、この中から代表的なコントロールをいくつかサンプルとして取り上げ、具体的なコードを解説していきたいと思います。
ことばの意味
- コントロール
ボタンやテキストなどのユーザーフォーム上に配置される部品のことです。
コントロール | 説明 |
---|---|
テキストボックス | ユーザーが文字や数字を入力するためのフィールドです。 |
ラベル | テキストや指示を表示するための要素です。 |
コマンドボタン | ユーザーがクリックして操作を実行するボタンです。 |
ドロップダウンリスト | 複数の選択肢から1つを選べるリストです。 |
リストボックス | 複数選択可能なリストから1つまたは複数を選択できる機能です。 |
オプションボタン | グループ内から1つの選択肢を選ぶためのボタンです。 |
チェックボックス | 複数の選択肢を独立して選べるチェックボックスです。 |
マルチページ | タブ形式で複数のページを作成し、それぞれに異なる内容を配置できる機能です。 |
フレーム | ボタンやテキストボックスなど、関連する要素をひとまとめにするための枠(フレーム)です。 |
画像表示 | フォーム内に画像を表示する機能です。 |
スピンボタン | 数値の増減を行うためのボタンです。 |
スクロールバー | 指定範囲内の値をスクロールして選択できるバーです。 |
プログレスバー | 処理の進行状況を視覚的に表示するためのバーです。 |
代表的なコントロールを使用したユーザーフォームの事例と解説
シナリオ
ユーザーフォーム上でユーザーが入力した情報をもとに、Excelシートの情報を更新するアプリケーションを作成します。ユーザーフォームは以下のようなものにします。
ユーザーフォームの作成
ユーザーフォームを使ったアプリケーションでは、コードとは別に、まず"ユーザーフォーム" を作成する必要があります。以下に、ユーザーフォームの作成方法を解説していきます。
まず、VBE(Visual Basic Editor)の「挿入」メニューから「ユーザーフォーム」を選び、ユーザーフォームを挿入します。
このようなまっさらのユーザーフォームが挿入されます。
ユーザーフォームが挿入されたら、ユーザーフォームのタイトルを設定します。ユーザーフォームプロパティ(通常、左下に表示されている)の「Caption」に「在庫補充」と入力します。※ここは好きな名称で良いです。
次に各コントロールを配置していきます。コントロールは、ツールボックスからドラッグ&ドロップで配置できます。
次に各コントロールのオブジェクト名を設定していきます。コマンドボタンのみキャプション名も設定します。
以上でユーザーフォームの作成は完了です。
コードの実装
次にコードを実装していきます。
コードは、通常であれば、標準モジュールに記述していきますが、ユーザーフォームの場合はユーザーフォームにコードを記述していきます。ユーザーフォームの上で右クリックすると「コードの表示」というメニューが表示されますので、これをクリックします。
そうすると下図のように、ユーザーフォームのコードモジュール画面が開きます。ここにコードを記述していきます。
コードは以下の通りです。
Private Sub UserForm_Initialize()
' 商品名リストを初期化
With cmb_product ' 商品名を選択するためのコンボボックス
.AddItem "商品A"
.AddItem "商品B"
.AddItem "商品C"
End With
End Sub
Private Sub btn_update_Click()
' 変数宣言
Dim wb As Workbook ' アクティブなワークブックを格納するための変数
Dim ws As Worksheet ' 在庫管理シートを格納するための変数
Dim product_name As String ' 選択された商品名を格納するための変数
Dim quantity As Long ' 入力された数量を格納するための変数
Dim search_result As Range ' 商品名の検索結果を格納するための変数
' ワークブックとワークシートを取得する
Set wb = ThisWorkbook
Set ws = wb.Sheets("在庫管理")
' 選択された商品名と数量を取得
product_name = cmb_product.Value
quantity = CLng(txt_quantity.Value) ' 数量を取得して数値に変換
' 商品名がシートのどこにあるかを検索
Set search_result = ws.Range("F:F").Find(What:=product_name, LookIn:=xlValues, LookAt:=xlWhole)
If Not search_result Is Nothing Then
' 見つかった場合、その行の在庫数量を更新
ws.Cells(search_result.Row, 7).Value = ws.Cells(search_result.Row, 7).Value + quantity
MsgBox "在庫が更新されました。", vbInformation
Else
MsgBox "商品が見つかりませんでした。", vbExclamation
End If
End Sub
また、Excelシートは以下のように設計しておきます。「在庫を補充する」ボタンにPrivate Sub UserForm_Initialize()
を登録しておき、クリックされるとユーザーフォームが立ち上がるようにしておきます。シート名は「在庫管理」にします。
尚、マクロの登録方法を調べたい場合は、こちらの記事の中の該当部を参考にしていただければ幸いでございます。
コードの解説をしていきます。
まず、通常であれば Sub
ステートメントにコードを記述していきますが、ユーザーフォームのコードモジュールにコードを記述していく場合は、一般的に Private Sub
ステートメントにコードを記述してきます。
Sub
と Private Sub
の違いは以下の通りです。
項目 | Sub | Private Sub |
---|---|---|
アクセスレベル | パブリック(公開)。他のモジュールやクラスからも呼び出せる。 | プライベート(非公開)。同じモジュール内でのみ呼び出せる。 |
スコープ | グローバルまたはモジュールレベル。 | モジュールレベルのみ。 |
使用用途 | 他のモジュールやクラスからもアクセス可能なプロシージャ。 | 同じモジュール内でのみ使用するプロシージャ。 |
イベントハンドラとしての利用 | 可能だが、通常は Private Sub が推奨される。 | 主にイベントハンドラとして使用される。 |
セキュリティ | 他のモジュールやクラスから意図せず呼び出されるリスクがある。 | 他のモジュールやクラスからは呼び出されないため、リスクが低い。 |
まず、Private Sub Userform_Initialize()
を解説します。
Private Sub UserForm_Initialize()
' 商品名リストを初期化
With cmb_product ' 商品名を選択するためのコンボボックス
.AddItem "商品A"
.AddItem "商品B"
.AddItem "商品C"
End With
End Sub
このコードは、ユーザーフォームが表示される前に実行される処理で、商品名を選択するコンボボックス(cmb_product
)に「商品A」、「商品B」、「商品C」というアイテムを追加しています。
具体的には、コンボボックスオブジェクト cmb_product に、AddItem メソッドを使って「商品A」、「商品B」、「商品C」を追加しています。
これにより、ユーザーフォームが表示された際には、これらの商品名から選択できる状態になります。
尚、With
ステートメントは、特定のオブジェクトに対して複数の操作を簡潔にまとめるための構文です。これにより、オブジェクト名を繰り返し書く手間を省き、コードを短く読みやすくします。
次に、Private Sub btn_update_Click()
を解説します。
' 変数宣言
Dim wb As Workbook ' アクティブなワークブックを格納するための変数
Dim ws As Worksheet ' 在庫管理シートを格納するための変数
Dim last_row As Long ' シートの最後の行番号を格納するための変数
Dim product_name As String ' 選択された商品名を格納するための変数
Dim quantity As Long ' 入力された数量を格納するための変数
Dim search_result As Range ' 商品名の検索結果を格納するための変数
ここでは変数の宣言をしています。Dim 変数 As データ型
の構文で宣言します。これにより各変数は、As 以降で指定したデータ型のデータを保持できるようになります。
' ワークブックとワークシートを取得する
Set wb = ThisWorkbook
Set ws = wb.Sheets("在庫管理")
ここでは、このマクロを記述しているワークブックとワークシートを、オブジェクト変数 wb、ws に格納しています。これにより、これ以降のコードにおいて、これらのオブジェクトを簡単に参照できるようになります。
' 選択された商品名と数量を取得
product_name = cmb_product.Value
quantity = CLng(txt_quantity.Value) ' 数量を取得して数値に変換
ここでは、ユーザーフォーム上のコンボボックスから選択された商品名と、テキストボックスに入力された数量を取得し、それぞれを変数に格納する処理を行っています。
数量の方は、CLng
関数を使って文字列を数値(Long
型)に変換し、その値を quantity
という変数に格納しています。
' 商品名がシートのどこにあるかを検索
Set search_result = ws.Range("F:F").Find(What:=product_name, LookIn:=xlValues, LookAt:=xlWhole)
If Not search_result Is Nothing Then
' 見つかった場合、その行の在庫数量を更新
ws.Cells(search_result.Row, 7).Value = ws.Cells(search_result.Row, 7).Value + quantity
MsgBox "在庫が更新されました。", vbInformation
Else
MsgBox "商品が見つかりませんでした。", vbExclamation
End If
ここでは、ユーザーフォームで入力された商品名がシート内に存在するかを検索し、見つかった場合はその商品の在庫数量を更新、見つからなかった場合はユーザーに商品が見つからなかったことを通知しています。
35行目のSet search_result = ws.Range("F:F").Find(What:=product_name, LookIn:=xlValues, LookAt:=xlWhole)
が難解ですが、ここではワークシートws
の F 列から product_name
という変数に格納された商品名を検索しています。
下表にFind
メソッドの各引数の意味を示します。
引数名 | 説明 |
---|---|
What | 検索する値を指定します。この場合は、変数 product_name に格納された商品名を検索します。 |
LookIn | 検索対象とする内容を指定します。xlValues はセルの値を対象とすることを意味します。 |
LookAt | 一致の条件を指定します。xlWhole は、完全に一致するセルのみを検索することを意味します。 |
Private Sub btn_update_Click()
全体としては、ユーザーフォーム上の btn_update
ボタンがクリックされたときに、ユーザーが選択した商品名と数量に基づいて在庫情報を検索し、該当する商品が見つかった場合は在庫を更新する処理が行われています。
以上がコードの解説です。
ことばの意味
- イベントハンドラ
特定の「イベント」が発生したときに自動的に実行されるコードやプロシージャのことを指します。プログラム内でユーザーが何かしらのアクションを行ったとき(例えばボタンをクリックしたとき、テキストボックスに文字を入力したとき、フォームが表示されたときなど)に、そのアクションに応じて特定の処理を実行するのがイベントハンドラの役割です。 - 構文
プログラミング言語の文法のことです。
おわりに
ご覧いただきありがとうございました。
本稿では、「Excelオブジェクトの操作」の中の「ユーザーフォームを操作する方法」を解説いたしました。
お問い合わせやご要望等ございましたら、「お問い合わせ/ご要望」またはコメントにて、ご連絡いただければ幸いでございます。
皆様の人生がより一層素晴らしいものになるよう、少しでもお役に立てれば幸いでございます。
なお、当サイトでは様々な情報を発信しております。もしよろしければ、トップページもご覧いただけると幸いでございます。
筆者の記事関連経験
- VBA使用経験約20年
実務に使用するマクロを多数作成してきました。 - Python 3 エンジニア認定基礎試験
経済産業省が定めたガイドライン「ITスキル標準(ITSS)」に掲載されている民間資格です。
VBAプログラミングスキルアップのための参考情報
ここでは参考図書を紹介いたしますが、これらに限らず自分に合うものを選ぶことが重要だと考えております。皆様の、より一層のご成功を心よりお祈りしております。
VBAプログラミングのスキルアップ
学習用としてもハンドブックとしても役立つ便利な書籍がこちらです。価格はやや高めですが、その内容は非常に充実しています。相応のスキルを身に付けるためには、こうしたしっかりとした書籍を一冊持っておくと良いでしょう。
入門書に関しては、どの書籍も大きな違いはありません。あまり迷うことに時間をかけるよりは、手頃なものを一冊選んでみると良いでしょう。VBAの入門書は数多く出版されていますので、興味がある方はぜひチェックしてみてください。
甲乙つけがたい場合、私はインプレス社の「いちばんやさしい」シリーズを選ぶことが多いです。
\チェックしてみよう/
\チェックしてみよう/
\チェックしてみよう/
VBAのプログラミング能力を客観的に証明したい場合には「VBAエキスパート試験」があります。この試験はVBAの知識を公式に認定するものです。VBAの総合的な能力獲得を目指す方に適しています。以下の公式テキストが販売されております。
プログラミングの一般教養
「独学プログラマー」というプログラミングの魅力を解説した書籍があります。これはVBAではなくPythonを題材としていますが、プログラミングの基本的な知識や思考法、仕事の進め方まで幅広く学べます。
こちらの記事でも紹介しております。もしよろしければご覧ください。