我要在comboboxes
中将相对大量的数据转换为三个excel userform
。基本上,我正在尝试为建筑产品创建采购订单系统。这涉及三个组合框,基本上分为“类别”,“子类别”和“产品”。
我发现一些使用.offset
函数的代码,但是我发现使用此函数的唯一方法非常耗时。我是VBA的新手。
有没有一种方法可以使用此代码或其他代码对我的数据进行有效排序,而不是每次手动更改偏移量?
Private Sub UserForm_Initialize()
Dim ws As Worksheet
Dim LR As Long
Dim Cell As Range
Dim List As New Collection
Dim Item As Variant
Set ws = ActiveSheet
With ws
LR = Sheet1.Cells(.Rows.Count, 1).End(xlUp).Row
For Each Cell In .Range("A2:A" & LR)
With Cell
On Error Resume Next
List.Add .Text, CStr(.Value)
On Error GoTo 0
End With
Next Cell
For Each Item In List
ComboBox1.AddItem Item
Next Item
End With
End Sub
Private Sub ComboBox1_Change()
Dim ws As Worksheet
Dim LR As Long
Dim Cell As Range
Dim List As New Collection
Dim Item As Variant
Set ws = ActiveSheet
With ws
LR = Sheet1.Cells(.Rows.Count, 1).End(xlUp).Row
ComboBox2.Clear
For Each Cell In .Range("A2:A" & LR)
With Cell
If .Text = ComboBox1.Value Then
On Error Resume Next
List.Add .Offset(0, 1).Text, CStr(.Offset(0, 1).Value)
On Error GoTo 0
End If
End With
Next Cell
For Each Item In List
ComboBox2.AddItem Item
Next Item
End With
End Sub
Private Sub ComboBox2_Change()
Dim ws As Worksheet
Dim LR As Long
Dim Cell As Range
Dim List As New Collection
Dim Item As Variant
Set ws = ActiveSheet
With ws
LR = Sheet1.Cells(.Rows.Count, 1).End(xlUp).Row
ComboBox3.Clear
For Each Cell In .Range("A2:A" & LR)
With Cell
If .Text = ComboBox1.Value Then
If .Offset(0, 1).Text = ComboBox2.Value Then
On Error Resume Next
List.Add .Offset(0, 2).Text, CStr(.Offset(0, 2).Value)
On Error GoTo 0
End If
End If
End With
Next Cell
For Each Item In List
ComboBox3.AddItem Item
Next Item
End With
End Sub
任何帮助都会很棒!
答案 0 :(得分:0)
使用数据字段数组加快速度
据我了解,您主要关心的是使用UserForm中的级联组合框和可读代码避免大量.Offset
来提高速度。
[i。]遍历一个范围总是很费时间,将您的完整数据集分配给 variant 数据字段数组({{1 }})。
[ii。]调用单个帮助程序 myData
使fillComboNo
事件过程更加易读。
[iii。]附加帮助程序_Change
对进行分类以使选择用户友好。
[iv。]此外,此示例代码还允许在其他SortColl
事件过程中使用相同的帮助过程fillComboNo
添加 更多组合框 。 -当然,在这种情况下,也有必要扩展分配给数据字段数组Combobox{No}_Change
的范围(即从3列myData
扩展到A:C
)。
示例代码
基本上,此解决方案与您的方法很接近,因为它也使用集合。它更快,因为它使用如上所述的数据字段数组; 它并不假装提供最有效的方式来显示级联组合框。
此示例假定列举了所有需要的组合框A:D
,ComboBox1
,ComboBox2
,...
ComboBox3
帮助程序Option Explicit ' declaration head of the UserForm code module
Dim myData ' Variant 2-dim datafield array ( 1-based !)
Private Sub UserForm_Initialize()
Dim LR As Long, ws As Worksheet
Set ws = Sheet1 ' if using CodeName in thisWorkbook
' ~~~~~~~~~~~~~~~~~~~~~~~~~
' [0] get entire DATA FIELD ' e.g. columns A:C (omitting title row)
' ~~~~~~~~~~~~~~~~~~~~~~~~~
LR = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row ' get last row
myData = ws.Range("A2:C" & LR).Value2 ' << assign range values to datafield array
' [1] fill first ComboBox
FillComboNo 1 ' <~~ helper procedure FillComboNo
End Sub
Private Sub ComboBox1_Change()
FillComboNo 2 ' <~~ helper procedure FillComboNo
End Sub
Private Sub ComboBox2_Change()
FillComboNo 3 ' <~~ helper procedure FillComboNo
End Sub
FillComboNo
排序例程Sub FillComboNo(ByVal no As Long)
' Purpose: fill cascading comboboxes
' Note: assumes controls named as "ComboBox" & No (ComboBox1, ComboBox2, ...)
Dim myList As New Collection
Dim item As Variant
Dim i As Long, ii As Long
Dim OK As Boolean, OKTemp As Boolean
' [0] clear ComboBox{No}
Me.Controls("ComboBox" & no).Clear
' [1] assign values in column No based on prior hierarchy levels
For i = LBound(myData) To UBound(myData)
' [1a] check upper hierarchy
OK = True
For ii = 1 To no - 1
OKTemp = myData(i, ii) = Me.Controls("ComboBox" & ii): OK = OK And OKTemp
Next ii
' [1b] add to collection
If OK Then
On Error Resume Next
myList.Add myData(i, no), myData(i, no)
If Err.Number <> 0 Then Err.Clear
End If
Next i
' [1c] sort collection via helper procedure
SortColl myList ' <~~ helper procedure SortColl
' [2] fill ComboBox{No}
For Each item In myList
Me.Controls("ComboBox" & no).AddItem item
Next item
End Sub
SortColl