TOP

VBA-第 12.2 课。控件 (Controls)

YouLibreCalc for Excel logo

控件 (Controls) 具有各种属性和许多与其关联的事件,但现在我们只关注 VBA 编程中使用的几个属性。


我们首先添加 3 个控件 - Label、TextBox 和 CommandButton:

编辑此控件的名称和属性(使用包含文本的 Caption 属性)以获得以下结果:

现在,当我们输入数字并单击“确定”时,没有任何反应。

为了创建一个操作,我们将添加一个事件,该事件会将输入的值从文本框写入单元格 A1 并关闭表单。

您可以通过双击该控件来访问如下所示的选项:

该下拉列表包含各种控件和该表单。

选择按钮(Button)和Click事件:

Private Sub CommandButton_validate_Click()

     Range("A1") = Textbox_number.Value
     'Textbox_number 是文本框的名称
     'Value 是包含文本框值的属性
    
     Unload Me
     '卸载关闭表单 (UserForm)
     '我们使用 Me 而不是表单名称(因为此代码位于我们要关闭的 UserForm 的中间)
End Sub

现在,在关闭此表单 (UserForm) 之前,输入的值已保存在单元格 A1 中。

添加第二个标题 (Label) 并编辑以下属性:Caption、Forecolor(颜色:红色)和 Visible(False 以隐藏默认控件):

现在让我们添加一个事件,当用户更改文本字段中的值时将触发该事件。如果该值不是数字,该事件将显示一条错误消息。

Private Sub Textbox_number_Change()
     If IsNumeric(Textbox_number.Value) Then 'IF 是一个数值...
         Label_error.Visible = False '标题 (Label) 已隐藏
     Else '否则...
         Label_error.Visible = True '显示名称
     End If
End Sub

每次输入下一个字符时都会测试输入的值。

我们仍然需要在表单上添加输入值的验证(validation)。如果该值不是数字,我们将显示一条消息:

Private Sub CommandButton_validate_Click()
     If IsNumeric(Textbox_number.Value) Then 'IF 是一个数值...
         Range("A1") = Textbox_number.Value '复制到A1
         Unload Me '我要关门了
     Else '否则...
         MsgBox "Incorrect value" '无效值
     End If
End Sub

为了在没有错误消息时不让窗体右侧为空,我们可以通过调整该窗体的 Width 属性来减小其大小:

Private Sub Textbox_number_Change()
     If IsNumeric(Textbox_number.Value) Then 'IF 是一个数值...
         Label_error.Visible = False '标题 (Label) 已隐藏
         Me.Width = 156 '表格宽度
     Else '否则...
         Label_error.Visible = True '显示名称
         Me.Width = 244 '表格宽度
     End If
End Sub

您可以下载Excel示例文件:userform1.xls

结果如下:

Checkboxes

以下是如何使用 CheckBox 的示例:

当复选框被选中/取消选中时,可以使用 Click 事件更改关联单元格的值:

Private Sub CheckBox1_Click() '1号
     If CheckBox1.Value = True Then '如果选择...
        Range("A2") = "Checked"
     Else '如果没有选择...
        Range("A2") = "Unchecked"
     End If
End Sub

Private Sub CheckBox2_Click() '2号
     If CheckBox2.Value = True Then '如果选择...
        Range("B2") = "Checked"
     Else '如果没有选择...
        Range("B2") = "Unchecked"
     End If
End Sub

Private Sub CheckBox3_Click() '3号
     If CheckBox3.Value = True Then '如果选择...
        Range("C2") = "Checked"
     Else '如果没有选择...
        Range("C2") = "Unchecked"
     End If
End Sub

在此示例中,首次打开表单时,最初未选中复选框。

要在相应单元格的值为“已选中”(“Checked”)时检查每个复选框,我们将使用 UserForm_Initialize 对表单激活运行检查:

Private Sub UserForm_Initialize() '如果选中
     If Range("A2") = "Checked" Then
         CheckBox1.Value = True
     End If
     
     If Range("B2") = "Checked" Then
         CheckBox2.Value = True
     End If
     
     If Range("C2") = "Checked" Then
         CheckBox3.Value = True
     End If
End Sub

您可以在此处看到已完成的 Excel 文件中的示例: userform2.xls

选项按钮 (Option Buttons)

当使用选项按钮(Option Buttons 或有时也称为 Radio Buttons)时,用户只能为每个“组”选择一个选项,这与用户可以一次勾选多个框的复选框不同。

要创建“组”,请首先插入 Frame,然后插入 OptionButton:

您可以在此处看到已完成的 Excel 文件中的示例: userform3.xls

提交表单时,数据将输入到与所选列名称 (column_value) 和行 (row_value) 关联的单元格中。

为了知道选择了哪些选项,我们可以执行与前面示例(带有复选框)相同的操作,但我们将使用循环来减少代码大小。

我们将使用 For Each 循环,这是我们之前没有介绍过的一种循环。此循环允许您对“对象组”中的每个对象执行指令:

Private Sub CommandButton1_Click()
     Dim column_value As String, row_value As String
     
     '循环每个 Frame_column 控件
     For Each column_button In Frame_column.Controls
         '如果控制值 = True(则如果选择)...
         If column_button.Value Then
            '变量“column_value”采用按钮文本值
            column_value = column_button.Caption
         End If
     Next
     
     '循环另一个块
     For Each row_button In Frame_row.Controls
         If row_button.Value Then
             row_value = row_button.Caption
         End If
     Next

     Range(column_value & row_value) = "Cell chosen!"  '“细胞已选定!”
     
     '关闭(卸载)表单(我)
     Unload Me
End Sub

我们的表单现在输入值“Cell selected!”在选定的单元格中。

为了避免错误,我们需要检查用户是否从两组选项中正确选择。

在此示例中,当表单尚未完成时,“确认”按钮(“Confirm”)将变灰(禁用)。这不是最简单的解决方案,但它是一个很好的例子,说明了为什么函数/过程在表单(UserForm)中间很有用。

编辑文本和 Enabled 属性以禁用该按钮。

结果如下:

在前面的代码中,我们使用了两个 For Each 循环来获取选项按钮(Option Buttons)的值。现在我们需要对十个选项的确认按钮(“Confirm”)和Click事件使用相同的值。

为此,我们不需要复制每个事件的循环,我们将通过函数调用它们。

从前面的代码开始并修改它,我们将实现以下结果:

 Private Function column_value()
 '返回所选按钮的文本值的函数 (column_value)
     For Each column_button In Frame_column.Controls
         If column_button.Value Then
             column_value = column_button.Caption
         End If
     Next
 End Function

 Private Function row_value()
 '返回所选按钮文本值的函数 (row_value)
     For Each row_button In Frame_row.Controls
         If row_button.Value Then
             row_value = row_button.Caption
         End If
     Next
 End Function

 Private Sub CommandButton1_Click() '单击(“确认您的选择”)时发生的操作
     Range(column_value & row_value) = "Cell chosen!"  '“细胞已选定!”
     'column_value和row_value是这些函数返回的值
     Unload Me
 End Sub

我们剩下要做的就是创建一个例程,检查是否正确选择了选项按钮(通过调用两个函数)并在需要时激活该按钮。

同样,验证是在单独的过程中完成的,以避免为每个单选按钮的每个事件复制代码 10 次:

Private Sub activate_button()
 '如果条件测试成功则激活按钮
     If column_value <> "" And row_value <> "" Then
     'column_value和row_value是这些函数返回的值
         CommandButton1.Enabled = True
         CommandButton1.Caption = "Confirm your selection"  '“确认你的选择”
     End If
End Sub

Private Sub OptionButton11_Click()
     activate_button '我们启动“activate_button”程序
End Sub
Private Sub OptionButton12_Click()
     activate_button
End Sub
Private Sub OptionButton13_Click()
     activate_button
End Sub
Private Sub OptionButton14_Click()
     activate_button
End Sub
Private Sub OptionButton15_Click()
     activate_button
End Sub
Private Sub OptionButton16_Click()
     activate_button
End Sub
Private Sub OptionButton17_Click()
     activate_button
End Sub
Private Sub OptionButton18_Click()
     activate_button
End Sub
Private Sub OptionButton19_Click()
     activate_button
End Sub
Private Sub OptionButton20_Click()
     activate_button
End Sub

您可以在此处看到已完成的 Excel 文件中的示例: userform3b.xls