Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/29.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Excel 如何使用单个组合框元素引用不同工作表中的单元格?_Excel_Vba_Combobox - Fatal编程技术网

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