Excel 系统集合数组列表

Excel 系统集合数组列表,excel,vba,excel-2010,Excel,Vba,Excel 2010,我正在尝试将数据添加到组合框中 我有一个用户表单,可以在两张纸上使用。它创建一个地址列表。根据激活的工作表,地址列表是从两张工作表中的一张创建的 如果活动工作表名称=SCHECK.name,则我使用System.Collection.ArrayList从工作表WIR创建唯一排序值列表,并将其添加到组合框中 如果活动工作表是S20FA,则我从CAL创建列表。我想使用系统集合来创建它,因为它比我创建数组的解决方案快得多,然后在数组上循环并添加到组合框 问题是,在将地址添加到数组中之前,如何使用Sys

我正在尝试将数据添加到组合框中

我有一个用户表单,可以在两张纸上使用。它创建一个地址列表。根据激活的工作表,地址列表是从两张工作表中的一张创建的

如果活动工作表名称=SCHECK.name,则我使用
System.Collection.ArrayList
从工作表WIR创建唯一排序值列表,并将其添加到组合框中

如果活动工作表是S20FA,则我从CAL创建列表。我想使用系统集合来创建它,因为它比我创建数组的解决方案快得多,然后在数组上循环并添加到组合框

问题是,在将地址添加到数组中之前,如何使用
System.Collection.ArrayList
执行所需的检查

除此之外,是否可以使用
System.Collection.ArrayList
创建多维数组,以便与多列组合框一起使用

Dim wb As Workbook: Set wb = ThisWorkbook 
Dim myArrayList As Object 
Dim i, lastRow As Long 
Dim address() As String 
Dim number_address As Integer 
Dim cell As Range 
Dim addressList, addressItem

Application.Calculation = xlCalculationManual 
Application.ScreenUpdating = False

Call wb.defineCols 
Call wb.defineSheets

If ActiveSheet.Name = wb.SCHECK.Name Then
    If wb.WIR.FilterMode = True Then wb.WIR.AutoFilter.ShowAllData
    lastRow = wb.WIR.cells(Rows.count, wb.COL_Address_code).End(xlUp).Row

    Set myArrayList = CreateObject("System.Collections.ArrayList")
    addressList = wb.WIR.Range(wb.WIR.cells(3, wb.COL_Address_code), wb.WIR.cells(lastRow, wb.COL_Address_code))

    With myArrayList
        For Each addressItem In addressList
            If Not .Contains(addressItem) Then .add addressItem
        Next
        .Sort
        If .count Then Me.address_combo.List = Application.Transpose(myArrayList.toarray())
    End With
    myArrayList.Clear
    Set myArrayList = Nothing
 ElseIf ActiveSheet.Name = wb.S20FA.Name Then
    If wb.CAL.FilterMode = True Then wb.CAL.AutoFilter.ShowAllData
    lastRow = wb.CAL.cells(Rows.count, "A").End(xlUp).Row
    Set cellRange = wb.CAL.Range("A8:A" & lastRow)
    DoEvents
    number_address = 0
    For Each cell In cellRange
        number_address = number_address + 1
        ReDim Preserve address(number_address - 1)
            If IsError(Application.match(cell, address, False)) Then

                '''' Test cells

                If wb.CAL.Range("G" & cell.Row) <> "" Then
                    If IsError(wb.CAL.Range("K" & cell.Row).value) = False Then
                        If wb.CAL.Range("K" & cell.Row).value <> "" And wb.CAL.Range("K" & cell.Row).value <> 0 Then
                            If (wb.CAL.Range("Q" & cell.Row).value <> "" And wb.CAL.Range("Q" & cell.Row).value <> 0) Or _
                               (wb.CAL.Range("W" & cell.Row).value <> "" And wb.CAL.Range("W" & cell.Row).value <> 0) Then
                                address(number_address - 1) = wb.CAL.Range("A" & cell.Row).value
                            Else
                                number_address = number_address - 1
                            End If
                        Else
                            number_address = number_address - 1
                        End If
                    End If
                Else
                    number_address = number_address - 1
                End If
            Else
                number_address = number_address - 1
            End If
    Next cell

    DoEvents
    For i = 0 To UBound(address)
        If address(i) <> "" Then
            address_combo.AddItem address(i)
        End If
    Next i 
 End If 
Application.ScreenUpdating = True 
Application.Calculation = xlCalculationAutomatic
Dim wb As工作簿:Set wb=thiswoolk
Dim myArrayList作为对象
昏暗的我,最后一排一样长
Dim address()作为字符串
Dim编号\u地址为整数
暗淡单元格作为范围
Dim addressList,addressItem
Application.Calculation=xlCalculationManual
Application.ScreenUpdating=False
调用wb.defineCols
调用wb.defineSheets
如果ActiveSheet.Name=wb.SCHECK.Name,则
如果wb.WIR.FilterMode=True,则wb.WIR.AutoFilter.ShowAllData
lastRow=wb.WIR.cells(Rows.count,wb.COL\u Address\u code)。End(xlUp)。Row
设置myArrayList=CreateObject(“System.Collections.ArrayList”)
addressList=wb.WIR.Range(wb.WIR.cells(3,wb.COL\U地址代码),wb.WIR.cells(lastRow,wb.COL\U地址代码))
与myArrayList
对于addressList中的每个addressItem
如果不是。包含(addressItem),则。添加addressItem
下一个
分类
如果.count,那么Me.address\u combo.List=Application.Transpose(myArrayList.toarray())
以
myArrayList,明白了
设置myArrayList=Nothing
ElseIf ActiveSheet.Name=wb.S20FA.Name然后
如果wb.CAL.FilterMode=True,则wb.CAL.AutoFilter.ShowAllData
lastRow=wb.CAL.cells(Rows.count,“A”).End(xlUp).Row
设置cellRange=wb.CAL.Range(“A8:A”和lastRow)
多芬特
数字\地址=0
对于cellRange中的每个单元格
编号地址=编号地址+1
ReDim保留地址(数字\地址-1)
如果IsError(Application.match(cell,address,False))那么
''测试单元
如果wb.CAL.Range(“G”和cell.Row)”,则
如果IsError(wb.CAL.Range(“K”和cell.Row.value)=False,则
如果wb.CAL.Range(“K”和cell.Row).value”和wb.CAL.Range(“K”和cell.Row).value)为0,则
如果(wb.CAL.Range(“Q”和cell.Row).value“”和wb.CAL.Range(“Q”和cell.Row).value 0)或_
(wb.CAL.Range(“W”和cell.Row).value“”和wb.CAL.Range(“W”和cell.Row).value 0)然后
地址(数字地址-1)=wb.CAL.Range(“A”和cell.Row).value
其他的
数字地址=数字地址-1
如果结束
其他的
数字地址=数字地址-1
如果结束
如果结束
其他的
数字地址=数字地址-1
如果结束
其他的
数字地址=数字地址-1
如果结束
下一个细胞
多芬特
对于i=0到UBound(地址)
如果地址(i)“,则
地址\组合。附加项地址(i)
如果结束
接下来我
如果结束
Application.ScreenUpdating=True
Application.Calculation=xlCalculationAutomatic

由于您希望避免重复,因此最好使用设计用于处理重复的数据结构<代码>脚本。字典是这类应用程序的优秀工具;它拒绝重复的密钥,因此在其
.keys
数组中有一个干净且唯一的列表

下面是使用字典数据结构对代码的重写。试试看它是否能提高速度。注意列表没有排序,但是如果速度提高了,但是我们仍然需要排序,我们可以在以后添加一个排序例程

Dim wb As Workbook: Set wb = ThisWorkbook
Dim dict As Object ' <-- changed the name to correspond to the dictionary
Dim i, lastRow As Long
Dim address() As String
Dim number_address As Integer
Dim cell As Range
Dim addressList, addressItem

Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False

Call wb.defineCols
Call wb.defineSheets

If ActiveSheet.Name = wb.SCHECK.Name Then
    If wb.WIR.FilterMode Then wb.WIR.AutoFilter.ShowAllData
    lastRow = wb.WIR.Cells(Rows.Count, wb.COL_Address_code).End(xlUp).Row

    Set dict = CreateObject("Scripting.Dictionary") ' <--
    addressList = wb.WIR.Range(wb.WIR.Cells(3, wb.COL_Address_code), wb.WIR.Cells(lastRow, wb.COL_Address_code))

    For Each addressItem In addressList
        If Not dict.Exists(addressItem.Value) Then dict.Add addressItem.Value, addressItem.Value
    Next
    If dict.Count > 0 Then Me.address_combo.List = Application.Transpose(dict.toarray())
ElseIf ActiveSheet.Name = wb.S20FA.Name Then
    If wb.CAL.FilterMode = True Then wb.CAL.AutoFilter.ShowAllData
    lastRow = wb.CAL.Cells(Rows.Count, "A").End(xlUp).Row
    Set cellRange = wb.CAL.Range("A8:A" & lastRow)
    DoEvents
    number_address = 0
    For Each cell In cellRange
        If Not dict.Exists(cell.Value) And _
            wb.CAL.Range("G" & cell.Row) <> "" And _
            Not IsError(wb.CAL.Range("K" & cell.Row).Value) And _
            wb.CAL.Range("K" & cell.Row).Value <> "" And wb.CAL.Range("K" & cell.Row).Value <> 0 And _
            ((wb.CAL.Range("Q" & cell.Row).Value <> "" And wb.CAL.Range("Q" & cell.Row).Value <> 0) Or _
             (wb.CAL.Range("W" & cell.Row).Value <> "" And wb.CAL.Range("W" & cell.Row).Value <> 0)) Then

             dict.Add cell.Value, cell.Value
        End If
    Next cell
    DoEvents
    address_combo.List = dict.Items
 End If
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
Dim wb As工作簿:Set wb=thiswoolk

Dim dict As Object’这是我在A.S.H建议的帮助下提出的解决方案

我保留了原来的
System.Collection.ArrayList
,现在在这两种情况下都使用它

我现在将整个范围复制到内存中并在内存中进行检查,而不是在工作表上循环并检查第二个需求

通过这种方法,我现在的完成速度是0.03秒,而不是几秒前

如果您发现任何错误或改进,请给我留言,我随时愿意尝试新的解决方案

Dim wb As Workbook: Set wb = ThisWorkbook
Dim myArrayList As Object: Set myArrayList = CreateObject("System.Collections.ArrayList")
Dim i, lastRow As Long
Dim address() As String
Dim number_address As Integer
Dim cell As Range
Dim addressList, addressItem

Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False

Call wb.defineCols
Call wb.defineSheets

If ActiveSheet.Name = wb.PCHECK.Name Then
    If wb.WIR.FilterMode = True Then wb.WIR.AutoFilter.ShowAllData
    lastRow = wb.WIR.cells(Rows.count, wb.COL_Address_code).End(xlUp).Row
    addressList = wb.WIR.Range(wb.WIR.cells(3, wb.COL_Address_code), wb.WIR.cells(lastRow, wb.COL_Address_code))
    With myArrayList
        For Each addressItem In addressList
            If Not .Contains(addressItem) Then .add addressItem
        Next
        .Sort
        If .count > 0 Then Me.ComboBox1.List = Application.Transpose(myArrayList.toarray())
    End With
ElseIf ActiveSheet.Name = wb.S20FA.Name Then
    If wb.CAL.FilterMode = True Then wb.CAL.AutoFilter.ShowAllData
    lastRow = wb.CAL.cells(Rows.count, "A").End(xlUp).Row
    addressList = wb.CAL.Range("A8:W" & lastRow).value
    With myArrayList
        For i = LBound(addressList) To UBound(addressList, 1)
            If Not .Contains(addressList(i, 1)) Then
                If addressList(i, 7) <> "" Then
                    If Not IsError(addressList(i, 11)) And addressList(i, 11) <> "" And addressList(i, 11) <> 0 Then
                        If (addressList(i, 18) <> "" And addressList(i, 18) <> 0) Then
                            .add addressList(i, 1)
                        End If
                    End If
                End If
            End If
        Next i
        .Sort
        If .count > 0 Then Me.ComboBox1.List = Application.Transpose(myArrayList.toarray())
    End With
End If

myArrayList.Clear
Set myArrayList = Nothing
Dim wb As工作簿:Set wb=thiswoolk
将myArrayList设置为对象:设置myArrayList=CreateObject(“System.Collections.ArrayList”)
昏暗的我,最后一排一样长
Dim address()作为字符串
Dim编号\u地址为整数
暗淡单元格作为范围
Dim addressList,addressItem
Application.Calculation=xlCalculationManual
Application.ScreenUpdating=False
调用wb.defineCols
调用wb.defineSheets
如果ActiveSheet.Name=wb.PCHECK.Name,则
如果wb.WIR.FilterMode=True,则wb.WIR.AutoFilter.ShowAllData
lastRow=wb.WIR.cells(Rows.count,wb.COL\u Address\u code)。End(xlUp)。Row
addressList=wb.WIR.Range(wb.WIR.cells(3,wb.COL\U地址代码),wb.WIR.cells(lastRow,wb.COL\U地址代码))
与myArrayList
对于addressList中的每个addressItem
如果不是。包含(addressItem),则。添加addressItem
下一个
分类
如果.count>0,则Me.ComboBox1.List=Application.Transpose(myArrayList.toarray())
以
ElseIf ActiveSheet.Name=