如何使用单个组合框元素引用不同工作表中的单元格?
How do I reference cells from different sheets with single combo box element?
假设我有 2 张:companies
和 persons
。我将公司和个人的姓名放入一个组合框中,因此组合框中的项目如下所示:
*CompanyName1
*CompanyName2
*CompanyName3
...
*CompanyNameN
*PersonName1
*PersonName2
*PersonName3
...
*PersonNameN
我希望 ComboBox 在选择时引用相应的单元格,但是如果条目来自 2 个不同的单元格,我该怎么办?我只这样看:
用 Companies
中的项目填充组合框
创建一个变量来保持Persons
的起始索引
dim PersonsIndexStart as Integer
PersonsIndexStart = ComboBox.ListCount + 1
用 Persons
中的项目填充组合框
选择项目后,计算项目的 "true index"。
dim TrueIndex as integer
If ComboBox.ListIndex >= PersonsIndexStart Then
TrueIndex = ComobBox.ListIndex - PersonsIndexStart
Else TrueIndex = ComboBox.ListIndex
End If
这个方法看起来很笨拙,还有别的方法吗?例如,我可以将一些额外的数据附加到 ComboBox 项目而不是它的名称吗?
如果您的第二个数据在 A20:A50
范围内,那么您可以使用
Range("A20").Offset(ComboBox.ListIndex,0)
直接进入正确的单元格。所以你只需要知道你的第二个列表从哪里开始。
我可以将一些额外的数据附加到 ComboBox 吗?
(示例代码假定用户窗体)
当然可以用二维数据块填充ComboBox;多列由其 .ColumnCount
和 .ColumnWidths
属性定义。您甚至可以通过定义零宽度来隐藏列 - c.f。 UserForm_Layout
。此外,我演示了一种通过所谓的数组方法将数据分配给 ComboBox 的 .List
属性 的快速方法。为了满足您的额外信息需求,第 2 列和第 3 列(均隐藏为零宽度)预填充了对 sheet no 1 or 2 的引用及其在引用中的 "true" 行索引工作sheet.
Private Sub UserForm_Initialize()
' Purpose: populate ComboBox with data from 2 sheets
doFillCombo Me.ComboBox1, Sheet1, Sheet2 ' sheets reference via their CodeName here !
End Sub
Private Sub UserForm_Layout()
' Purpose: layout combobox including hidden columns
With Me.ComboBox1
.ColumnCount = 3 ' << provide for 3 columns assigned via .List
.ColumnWidths = .Width & ";0;0" ' << hide last columns by ZERO widths
End With
End Sub
子调用doFillCombo()
(从UserForm_Initialize
调用)
Private Sub doFillCombo(cbo As MSForms.ComboBox, _
ws1 As Worksheet, ws2 As Worksheet, _
Optional ByVal ColWs1 = "A", Optional ByVal ColWs2 = "A")
' assign data from both sheets to temporary arrays
Dim tmp1, tmp2
tmp1 = getData(ws1, ColWs1)
tmp2 = getData(ws2, ColWs2)
' provide for a container array
ReDim arr(1 To UBound(tmp1) + UBound(tmp2), 1 To 3)
' read 1st data block to container
Dim i&
For i = 1 To UBound(tmp1)
arr(i, 1) = tmp1(i, 1)
arr(i, 2) = 1 ' refers to 1st worksheet
arr(i, 3) = i ' item count in the sheet's data column
Next i
' read 2nd data block to container
Dim StartRow&: StartRow = UBound(arr) - UBound(tmp2) + 1
For i = StartRow To UBound(arr)
arr(i, 1) = tmp2(i - UBound(tmp1), 1)
arr(i, 2) = 2 ' refers to 2nd worksheet
arr(i, 3) = i - UBound(tmp1) ' item count in the sheet's data column
Next i
' Assign data to combobox'es list property by one code line
cbo.List = arr
End Sub
*过程调用的辅助函数doFillCombo
Private Function getData(ws As Worksheet, ByVal col, Optional ByVal StartRow& = 2) As Variant()
' Purpose: assign column data to variant array
If IsNumeric(col) Then col = Split(ws.Cells(1, col).Address, "$")(1)
Dim LastRow&
LastRow = ws.Range(col & Rows.Count).End(xlUp).Row
getData = ws.Range(col & StartRow & ":" & col & LastRow).Value2
End Function
可能的测试显示以获取信息
假定标签控件(例如 Label1
)显示引用的 sheet 编号以及隐藏组合框列中预填充的行索引:
Private Sub ComboBox1_Click()
' Purpose: display sheet related counters
' Note: index reference to .List is zero-based (1st column = 0, 2nd = 1, ...)
With Me.ComboBox1
If .ListIndex < 0 Then Exit Sub
Me.Label1 = "Sheet" & .List(.ListIndex, 1) & " " & _
"Item " & .List(.ListIndex, 2) ' optional test display via e.g. Label1
End With
End Sub
顺便说一句,无论如何你都不会避免一些计算;在你的情况下,我什至建议坚持你选择的方法,但要通过用户定义的函数获取索引——不必认为这是笨拙的:-)。
假设我有 2 张:companies
和 persons
。我将公司和个人的姓名放入一个组合框中,因此组合框中的项目如下所示:
*CompanyName1
*CompanyName2
*CompanyName3
...
*CompanyNameN
*PersonName1
*PersonName2
*PersonName3
...
*PersonNameN
我希望 ComboBox 在选择时引用相应的单元格,但是如果条目来自 2 个不同的单元格,我该怎么办?我只这样看:
用
Companies
中的项目填充组合框
创建一个变量来保持
的起始索引Persons
dim PersonsIndexStart as Integer PersonsIndexStart = ComboBox.ListCount + 1
用
Persons
中的项目填充组合框
选择项目后,计算项目的 "true index"。
dim TrueIndex as integer If ComboBox.ListIndex >= PersonsIndexStart Then TrueIndex = ComobBox.ListIndex - PersonsIndexStart Else TrueIndex = ComboBox.ListIndex End If
这个方法看起来很笨拙,还有别的方法吗?例如,我可以将一些额外的数据附加到 ComboBox 项目而不是它的名称吗?
如果您的第二个数据在 A20:A50
范围内,那么您可以使用
Range("A20").Offset(ComboBox.ListIndex,0)
直接进入正确的单元格。所以你只需要知道你的第二个列表从哪里开始。
我可以将一些额外的数据附加到 ComboBox 吗? (示例代码假定用户窗体)
当然可以用二维数据块填充ComboBox;多列由其 .ColumnCount
和 .ColumnWidths
属性定义。您甚至可以通过定义零宽度来隐藏列 - c.f。 UserForm_Layout
。此外,我演示了一种通过所谓的数组方法将数据分配给 ComboBox 的 .List
属性 的快速方法。为了满足您的额外信息需求,第 2 列和第 3 列(均隐藏为零宽度)预填充了对 sheet no 1 or 2 的引用及其在引用中的 "true" 行索引工作sheet.
Private Sub UserForm_Initialize()
' Purpose: populate ComboBox with data from 2 sheets
doFillCombo Me.ComboBox1, Sheet1, Sheet2 ' sheets reference via their CodeName here !
End Sub
Private Sub UserForm_Layout()
' Purpose: layout combobox including hidden columns
With Me.ComboBox1
.ColumnCount = 3 ' << provide for 3 columns assigned via .List
.ColumnWidths = .Width & ";0;0" ' << hide last columns by ZERO widths
End With
End Sub
子调用doFillCombo()
(从UserForm_Initialize
调用)
Private Sub doFillCombo(cbo As MSForms.ComboBox, _
ws1 As Worksheet, ws2 As Worksheet, _
Optional ByVal ColWs1 = "A", Optional ByVal ColWs2 = "A")
' assign data from both sheets to temporary arrays
Dim tmp1, tmp2
tmp1 = getData(ws1, ColWs1)
tmp2 = getData(ws2, ColWs2)
' provide for a container array
ReDim arr(1 To UBound(tmp1) + UBound(tmp2), 1 To 3)
' read 1st data block to container
Dim i&
For i = 1 To UBound(tmp1)
arr(i, 1) = tmp1(i, 1)
arr(i, 2) = 1 ' refers to 1st worksheet
arr(i, 3) = i ' item count in the sheet's data column
Next i
' read 2nd data block to container
Dim StartRow&: StartRow = UBound(arr) - UBound(tmp2) + 1
For i = StartRow To UBound(arr)
arr(i, 1) = tmp2(i - UBound(tmp1), 1)
arr(i, 2) = 2 ' refers to 2nd worksheet
arr(i, 3) = i - UBound(tmp1) ' item count in the sheet's data column
Next i
' Assign data to combobox'es list property by one code line
cbo.List = arr
End Sub
*过程调用的辅助函数doFillCombo
Private Function getData(ws As Worksheet, ByVal col, Optional ByVal StartRow& = 2) As Variant()
' Purpose: assign column data to variant array
If IsNumeric(col) Then col = Split(ws.Cells(1, col).Address, "$")(1)
Dim LastRow&
LastRow = ws.Range(col & Rows.Count).End(xlUp).Row
getData = ws.Range(col & StartRow & ":" & col & LastRow).Value2
End Function
可能的测试显示以获取信息
假定标签控件(例如 Label1
)显示引用的 sheet 编号以及隐藏组合框列中预填充的行索引:
Private Sub ComboBox1_Click()
' Purpose: display sheet related counters
' Note: index reference to .List is zero-based (1st column = 0, 2nd = 1, ...)
With Me.ComboBox1
If .ListIndex < 0 Then Exit Sub
Me.Label1 = "Sheet" & .List(.ListIndex, 1) & " " & _
"Item " & .List(.ListIndex, 2) ' optional test display via e.g. Label1
End With
End Sub
顺便说一句,无论如何你都不会避免一些计算;在你的情况下,我什至建议坚持你选择的方法,但要通过用户定义的函数获取索引——不必认为这是笨拙的:-)。