如何将列表框VBA表单数组关联与绝对地址相关联

时间:2018-02-06 15:26:09

标签: arrays excel vba excel-vba listbox

我正在使用范围填充表单中的列表框:

Private Sub UserForm_Initialize()
    Names = Range("C6:D" & Cells(Rows.Count, 3).End(xlUp).Row)
    For i = LBound(Names, 1) To UBound(Names, 1)
        ListBox1.AddItem Names(i, 1) & "-" & Names(i, 2)
    Next
    OptionButton3.Value = True
End Sub

我需要在我的代码中稍后调用每个项目的地址来采取行动;实际上,列表框中的每个项目都是选择用户将每个项目放在不同的列表框中作为表单的一部分来处理的行。

我试图像这样重新定义数组,但由于“需要恒定表达式”而没有成功:

Dim Names(6 To Cells(Rows.Count, 3).End(xlUp).Row, Range("C6:D" & Cells(Rows.Count, 3).End(xlUp).Row))

将地址与数组相关联或记录行列表的最佳方法是什么?

2 个答案:

答案 0 :(得分:0)

认为这就是你需要的:

<强>代码

Private Sub UserForm_Initialize()
' I. Get started
' a) variables
  Const iOffset As Long = 5                     ' row offset 5, i.e. start at row C6
  Dim names, a                                  ' variant datafield arrays
  Dim i      As Long, n As Long
  Dim ws     As Worksheet
' b) set worksheet object to memory
  Set ws = ThisWorkbook.Worksheets("MySheet")   ' << change to your sheet name
' c) listbox layout just for demo
  Me.ListBox1.ColumnCount = 2
  Me.ListBox1.ColumnWidths = "100;50"
' d) get last row of column C
  n = ws.Cells(Rows.Count, 3).End(xlUp).Row
' II. Get values
' a) create 1-based 2-dim variant datafield array
  names = ws.Range("C6:D" & n)
' b) concatenate names and define cell address
  For i = LBound(names, 1) To UBound(names, 1)
    names(i, 1) = names(i, 1) & "-" & names(i, 2)
    names(i, 2) = "C" & i + iOffset
  Next
' III. Fill Listbox
' get values of names array (1-liner, allows more than 10 columns :-)
  ListBox1.List = names
' IV.  Test to get 2nd array column into new array a
  a = Application.Index(names, 0, 2)
  For i = LBound(a) To UBound(a)
      Debug.Print a(i, 1)
  Next i
' V. clear memory
  Set ws = Nothing
End Sub

注意

我添加了一个常量,用于定义您的行Offset(Const iOffset As Long = 5)并使用数组分配加速代码到一个代码语句中的ListBox.List,而不是添加一个一个(BTW这将允许使用超过10个列表框列)。

正如@Rory所说,只需将行偏移量(例如+5)添加到当前活动的ListBox1.Listindex就可以获得行号。在这种情况下,您应该只注意标记列表行(即检查If ListBox1.ListIndex > -1 Then ...做某事。)

答案 1 :(得分:0)

我通过一个相当不优雅的黑客解决了这个问题,我并不特别喜欢使用列出行号的帮助列。有更好的方法可以做到这一点,我确定,但这就是我想出的:

Private Sub UserForm_Initialize()
    Names = Range("C6:E" & Cells(Rows.Count, 3).End(xlUp).Row)
    For i = LBound(Names, 1) To UBound(Names, 1)
        ListBox1.AddItem Names(i, 3) & ": " & Names(i, 1) & "-" & Names(i, 2)
    Next
    OptionButton3.Value = True
End Sub
然后,一旦用户选择了要执行的项目,我就会在我的代码中回忆起行号:

For i = 0 To (ListBox2.ListCount - 1)
    Dim itemName() As String
    itemName() = Split(ListBox2.list(i), ":")
    deviceRow = itemName(0)
    Debug.Print "Row number: " + deviceRow
    ... <SNIP>

它打印像这样:

Row number: 10
Row number: 7
Row number: 14
Row number: 9

必须有更好的方法来做到这一点,但那是我的解决方案。