对于多行多列数据,基本使用Worksheet中的Range就可以处理了。但是在UserForm类型的应用中,也时常需要处理多行多列的数据。在UserForm中,显示和处理多列数据,通常可以有的选择有以下几种:DataGrid,ListView,ListBox。前面两类相当强大,但是也比较复杂,一般的简单应用中用不到。
DataGrid
DataGrid控件天生就是为了处理像Recordset这种数据而准备的,与它类似的数据控件(其它公司提供的数据控件)也还有其它几种,这里并不是重点,所以简单介绍一下。默认情况下,VBE中是看不到这个控件的,需要下载DATGDCHS.dll并放到C:\winnt\system32\下,然后运行命令“regsvr32 DATGDCHS.dll”注册。注册完成后,选择"Tools"菜单下的"Additional Controls..."菜单项,添加对应的控件到工具箱中就可以了。
DataGrid最重要的属性就是DataSource属性,就是设置表格的数据源。其它的也可以设置列的一些属性,这里就不详细介绍了。需要的同学请自备Google并自行搜索。
ListView
ListView也是处理这类型数据的一个选择,功能也比较强大,特别是可以设置图标,在很多时候还是很适合使用的。下面的伪代码介绍了常用的属性和方法:
' 清除listview1中的标题
ListView1.ColumnHeaders.Clear
' 清除listview1中的内容
ListView1.ListItems.Clear
With Sheets( 1 )
' 添加列标题
ListView1.ColumnHeaders.Add 1 , , .Cells( 1 , 1 ), ListView1.Width / 9
ListView1.ColumnHeaders.Add 2 , , .Cells( 1 , 2 ), ListView1.Width / 9
' 显示为报表视图
ListView1.View = lvwReport
' 选取整行
ListView1.FullRowSelect = True
' 复选框
ListView1.CheckBoxes = True
ListView1.BackColor = RGB ( 255 , 199 , 9 )
For i = 5 To .[A65536].End(xlUp).Row
' 为listview1控件里面的行添加内容
Set currentItem = ListView1.ListItems.Add()
currentItem.Text = .Cells(i, 1 ) ' 为行标赋值
currentItem.SubItems( 1 ) = .Cells(i, 2 )
currentItem.SubItems( 2 ) = .Cells(i, 3 )
currentItem.SubItems( 3 ) = .Cells(i, 4 )
' 为里面的第三列调整相应的字体大小及颜色
With currentItem.ListSubItems.Item( 2 )
If .Text < 2 Then
.ForeColor = RGB ( 255 , 0 , 0 )
Else
.Bold = True
.ForeColor = RGB ( 0 , 0 , 255 )
End If
End With
Next i
End With
默认情况下,ListView不会出现在工具箱中,需要在“Tools”菜单中,点击“Additional Controls...”菜单,打开对话框,勾选“Microsoft ListView Control,version 6.0”,然后在工具箱中就可以使用了。
经典的ListView双击列头排序的方法如下(使用了"^"与"v"去标示了排序的顺序,如果使用图片的话也是可以的):
SetSortMark columnHeader
With lstAllocatonList
If (columnHeader.Index - 1) = .SortKey Then
.SortOrder = (.SortOrder + 1) Mod 2
Else
.Sorted = False
.SortOrder = 0
.SortKey = columnHeader.Index - 1
.Sorted = True
End If
End With
End Sub
Private Sub SetSortMark(columnHeader As MSComctlLib.columnHeader)
Dim i As Integer
Dim suffix As String
suffix = IIf( Right(columnHeader.text, 2) = " v ", " ^ ", " v ")
With lstAllocatonList.ColumnHeaders
For i = 1 To .Count
.Item(i).text = Replace(.Item(i).text, " ^ ", "")
.Item(i).text = Replace(.Item(i).text, " v ", "")
Next
End With
columnHeader.text = columnHeader.text + suffix
End Sub
ListBox
虽然上面的两种选择很强大,但是设置也比较复杂,而且在很多时候,客户并不允许去下载相关的控件。而且在通常情况下,使用ListBox也可以达到相同的效果了。所以ListBox是最常用的方式,这里也重点介绍一下。使用ListBox常见的任务如下所示:
任务1:给ListBox绑定集合:
List - 代表所有行,可以直接赋给一个集合,也可以使用List(i,j)的形式给每个格赋值。
Column - 代表所有列,可以直接赋给一个集合,也可以使用Column (i,j)的形式给每个格赋值。
RowSource - 代表所有数据,可以直接赋给一个集合。
注意给List赋值,行列都会按正常排列,给Column赋值的时候,行列会颠倒过来,一般需要使用Application.Transpose方法配合。而RowSource需要一个字符串,通常可以使用Range的Address方法获得,当然直接给地址或者Range的Name也行。下面是常见的赋值方式,注意其中的格式:
ListBox1.RowSource = " =Sheet1!A1:B5 "
' 直接使用数组的形式
Dim arr( 1 To 4 , 1 To 2 ) As String
arr( 1 , 1 ) = Cells( 1 , 1 )
' 省略赋值的过程...
arr( 4 , 2 ) = Cells( 4 , 2 )
ListBox2.List = arr
ListBox3.Column = Application.WorksheetFunction.Transpose(arr)
' 使用单元格的形式
Dim source As Variant
' source = Range("A1:B4")
source = [A1:B4]
ListBox4.List = source
任务2:编辑ListBox中的元素
AddItem - 添加一个新元素,参数是一个String,如果是多列的话,这个方法只会添加到第一列中,一般需要配合List(i,j)方法填充其他列的值。
RemoveItem - 移除一个元素,参数是一个Index值(从0开始)。
Clear - 清空ListBox。
注意使用List(i,j),Column(j,i)的形式也可以获得或设置给每一个格的值,注意行列的Index都是从0开始的。例如下面是对一个2列的列表操作:
ListBox1.AddItem TextBox1.Text
ListBox1.List(ListBox1.ListCount - 1 , 1 ) = TextBox2.Text
' 删除选中行
If ListBox1.ListIndex <> -1 Then
ListBox1.RemoveItem ListBox1.ListIndex
End If
ListBox1.Clear
任务3:获取ListBox中行列的总数
ListCount - 行总数,遍历的时候很有用。
ColumnCount - 获取或设置列的数目。
需要使用多列的时候,一般需要先设置ColumnCount为期望的数目。
任务4:获取ListBox中当前选中的行列
ListIndex - 当前选中的行的Index值。如果是可以多选的话,这个值有可能不太可靠,一般采用Selected遍历整个集合来确定选中的行。
Value - 当前选中的行的值,如果是多列的话,只返回第一列的值。
Selected - 判断某行是否被选中。
任务5:设置ListBox的表头
这个问题,常见的只有一种解法,那就是使用RowSource绑定集合。
这个时候A2上面一行的内容会作为ListBox的表头使用。
基本使用上面这些属性就可以达到显示和处理多行多列数据的目的了。 其它ListBox的属性可以参看相关资料。