ExcelとAccessのスキルアップをサポートするサイトです

ExcelとAccessの学習室

Excelでユーザーフォームを作るためのテクニック5選

VBAを使えるようになってくると、ユーザーフォームを作りたくなりますよね?

今回は、ユーザーフォームを作るテクニックについて解説します。

この記事を書いている私は、10年前からVBAを活用して業務改善を続けてきました。

ユーザーフォームもたくさん作ってきました。

ユーザーフォームには多くのパーツがあります。パーツの数だけテクニックがありますが、「こういう使い方を覚えれば大丈夫」という項目に絞って解説します。

VBAをある程度使えるけど、ユーザーフォームの経験が少ない方」が対象になります。
また、たまにしかユーザーフォームを使わない方にとっても、忘備録として活用できるようにしました。

サンプルコードも載せておきますが、100%の動作保証が取られるものではありませんので、ご自分のフォームに合わせてカスタマイズして頂ければと思います。

テクニック1-フォームを起動したり閉じたりする

ユーザーフォームを使ったことの無い方は、まずは開き方と閉じ方をしっかりと覚えておきましょう

この記事では、下の表を作ってユーザーフォームでデータを表示してみます。

ユーザーフォームを作る

次にユーザーフォームを作ります。

オブジェクトブラウザを右クリックし、「挿入」→「ユーザーフォーム」の順に選択します。

ユーザーフォームが作成されるので、閉じるためのボタンも設置します。

OPENメソッドで作ったフォームを開くことが出来ます。

ユーザーフォームの開き方

ユーザーフォームを作るだけでは、フォームを起動することが出来ません。

ワークシートにボタン設けてフォームを起動してみます。

VBEで標準モジュールを作成します。

ユーザーフォームと同様に、「挿入」→「標準モジュール」の順に選択します。

標準モジュールにフォームを起動させるコードを書きます。

Sub OpenForm1()
    'ユーザーフォームを起動させる
    UserForm1.Show 
End Sub

次にボタンを右クリックし、マクロを登録します。

「OpenForm1」プロシージャを選択します。

ボタンをクリックすると、ユーザーフォームが起動することが確認できました。

「CommandButton1」をクリックしても、なにも作動しません。

一旦×ボタンでフォームを閉じます。

ユーザーフォームの閉じ方

ここでは、ユーザーフォーム上のボタンを使って閉じる方法を紹介します。

「CommondButton1」をクリックし、「コードの表示」をクリックします。

エディターが表示され、以下のようにコードが書かれています。

Private Sub CommandButton1_Click()

End Sub

フォームを閉じるための一文を追加し、下のように修正します。

Private Sub CommandButton1_Click()
   Unload UserForm1 'UserForm1を閉じる
End Sub 

ボタンをクリックすることで、開いていたユーザーフォームを閉じることができます。

ボタンの名前を編集する

左下の「プロパティウインドウ」で、ボタンの名前や表示を設定することもできます。

名前は「オブジェクト名」、表示は「Caption」で編集できます。

オブジェクト名を「閉じる」とすると、

Private Sub 閉じる_Click()
   Unload UserForm1 'UserForm1を閉じる
End Sub 

のようにプロシージャ名を変えなければいけません。

テクニック2-開いた時にプログラムを作動させる

エディターの上部に選択ボックスがあります。
項目を選択することで、パーツのイベントプロシージャを作ることが出来ます。

「UserForm」を選択します。

隣のボックスは、「Initialize」を選択します。

新しいイベントプロシージャを作成できました。

フォームが起動したと同時に命令を出すことが出来ます。

新しく作ったテキストボックスに文字を表示させてみます。

文字を表示させるためのテキストボックスをユーザーフォームに配置します。

「UserForm_Initialize」プロシージャに、データ表示するコードを書きます。

Private Sub UserForm_Initialize()
    'テキストボックスに表示させる
    Me.TextBox1.Value = "Hello World"
End Sub

フォームを起動させると、テキストボックスに文字を表示できました。

フォーム起動時には、

  • コンボボックスやリストボックスなどに選択データを登録する
  • 特定のワークシート内のデータを取得する

といった動作をよく行います。

テクニック3-モーダルとモードレスを使い分ける

「ユーザーフォームを起動させると、ワークシートを操作出来ない」

こういったことが不便に感じたことはありませんか?

「モードレス」を指定すれば、フォームを起動しながらワークシートの編集が可能です。

Sub OpenForm1()
    'モードレスでフォームを表示(シート編集可)
    UserForm1.Show vbModeless
End Sub

一方、初期設定されている編集できない状態は「モーダル」と呼ばれます。

Sub OpenForm1()
    'モーダルでフォームを表示(シート編集不可)
    UserForm1.Show vbModal
End Sub

誰かにワークシートの中身を書き換えられたくない場合は、モーダル設定の方が適しています。

モーダルとモードレスは用途によって使い分けましょう。

テクニック4-コンボボックスを使いこなす

コンボボックスは、ワークシートの入力規則と同じように、複数の選択データを格納することが出来ます。

新しいフォームUserForm2を作り、オブジェクトを配置します。

※使用するオブジェクト名は()内に記載しています。

Additemで収納する

コンボボックスには、定数とセルの値の両方を格納することが可能です。

フォームの起動時に商品CDを定数で格納してみます。

Private Sub UserForm_Initialize()
    'AddItemで格納(定数)
    Me.ComboBox1.AddItem "S01"
    Me.ComboBox1.AddItem "S02"
    Me.ComboBox1.AddItem "S03"
    Me.ComboBox1.AddItem "S04"
    Me.ComboBox1.AddItem "S05"
    Me.ComboBox1.AddItem "S06"
    Me.ComboBox1.AddItem "S07"
End Sub

データの格納はAdditemでシンプルに書けますが、商品CDが多くなると行数が増えます。

商品マスタの増減とともに都度コードを変えなければいけません。

一方、A列のデータを変数を使って格納するコードです。

Private Sub UserForm_Initialize()
    'AddItemで格納(変数)
    Dim n As Integer
    For n = 0 To Sheets("Sheet1").Range("A1").End(xlDown).Row - 2
        Me.ComboBox1.AddItem Cells(2 + n, 1).Value
    Next n
End Sub

繰り返し(ループ)を使っていますので、商品の増減にも自動で対応できます。

実行すると、いずれもコンボボックスにデータが格納されているのが分かります。

RowSourceで収納する

AddItemはデータを一個ずつ格納する方法ですが、RowSourceを使うと、セルの範囲をそのまま指定できます。

範囲を定数で指定したパターンです。

 Private Sub UserForm_Initialize()
    'RowSourceで格納("範囲の変更非対応")
    Me.ComboBox1.RowSource = Sheets("Sheet1").Range("A2:A8").Address
End Sub

商品マスタが増減した場合はコードの修正が必要です。

A列の最終行を取得し、商品マスタの増減に対応したパターンです。

 Private Sub UserForm_Initialize()
    'RowSourceで格納("範囲の変更対応")
    Me.ComboBox1.RowSource = Sheets("Sheet1").Range(Cells(2, 1),_ 
    Cells(Sheets("Sheet1").Range("A1").End(xlDown).Row, 1)).Address
End Sub

コード自体は長くなりますが、運用上このパターンをオススメします。

コンボボックスからデータを参照する

Excelでワークシートで入力規則とVLOOKUP関数を組み合わせる方法って、とても便利ですよね?

ユーザーフォームのコンボボックスでも、WorksheetFunctionを使って、同じような方法ができます。

Private Sub ComboBox1_Change()
    Dim i As Integer
    'VLOOKUP関数を使ってテキストボックスにデータを反映
    For i = 1 To 4
        Me.Controls("TextBox" & i).Value = _
        WorksheetFunction.VLookup(Me.ComboBox1.Value, Sheets("Sheet1")._
        Range("A1:E8"), i + 1, 0)
    Next i
End Sub

商品CDを選択すると、各テキストボックスにデータが反映されます。

テクニック5-リストボックスを使って複数のデータを選択する

リストボックスも複数のデータを収納できますが、更に便利に使えます。

  • 列ごとの幅を決める
  • 列見出しを表示する
  • 項目を複数選択させる
  • 左端にチェックボックスを表示させる

といった設定がありますが、下のコードは全てを有効にしています。

Private Sub UserForm_Initialize()
    '列数の表示
    ListBox1.ColumnCount = 5
    '各列の幅
    ListBox1.ColumnWidths = "40;40;80;40;40"
    '見出し列の表示
    ListBox1.ColumnHeads = True
    '複数選択
    ListBox1.MultiSelect = fmMultiSelectExtended
    ListBox1.ListStyle = fmListStyleOption
    '範囲の指定
    ListBox1.RowSource = Worksheets("Sheet1").Range("A2:E8").Address
End Sub

不要なコードは削除するかコメントするかで無効にできます。

実行すると、左端にチェックボックスが表示されています。

Ctrlキーを押しながら複数データを選択できます。

また、選択した複数データをメッセージボックスで表示するコードです。

Private Sub CommandButton2_Click()
Dim i As Integer
    '選択した複数データを表示
    For i = 0 To ListBox1.ListCount - 1
        If ListBox1.Selected(i) = True Then
            MsgBox (ListBox1.List(i, 0) & ":" & ListBox1.List(i, 1))
        End If
    Next
    MsgBox ("おわり")
End Sub

例えば、複数のデータを選択して、帳票をまとめて印刷させるときにはとても便利です。

まとめ

ユーザーフォームについて解説しました。
今回は、項目を絞り他のパーツは省略しましたが、実務に使える本当に大事なところを盛り込んでいます。

ユーザーフォームを使えるようになりたい方は、是非こちらのコードをコピペして自分流にアレンジしてみましょう。

ユーザーフォームで別のパーツを使う時にも、イベントプロシージャとオプションを扱えれば何とかなります。


本日もありがとうございました。