工作表Sheet1中的数据表共有3列,行数不确定,现需要将数据加载到用户窗体的ListBox控件中,设置控件的相关属性属性如下所示。
控件属性 | 属性值 |
---|---|
ColumnCount | 3 |
ColumnHeads | True |
RowSource | Sheet1!A2:C15 |
窗体显示效果如下图所示,这里有一点需要提醒大家注意,由于启用了列标题,所以RowSource
属性指定的单元格范围从第二行开始,这个参数指定范围之上的一行数据将作为ListBox控件的标题行。
ListBox控件的这几个常规属性大家也经常用到,无需多讲。由于数据行数累加增加,控件加载的数据越来越多,每次用户都需要使用右侧滚动条拖动才能查看最新数据,因此希望ListBox只加载最后10行数据(不含标题行),这样用户可以非常方便的选择数据。
利用UserForm_Initialize
事件可以轻松实现窗体加载时,在设置ListBox控件的RowSource
的动态范围(Sheet1!A6:C15),但是由于控件标题行并支持单独指定单元格范围,所以最终窗体效果如下图所示。工作表中第5行数据成为了ListBox的标题行,这显然是无法接受的。
借助辅助单元格区域就可以轻松实现,辅助单元格可以位于工作表中的任意位置,通常选择工作表中右侧未使用的列,此示例使用AA列开始的单元格区域。
_注意:_此后的VBA代码定位工作表数据区域时,如果使用UsedRange
,那么需要针对辅助单元格区域做特殊处理。
Private Sub UserForm_Initialize()
Dim lastRow As Long
With ActiveSheet
.Range("AA:AC").Clear
.Range("AB:AC").NumberFormatLocal = "h:mm:ss AM/PM"
.Range("AA:AA").NumberFormatLocal = "[$-x-sysdate]dddd, mmmm dd, yyyy"
lastRow = .Cells(Rows.Count, 1).End(xlUp).Row
If lastRow > 11 Then
.Range("AA1").Resize(1, 3).Value = .Range("A1:C1").Value
.Range("AA2").Resize(10, 3).Value = .Range(.Cells(lastRow - 9, 1), .Cells(lastRow, 3)).Value
Else
.Range("AA1").Resize(lastRow, 3).Value = .Range("A1").Resize(lastRow, 3).Value
End If
lastRow = .Cells(Rows.Count, "AA").End(xlUp).Row
End With
With Me.ListBox1
.ColumnCount = 3
.ColumnWidths = "75;75;75"
.ColumnHeads = True
.RowSource = "AA2:AC" & lastRow
End With
End Sub
【代码解析】
第4行代码清空AA到AC列用于保存临时数据。
第5~6行代码设置单元格格式,确保数据可以正确显示。
第7行代码获取数据行数。
第8行代码判断数据行数(不包含标题行)是否大于10。
如果多于10行数据,第8行代码将数据表标题行复制到辅助单元格区域的第一行,第10行代码拷贝最后10行数据到辅助单元格区域。
如果不足10行数据,第13行代码拷贝将整个数据表(包含标题行)拷贝到辅助单元格区域。
第14行代码获取辅助单元格区域数据行数。
第17行代码设置数据列数。
第18行代码设置列宽度。
第19行代码设置启用列标题。
第20行代码代码下拉列表数据区域。
效果如下图所示。