VBA编程——窗体与控件(2)

本文首先介绍一些常用的控件,如复合框、列表、复选框、单选按钮、切换按钮、图像,最后会简要介绍其它控件的应用。

复合框

复合框(ComboBox)是文本框和下拉列表的组合,其样式可以使用Style属性设置,可选的属性值包括:

  • 选项0-fmStyleDropDownCombo,默认值,文本框与下拉列表组合,可以录入内容,也可以在列表中选择。
  • 选项2-fmStyleDropDownList,只能在列表选择。

新建frmTest1窗体,添加一个复合框,设置Style属性为2-fmStyleDropDownList;添加按钮CommandButton1和文本框TextBox1,结果如下图所示。

测试复合框控件

下面双击窗体,并选择Initialize事件,添加如下代码,其功能是在窗体载入时添加列表项。

VBA
Private Sub UserForm_Initialize()
    '载入组合框列表
    With ComboBox1
        .AddItem ("张三")
        .AddItem ("李四")
        .AddItem ("王二")
    End With
End Sub

代码中,使用了ComboBox控件的AddItem()方法添加列表项。接下来添加CommandButton1按钮的Click事件代码如下。

VBA
Private Sub CommandButton1_Click()
    TextBox1.Text = ComboBox1.Text
End Sub

运行窗体,点击CommandButton1按钮,复合框ComboBox1中选中的内容会显示在文本框TextBox1中,如下图的所示。

读取复合框文本

下面将ComboBox1复合框的Style属性修改为默认的0-fmStyleDropDownCombo,然后修改CommandButton1按钮的Click事件代码如下。

VBA
'判断ComboBox列表项是否存在
Public Function cboItemExists(txt, cbo As ComboBox) As Boolean
    For i = 0 To cbo.ListCount - 1
        If txt = cbo.List(i) Then
            cboItemExists = True
            Exit Function
        End If
    Next
    cboItemExists = False
End Function

Private Sub CommandButton1_Click()
    txt = ComboBox1.Text
    If txt <> "" And cboItemExists(txt, ComboBox1) = False Then
        ComboBox1.AddItem (txt)
    End If
    '
    TextBox1.Text = ComboBox1.Text
End Sub

代码中,首先定义了cboItemExists()函数,用于判断ComboBox列表中是否存在指定的列表项;接下来在CommandButton1按钮的Click事件中,如果输入的文本不为空,并且不在列表项中,则添加到列表,最后,在TextBox1文本框中显示组合框中选中或输入的内容。

也许大家已经注意到了,cboItemExists()函数定义为公共的(Public),测试没有问题后可以移动到mComm模块中,以便在其它窗体中使用。

列表

列表(ListBox)可以选择一个项目也可以选择多个项目,使用MultiSelect属性设置,默认值为0-fmMultiSelectSingle,只能选中一个列表项,设置为1-fmMultiSelectMulti可以选中多个项目。

在“工程”窗口添加新的用户窗体,并命名为frmTest2。窗体中添加两个列表,分别是ListBox1(左)和ListBox2(右),并将ListBox1控件的MultiSelect属性设置为1-fmMultiSelectMulti;另外创建按钮CommandButton1,如下图所示。

列表测试窗体

接下来,在窗体的Initialize事件中添加如下代码。

VBA
Private Sub UserForm_Initialize()
    For i = 0 To 9
        ListBox1.AddItem ("项目" & i)
    Next
End Sub

运行窗体后会在ListBox1添加10个列表项,如下图所示。

添加列表项

列表中选中多个项目时,可以使用Shift键选择连续的项目,也可以按住Ctrl键选择不连续的项目。接下来修改CommandButton1按钮的Click事件响应代码,功能是将ListBox1列表中选中的项目移动到ListBox2列表中,如下面的代码。

VBA
Private Sub CommandButton1_Click()
    For i = ListBox1.ListCount - 1 To 0 Step -1
        If ListBox1.Selected(i) Then
            ListBox2.AddItem (ListBox1.List(i))
            ListBox1.RemoveItem (i)
        End If
    Next
End Sub

代码中,按索引反向访问ListBox1列表的项目,并使用Selected()方法判断项目是否被选中;对于选中的项目,首先添加到ListBox2列表中,然后通过ListBox1列表的RemoveItem()方法删除此项。如下图就是选中了项目1、项目3、项目5并点击CommandButton1按钮后的结果。

选中并移动多个列表项

本例,在判断ListBox1列表选中的项目时是从下向上搜索,这是因为,如是从上向下搜索时,如果移动了选中的项目后,ListBox1列表项目会减少,继续搜索会访问不存在的索引,此时就会产生运行时错误。

如果要求移动到ListBox2列表的项目顺序保持它们在ListBox1列表时的顺序,可以将AddItem()方法的第2个参数设置为0,如下面的代码。

VBA
Private Sub CommandButton1_Click()
    For i = ListBox1.ListCount - 1 To 0 Step -1
        If ListBox1.Selected(i) Then
            ListBox2.AddItem ListBox1.List(i), 0
            ListBox1.RemoveItem (i)
        End If
    Next
End Sub

AddItem()方法的第2个参数指定添加项目的索引,本例,每次在ListBox2中添加的项目都放在第一位,可以保持项目在ListBox1列表中的顺序。如下图就是就移动项目1、项目3、项目5的效果。

移动多个列表项

复选框和切换按钮

复选框(CheckBox)和切换按钮(ToggleButton)都可以用于“开/关”状态的信息,它们都是使用Value属性表示状态,属性值可以是True或False。下面创建frmTest3窗体,并添加一个复选框和一个切换按钮,然后分别双击打开两个控件,并添加如下代码。

VBA
Private Sub CheckBox1_Click()
    ToggleButton1.value = CheckBox1.value
End Sub

Private Sub ToggleButton1_Click()
    CheckBox1.value = ToggleButton1.value
End Sub

代码的功能很简单,就是保持CheckBox1控件和ToggleButton1控件状态的同步。

此外,复选框和切换按钮都可以使用Caption属性设置显示的文本内容。而复选框还可以使用Alignment属性设置文本的位置,默认位于右侧。

单选按钮与框架

单选按钮(RadioButton)一般会多个一起使用,在同一容器(如窗体、框架等)中的单选按钮具有排他性,也就是说,在同一容器中的单选按钮一次只能选中一个,如果窗体中需要多组单选按钮,可以使用框架(Frame)组织,如下图所示。

框架与单选按钮

如图中所示,窗体中创建了两个框架Frame1和Frame2,每个框架中分别创建了三个单选按钮;每个框架中的单选按钮一次只能选中一个,并且,两个框架中的单选按钮互不干扰。

单选按钮可以通过Caption属性修改显示的文本,通过Value读取或设置选中状态,取值为True或False。

图像

图像(Image)控件中,可以使用Picture属性指定显示的图片,代码中可以使用LoadPicture()函数载入图像,其参数为图片文件的路径。

需要注意PictureSizeMode属性,用于指定图片显示的模式,属性值包括:

  • 值0-frmPictureSizeModeClip,默认值,大于控件尺寸的部分会被裁剪。
  • 值1-frmPictureSizeModeStretch,适配图像控件的尺寸,图片的宽高比可能失真。
  • 值2-frmPictureSizeModeZoom,在图像控件中按图片实际比例显示。

下图从左到右分别显示了三种显示效果。

图像显示模式

此外,可以使用图像控件的PictureAlignment属性设置图片的对齐方式,属性值如下表所示。

常量说明
0fmPictureAlignmentTopLeft左上角。
1fmPictureAlignmentTopRight右上角。
2fmPictureAlignmentCenter中心位置。图像控件的默认值。
3fmPictureAlignmentBottomLeft左下角。
4fmPictureAlignmentBottomRight右下角对齐。

其它控件

TagScrip控件可以设置多个标签(Tag),但容器中只有一组控件。比如,可以使用标签标识姓名,然后在容器中显示对应的人员信息。TagScrip控件可以使用Change事件响应点击标签的操作,并使用Value属性获取当前选中的标签,第一个标签索引为0,第二个标签索引为1,以此类推。

多页控件可以创建多个可切换的分页,每个分页有独立的一组控件,可以创建类似单元格格式设置窗口的界面。多页控件使用Change事件响应切换分页的操作,并使用Value属性获取当前选中的分页索引,第一个分页索引为0,第二个分页索引为1,以此类推。

滚动条(ScrollBar)控件的Min和Max属性可以设置滚动条的最小值和最大值范围;LargeChange属性指定在滑块与箭头按钮之间点击时增加或减少的数值,SmallChange属性可以设置点击箭头时增加或减少的数值。滚动条数值改变时,可以通过Change事件响应数据变化。此外,可以使用ControlSource属性设置滚动条数值的显示位置,如“Sheet4!$A$1”表示Sheet4工作中的A1单元格;Orientation属性可以设置滚动条的方向,默认为自动,会以高度和宽度比确定方向。

旋转按钮(SpinButton)只显示两个方向箭头,可以调整数据的大小,其属性与事件应用与滚动条基本一样,只是没有LargeChange属性。

RefEdit控件可以实现选择引用区域的功能,选择完成后可以使用Value属性读取选中的结果。