フォームコントロールの操作
メニューを表示するにはスワイプしてください
TextBoxes と ComboBoxes はほとんどのデータ入力に対応していますが、他にも特定の選択肢をより自然に表現できるコントロールがいくつかあります。これらの値を正しく読み取るには、注意すべきポイントがいくつか存在します。
CheckBoxes
CheckBox の Value プロパティは単純なブール値で、チェックされていれば True、そうでなければ False です:
If chkWelcomeEmail.Value = True Then
MsgBox "A welcome email would be sent here."
End If
フォーム上の各 CheckBox は他の CheckBox とは完全に独立しており、chkWelcomeEmail をチェックしても chkNewsletter には影響しません。選択肢が排他的でない場合に理想的な動作です。
OptionButtons
OptionButton は逆の動作をします。同じグループ内では、1つを選択すると他のすべてが自動的に選択解除されます。これは、顧客が同時に Active と Inactive にはなれないため、スクリーンショットの Status 選択肢に最適です。どれが選択されているかを確認するには、それぞれの Value を個別にチェックします:
Dim status As String
If optActive.Value = True Then
status = "Active"
ElseIf optInactive.Value = True Then
status = "Inactive"
ElseIf optProspect.Value = True Then
status = "Prospect"
End If
排他性は自動的に VBA によって処理されるため、1つを選択したときに他の2つを解除するコードを書く必要はありません。ただし、グループ分けが重要です。OptionButton は同じコンテナ(フォーム本体や配置された Frame コントロール)内でのみ排他的に動作します。そのため、同じフォーム上に Status と Priority など2つの OptionButton グループがある場合は、それぞれ異なる Frame 内に配置する必要があります。そうしないと、VBA はすべてを1つの排他的グループとして扱います。
ListBoxes
ListBox は、Figure 5.5 の City リストのように、複数の選択肢を一度に表示し、クリックして開く必要がありません。ComboBox と同様に .AddItem で項目を追加し、選択内容は .Value または .ListIndex で取得します:
Private Sub UserForm_Initialize()
lstCities.AddItem "Chicago"
lstCities.AddItem "Boston"
lstCities.AddItem "Austin"
End Sub
Private Sub cmdAssign_Click()
If lstCities.ListIndex = -1 Then
MsgBox "Please select a city first."
Exit Sub
End If
MsgBox "Assigning to: " & lstCities.Value
End Sub
ListIndex は選択された項目の位置を示し、最初の項目が 0 から始まります。何も選択されていない場合は -1 となり、cmdAssign_Click で都市が選択されていない場合のチェックに利用されています。.Value は選択されたテキスト自体を返し、通常は数値の位置よりも便利です。
Multi-Page Forms
MultiPage コントロール(Figure 5.5 の上部にある Details / Preferences タブ)は、関連するコントロールを同じ物理フォーム上の別々のページにまとめます。フォームにフィールドが多すぎて1画面に収まらない場合に便利です。各ページは位置で指定され、現在表示されているページ上のコントロールのみがユーザーにとって意味を持ちますが、どのページが表示されていてもすべてのコントロールはコードから参照可能です:
Private Sub MultiPage1_Change()
If MultiPage1.Value = 1 Then
MsgBox "Now viewing Preferences"
End If
End Sub
MultiPage1.Value は ListIndex と同じく 0 から始まるカウント方式で、最初のページが 0、2番目(Figure 5.5 の Preferences)が 1 です。Change イベントはユーザーが別のタブをクリックするたびに自動的に発生します。
タスク
- frmAddCustomer に Frame を追加し、その中に 3 つの OptionButton(optActive、optInactive、optProspect)を配置して、以前の cboStatus ComboBox を置き換え、上記の If...ElseIf ブロックを記述して選択内容を取得する。
- 2 つの独立した CheckBox(chkWelcomeEmail、chkNewsletter)を追加し、一方をチェックしても他方に影響しないことをテストで確認する。
- UserForm_Initialize で ListBox(lstCities)を作成し、何も選択されていない場合(ListIndex = -1)にエラーを表示するチェックを記述する。
- チャレンジ:Company Name、Contact、Email フィールドを「Details」という名前の MultiPage の 1 ページにまとめ、CheckBox と OptionButton を 2 ページ目「Preferences」に配置する。
1. cboStatus を OptionButton の Frame で置き換える
- フォームから
cboStatusとそのラベルを削除 — 追加ではなく置き換え。 - Frame コントロールをフォームにドラッグし、その枠内に 3 つの OptionButton をすべてドラッグして配置 — この囲い込みによって 1 グループとして排他的に動作。
- 各 OptionButton の名前はプロパティウィンドウで個別に変更。Frame の Caption は「Status」などシンプルでよく、コードで参照しないなら名前は不要。
- 選択内容の取得は、各 OptionButton の
.ValueをIf...ElseIfで個別に判定 — グループ内でどれが選択されているかを示す単一プロパティは存在しない。 cboStatus.Valueはもう存在しないため、cmdSave_Clickでは OptionButton からstatus変数を作成し、newRowに書き込む。
2. 2 つの独立した CheckBox を追加
- これらはフォーム上に直接配置(Frame 内ではない) — CheckBox 同士が互いに影響を受けない。
- テストでは、一方をチェックしてからもう一方をチェックし、どちらも独立して切り替わることを確認。
3. ListBox の追加とバリデーション
cboCityで.AddItemと同様にUserForm_Initializeを繰り返して項目を追加。ListIndex = -1は「まだ何も選択されていない」状態 — 保存を進める前にこの条件をチェック。- このチェックは他の必須項目チェックと同じ
errors文字列に追加。
4. MultiPage チャレンジ
- MultiPage コントロールをフォームにドラッグ — デフォルトで 2 ページある。
- 各ページはプロパティウィンドウの Caption で名前変更。コード参照には (Name) プロパティを使用。
- 既存コントロールをページにドラッグするだけで、コードの参照名は変わらない。
Private Sub UserForm_Initialize()
cboCity.AddItem "Chicago"
cboCity.AddItem "Boston"
cboCity.AddItem "Austin"
cboCity.AddItem "Seattle"
cboCity.AddItem "Denver"
lstCities.AddItem "Chicago"
lstCities.AddItem "Boston"
lstCities.AddItem "Austin"
lstCities.AddItem "Seattle"
lstCities.AddItem "Denver"
End Sub
Private Sub cmdCancel_Click()
Unload Me
End Sub
Private Sub cmdSave_Click()
Dim tbl As ListObject
Dim newRow As ListRow
Dim errors As String
Dim status As String
' --- Reset field colors ---
txtCompanyName.BackColor = vbWhite
txtContact.BackColor = vbWhite
txtEmail.BackColor = vbWhite
' --- Required field checks ---
If Trim(txtCompanyName.Value) = "" Then
errors = errors & "- Company Name is required" & vbNewLine
txtCompanyName.BackColor = RGB(255, 199, 206)
End If
If Trim(txtContact.Value) = "" Then
errors = errors & "- Contact is required" & vbNewLine
txtContact.BackColor = RGB(255, 199, 206)
End If
If Trim(txtEmail.Value) = "" Then
errors = errors & "- Email is required" & vbNewLine
txtEmail.BackColor = RGB(255, 199, 206)
End If
' --- Status via OptionButtons ---
If optActive.Value = True Then
status = "Active"
ElseIf optInactive.Value = True Then
status = "Inactive"
ElseIf optProspect.Value = True Then
status = "Prospect"
Else
errors = errors & "- Please select a Status" & vbNewLine
End If
' --- ListBox check ---
If lstCities.ListIndex = -1 Then
errors = errors & "- Please select a city from the list" & vbNewLine
End If
If errors <> "" Then
MsgBox "Please fix the following:" & vbNewLine & errors, vbExclamation
Exit Sub
End If
' --- All checks passed — safe to save now ---
Set tbl = ThisWorkbook.Worksheets("Customers").ListObjects("tblCustomers")
Set newRow = tbl.ListRows.Add
newRow.Range(1, 1).Value = "C0" & (tbl.ListRows.Count + 100)
newRow.Range(1, 2).Value = txtCompanyName.Value
newRow.Range(1, 3).Value = txtContact.Value
newRow.Range(1, 4).Value = txtEmail.Value
newRow.Range(1, 5).Value = cboCity.Value
newRow.Range(1, 6).Value = status
If chkWelcomeEmail.Value = True Then
MsgBox "A welcome email would be sent to " & txtEmail.Value & "."
End If
MsgBox txtCompanyName.Value & " was added successfully."
Unload Me
End Sub
テストメモ:
- 2(CheckBox)は専用のバリデーションなし —
chkWelcomeEmailとchkNewsletterを個別にクリックし、互いに影響しないことを確認。 - 4(MultiPage)はレイアウト変更のみ — コード変更は不要。コントロール名はページ移動しても変わらない。
cboCity.Valueは保存時(newRow.Range(1, 5))に引き続き使用され、lstCitiesはタスク要件に従い独立してバリデーションされるコントロール — 必要に応じて連携も可能。
フィードバックありがとうございます!
AIに質問する
AIに質問する
何でも質問するか、提案された質問の1つを試してチャットを始めてください
フォームコントロールの操作
TextBoxes と ComboBoxes はほとんどのデータ入力に対応していますが、他にも特定の選択肢をより自然に表現できるコントロールがいくつかあります。これらの値を正しく読み取るには、注意すべきポイントがいくつか存在します。
CheckBoxes
CheckBox の Value プロパティは単純なブール値で、チェックされていれば True、そうでなければ False です:
If chkWelcomeEmail.Value = True Then
MsgBox "A welcome email would be sent here."
End If
フォーム上の各 CheckBox は他の CheckBox とは完全に独立しており、chkWelcomeEmail をチェックしても chkNewsletter には影響しません。選択肢が排他的でない場合に理想的な動作です。
OptionButtons
OptionButton は逆の動作をします。同じグループ内では、1つを選択すると他のすべてが自動的に選択解除されます。これは、顧客が同時に Active と Inactive にはなれないため、スクリーンショットの Status 選択肢に最適です。どれが選択されているかを確認するには、それぞれの Value を個別にチェックします:
Dim status As String
If optActive.Value = True Then
status = "Active"
ElseIf optInactive.Value = True Then
status = "Inactive"
ElseIf optProspect.Value = True Then
status = "Prospect"
End If
排他性は自動的に VBA によって処理されるため、1つを選択したときに他の2つを解除するコードを書く必要はありません。ただし、グループ分けが重要です。OptionButton は同じコンテナ(フォーム本体や配置された Frame コントロール)内でのみ排他的に動作します。そのため、同じフォーム上に Status と Priority など2つの OptionButton グループがある場合は、それぞれ異なる Frame 内に配置する必要があります。そうしないと、VBA はすべてを1つの排他的グループとして扱います。
ListBoxes
ListBox は、Figure 5.5 の City リストのように、複数の選択肢を一度に表示し、クリックして開く必要がありません。ComboBox と同様に .AddItem で項目を追加し、選択内容は .Value または .ListIndex で取得します:
Private Sub UserForm_Initialize()
lstCities.AddItem "Chicago"
lstCities.AddItem "Boston"
lstCities.AddItem "Austin"
End Sub
Private Sub cmdAssign_Click()
If lstCities.ListIndex = -1 Then
MsgBox "Please select a city first."
Exit Sub
End If
MsgBox "Assigning to: " & lstCities.Value
End Sub
ListIndex は選択された項目の位置を示し、最初の項目が 0 から始まります。何も選択されていない場合は -1 となり、cmdAssign_Click で都市が選択されていない場合のチェックに利用されています。.Value は選択されたテキスト自体を返し、通常は数値の位置よりも便利です。
Multi-Page Forms
MultiPage コントロール(Figure 5.5 の上部にある Details / Preferences タブ)は、関連するコントロールを同じ物理フォーム上の別々のページにまとめます。フォームにフィールドが多すぎて1画面に収まらない場合に便利です。各ページは位置で指定され、現在表示されているページ上のコントロールのみがユーザーにとって意味を持ちますが、どのページが表示されていてもすべてのコントロールはコードから参照可能です:
Private Sub MultiPage1_Change()
If MultiPage1.Value = 1 Then
MsgBox "Now viewing Preferences"
End If
End Sub
MultiPage1.Value は ListIndex と同じく 0 から始まるカウント方式で、最初のページが 0、2番目(Figure 5.5 の Preferences)が 1 です。Change イベントはユーザーが別のタブをクリックするたびに自動的に発生します。
タスク
- frmAddCustomer に Frame を追加し、その中に 3 つの OptionButton(optActive、optInactive、optProspect)を配置して、以前の cboStatus ComboBox を置き換え、上記の If...ElseIf ブロックを記述して選択内容を取得する。
- 2 つの独立した CheckBox(chkWelcomeEmail、chkNewsletter)を追加し、一方をチェックしても他方に影響しないことをテストで確認する。
- UserForm_Initialize で ListBox(lstCities)を作成し、何も選択されていない場合(ListIndex = -1)にエラーを表示するチェックを記述する。
- チャレンジ:Company Name、Contact、Email フィールドを「Details」という名前の MultiPage の 1 ページにまとめ、CheckBox と OptionButton を 2 ページ目「Preferences」に配置する。
1. cboStatus を OptionButton の Frame で置き換える
- フォームから
cboStatusとそのラベルを削除 — 追加ではなく置き換え。 - Frame コントロールをフォームにドラッグし、その枠内に 3 つの OptionButton をすべてドラッグして配置 — この囲い込みによって 1 グループとして排他的に動作。
- 各 OptionButton の名前はプロパティウィンドウで個別に変更。Frame の Caption は「Status」などシンプルでよく、コードで参照しないなら名前は不要。
- 選択内容の取得は、各 OptionButton の
.ValueをIf...ElseIfで個別に判定 — グループ内でどれが選択されているかを示す単一プロパティは存在しない。 cboStatus.Valueはもう存在しないため、cmdSave_Clickでは OptionButton からstatus変数を作成し、newRowに書き込む。
2. 2 つの独立した CheckBox を追加
- これらはフォーム上に直接配置(Frame 内ではない) — CheckBox 同士が互いに影響を受けない。
- テストでは、一方をチェックしてからもう一方をチェックし、どちらも独立して切り替わることを確認。
3. ListBox の追加とバリデーション
cboCityで.AddItemと同様にUserForm_Initializeを繰り返して項目を追加。ListIndex = -1は「まだ何も選択されていない」状態 — 保存を進める前にこの条件をチェック。- このチェックは他の必須項目チェックと同じ
errors文字列に追加。
4. MultiPage チャレンジ
- MultiPage コントロールをフォームにドラッグ — デフォルトで 2 ページある。
- 各ページはプロパティウィンドウの Caption で名前変更。コード参照には (Name) プロパティを使用。
- 既存コントロールをページにドラッグするだけで、コードの参照名は変わらない。
Private Sub UserForm_Initialize()
cboCity.AddItem "Chicago"
cboCity.AddItem "Boston"
cboCity.AddItem "Austin"
cboCity.AddItem "Seattle"
cboCity.AddItem "Denver"
lstCities.AddItem "Chicago"
lstCities.AddItem "Boston"
lstCities.AddItem "Austin"
lstCities.AddItem "Seattle"
lstCities.AddItem "Denver"
End Sub
Private Sub cmdCancel_Click()
Unload Me
End Sub
Private Sub cmdSave_Click()
Dim tbl As ListObject
Dim newRow As ListRow
Dim errors As String
Dim status As String
' --- Reset field colors ---
txtCompanyName.BackColor = vbWhite
txtContact.BackColor = vbWhite
txtEmail.BackColor = vbWhite
' --- Required field checks ---
If Trim(txtCompanyName.Value) = "" Then
errors = errors & "- Company Name is required" & vbNewLine
txtCompanyName.BackColor = RGB(255, 199, 206)
End If
If Trim(txtContact.Value) = "" Then
errors = errors & "- Contact is required" & vbNewLine
txtContact.BackColor = RGB(255, 199, 206)
End If
If Trim(txtEmail.Value) = "" Then
errors = errors & "- Email is required" & vbNewLine
txtEmail.BackColor = RGB(255, 199, 206)
End If
' --- Status via OptionButtons ---
If optActive.Value = True Then
status = "Active"
ElseIf optInactive.Value = True Then
status = "Inactive"
ElseIf optProspect.Value = True Then
status = "Prospect"
Else
errors = errors & "- Please select a Status" & vbNewLine
End If
' --- ListBox check ---
If lstCities.ListIndex = -1 Then
errors = errors & "- Please select a city from the list" & vbNewLine
End If
If errors <> "" Then
MsgBox "Please fix the following:" & vbNewLine & errors, vbExclamation
Exit Sub
End If
' --- All checks passed — safe to save now ---
Set tbl = ThisWorkbook.Worksheets("Customers").ListObjects("tblCustomers")
Set newRow = tbl.ListRows.Add
newRow.Range(1, 1).Value = "C0" & (tbl.ListRows.Count + 100)
newRow.Range(1, 2).Value = txtCompanyName.Value
newRow.Range(1, 3).Value = txtContact.Value
newRow.Range(1, 4).Value = txtEmail.Value
newRow.Range(1, 5).Value = cboCity.Value
newRow.Range(1, 6).Value = status
If chkWelcomeEmail.Value = True Then
MsgBox "A welcome email would be sent to " & txtEmail.Value & "."
End If
MsgBox txtCompanyName.Value & " was added successfully."
Unload Me
End Sub
テストメモ:
- 2(CheckBox)は専用のバリデーションなし —
chkWelcomeEmailとchkNewsletterを個別にクリックし、互いに影響しないことを確認。 - 4(MultiPage)はレイアウト変更のみ — コード変更は不要。コントロール名はページ移動しても変わらない。
cboCity.Valueは保存時(newRow.Range(1, 5))に引き続き使用され、lstCitiesはタスク要件に従い独立してバリデーションされるコントロール — 必要に応じて連携も可能。
フィードバックありがとうございます!