Excel VBA:向表单控件组合框添加数组

时间:2017-01-19 17:52:15

标签: arrays excel vba combobox

我想要组合几个文件并用一个结果文件进行分析。其中一个文件包含具有不同名称的样本,这些样本重复未知的次数。我想从此文件中取出所有未知名称,并将它们添加到下拉框(Form Control Combobox)。

为简化起见,我将以下字符串添加到第一列新Excel文件中的工作表:

  

字符串1

     

字符串1

     

String 2

     

字符串3

     

字符串3

     

字符串3

     

String 4

     

String 4

提取唯一字符串,我写了下面的代码:

Sub MakeArrayInDropDown()
    ' Declare variables
    Dim myArray() As Variant    ' Array with undefined size
    Dim i As Integer            ' Counter for-loop
    Dim i_UnStr As Integer      ' Counter of unique strings
    Dim i_lastStr As Integer    ' Length of strings in column A
    Dim wb As Workbook          ' Short workbookname
    Dim ws As Worksheet         ' Short worksheet name
    Dim TC As Range             ' Target Cell (TC)

    ' Set workbook and worksheet
    Set wb = ThisWorkbook
    Set ws = ActiveSheet

    ' Set cell where all unique strings should go to
    Set TC = ws.Cells(1, 3)

    ' Determine amount of strings in column A
    i_lastStr = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row

    ' Go through all strings that are in column A
    For i = 1 To i_lastStr

        ' Save the first string in the first position of the array
        If i_UnStr = 0 Then
            i_UnStr = 1
            ReDim myArray(i_UnStr)                      ' Resize array to 1
            myArray(i_UnStr) = ws.Cells(i, 1)           ' Add first string to array

        ' Add if next string is different from the string previously added
        ElseIf Not StrComp(myArray(i_UnStr), ws.Cells(i, 1)) = 0 Then
            ' Increase unique strings counter
            i_UnStr = i_UnStr + 1
            ' Resize array to no unique strings, preserving precious values
            ReDim Preserve myArray(i_UnStr)
            ' Add next unique string to array as well
            myArray(i_UnStr) = ws.Cells(i, 1)
        End If
    Next i

    ' Add Form Control dropdown to target cell
    ws.DropDowns.Add(TC.Left, TC.Top, TC.Width, TC.Height).Name = "dropdown_row" & TC.Row
    wb.Worksheets("Sheet1").Shapes("dropdown_row" & TC.Row).ControlFormat.List = myArray
End Sub

不幸的是,此代码会导致以下错误:

  

运行时错误1004:无法设置Dropdown类的List属性

我不明白我的数组有什么问题,因为如果我将最后一行改为

wb.Worksheets("Sheet1").Shapes("dropdown_row" & TC.Row).ControlFormat.List = _
    Array(myArray(1), myArray(2), myArray(3), myArray(4))

一切都很完美。好像我的阵列不被接受......

另外,最初我写了这样的最后一行

ws.Shapes("dropdown_row" & TC.Row).ControlFormat.List = myArray

但那给了我:

  

运行时错误424:需要对象

有人能解释一下为什么这两件事都错了吗?非常感谢!

2 个答案:

答案 0 :(得分:1)

我已经测试了您的代码和我的观察结果如下:

DropDown形状不喜欢数组索引Empty的{​​{1}}值。您似乎无法在传递给0方法的数组中使用混合类型,因为即使我将.List值更改为整数,它也会失败并返回相同的错误。

关于为什么这个陈述有效:

Empty

以上是有效的,因为你传递的数组可以避免上面提到的陷阱,因为你明确传递wb.Worksheets("Sheet1").Shapes("dropdown_row" & TC.Row).ControlFormat.List = _ Array(myArray(1), myArray(2), myArray(3), myArray(4)) 值。

注意:严格来说,在Empty时,您无需ReDim数组,数组通常为0,因此您可以使用它办法。

或者,您可以在第一个数组项中强制使用空字符串,这应该可以工作:

i_UnStr = 0

因此,解决方案是避免混合数据类型(也可能是数组中不必要的空元素),或者如果需要“空白”,则需要将其指定为空字符串myArray(0) = vbNullString ws.Shapes("dropdown_row" & TC.Row).ControlFormat.List = myArray 或文字vbNullString

在优化方面,我完全避免使用数组,特别是如果数据很大,因为""通常是一个相当昂贵的语句。

ReDim Preserve

答案 1 :(得分:0)

请尝试以下操作:

ws.Shapes("dropdown_row" & TC.Row).OLEFormat.Object.List = myArray