Excel 如何使用单个组合框元素引用不同工作表中的单元格?
假设我有两张表:Excel 如何使用单个组合框元素引用不同工作表中的单元格?,excel,vba,combobox,Excel,Vba,Combobox,假设我有两张表:公司和个人。我将公司和个人的名称放入一个组合框中,这样组合框中的项目如下所示: *CompanyName1 *CompanyName2 *CompanyName3 ... *CompanyNameN *PersonName1 *PersonName2 *PersonName3 ... *PersonNameN 我希望组合框在选择它时引用相应的单元格,但是如果条目来自两个不同的单元格,我该如何做呢?我只是这样看: 用公司的项目填充组合框 创建一个变量以保持人员的起始索引 dim
公司
和个人
。我将公司和个人的名称放入一个组合框中,这样组合框中的项目如下所示:
*CompanyName1
*CompanyName2
*CompanyName3
...
*CompanyNameN
*PersonName1
*PersonName2
*PersonName3
...
*PersonNameN
我希望组合框在选择它时引用相应的单元格,但是如果条目来自两个不同的单元格,我该如何做呢?我只是这样看:
公司的项目填充组合框
人员的起始索引
dim PersonsIndexStart as Integer
PersonsIndexStart = ComboBox.ListCount + 1
Persons
dim PersonsIndexStart as Integer
PersonsIndexStart = ComboBox.ListCount + 1
dim TrueIndex as integer
If ComboBox.ListIndex >= PersonsIndexStart Then
TrueIndex = ComobBox.ListIndex - PersonsIndexStart
Else TrueIndex = ComboBox.ListIndex
End If
这个方法看起来很笨拙,还有别的方法吗?例如,我可以向组合框项目附加一些名称以外的额外数据吗?如果您的第二个数据位于范围
A20:A50
中,则可以使用
Range("A20").Offset(ComboBox.ListIndex,0)
直接进入正确的牢房。因此,您只需要知道第二个列表从何处开始。如果第二个数据位于范围
A20:A50
内,则可以使用
Range("A20").Offset(ComboBox.ListIndex,0)
直接进入正确的牢房。因此,您只需要知道第二个列表从何处开始。我可以在组合框中附加一些额外的数据吗? (示例代码采用UserForm) 当然,可以用二维数据块填充组合框;多列由其
.ColumnCount
和.ColumnWidths
属性定义。您甚至可以通过定义零宽度来隐藏列-c.f.UserForm\u Layout
。此外,我还演示了一种通过所谓的数组方法将数据分配给ComboBox的.List
属性的快速方法。为了满足您的额外信息需求,第2列和第3列(均以零宽度隐藏)预先填充了对1号或2号工作表的引用及其在引用工作表中的“真实”行索引
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
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
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
)显示参考图纸编号以及隐藏组合框列中预先填充的行索引:
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
Private子组合框1_Click()
'用途:显示与图纸相关的计数器
'注意:对.List的索引引用是从零开始的(第一列=0,第二列=1,…)
和我一起
如果.ListIndex<0,则退出Sub
Me.Label1=“Sheet”和.List(.ListIndex,1)和_
“项目”和列表(.ListIndex,2)通过例如Label1的可选测试显示
以
端接头
顺便说一句,你不会避免一些计算无论如何;在您的情况下,我甚至建议坚持您选择的方法,但通过用户定义的函数获取索引-不必认为这很笨拙:-)。我可以在组合框中附加一些额外的数据吗? (示例代码采用UserForm) 当然,可以用二维数据块填充组合框;多列由其
.ColumnCount
和.ColumnWidths
属性定义。您甚至可以通过定义零宽度来隐藏列-c.f.UserForm\u Layout
。此外,我还演示了一种通过所谓的数组方法将数据分配给ComboBox的.List
属性的快速方法。为了满足您的额外信息需求,第2列和第3列(均以零宽度隐藏)预先填充了对1号或2号工作表的引用及其在引用工作表中的“真实”行索引
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
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
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
)显示参考图纸编号以及隐藏组合框列中预先填充的行索引:
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
Private子组合框1_Click()
'用途:显示与图纸相关的计数器
'注意:对.List的索引引用是从零开始的(第一列=0,第二列=1,…)
和我一起
如果.ListIndex<0,则退出Sub
Me.Label1=“Sheet”和.List(.ListIndex,1)和_
“项目”和列表(.ListIndex,2)通过例如Label1的可选测试显示
以
端接头
顺便说一句,你不会避免一些计算无论如何;在你的情况下,我甚至建议坚持你选择的方法,但要通过用户定义的函数获取索引-不必认为这很笨拙:-)。你能使用工作表函数吗,说
match
或countif
,看看每张纸上是否都有选择?@Nathan_Sav返回组合框条目的值并在范围内搜索它?这可能行得通。也许可以使用带有种类(公司/个人)和索引值的隐藏列?使用两列组合并在第二列中加载单元格地址怎么样。使其可见或不可见。。。通过这种方式,您可以访问单元格而不需要组合索引。您是否可以使用工作表函数,例如match
或countif
,以便查看每个工作表上是否存在所选内容?@Nathan_Sav返回组合框条目的值并在范围内搜索它?这可能行得通。也许可以使用带有种类(公司/个人)和索引值的隐藏列?使用两列组合并在第二列中加载单元格地址怎么样。使其可见或不可见。。。通过这种方式,您可以访问单元格而不需要组合索引。问题是,如果第一张工作表中的条目具有索引,例如0-4,而第二张工作表中的条目索引为5-9,那么如果我选择索引为8
的条目,它将在第二张工作表中返回我的偏移量4
时返回我的偏移量8
。问题是,如果第一张工作表中的条目有索引,比如0-4,第二张工作表中的条目索引是5-9,那么如果我选择索引为8
的条目,它将在应该返回时返回偏移量8