Excel 数组/集合未将值插入自定义userform上的cbo

Excel 数组/集合未将值插入自定义userform上的cbo,excel,vba,excel-2010,Excel,Vba,Excel 2010,我读过DougGlancy关于创建灵活的选择器表单的文章。利用他的代码和以前的一些工作代码,我试图动态读取字符串列表,将它们插入到集合中,并将集合作为值传递给自定义组合框中的选项。尽管如此,当我打开正确的电子表格时,组合框中不会显示。下面是我写的代码 道格·格兰西的文章: 这是模块中使用的代码: '====================================================================================================

我读过DougGlancy关于创建灵活的选择器表单的文章。利用他的代码和以前的一些工作代码,我试图动态读取字符串列表,将它们插入到集合中,并将集合作为值传递给自定义组合框中的选项。尽管如此,当我打开正确的电子表格时,组合框中不会显示。下面是我写的代码

道格·格兰西的文章:

这是模块中使用的代码:

'==========================================================================================================================
'Filename: modVulnerabilityReport
'Description: A module to contain the functions to analyze a list of vulnerabilities outputted from the Vulnerability
'             Remediation Asset Manager (VRAM) for a systems at a site. Utilizing built-in worksheet functions, this output
'             will be a calculation of the number of vulnerabilities per category which will be displayed in a message box.
'Concept taken from: Doug Glancy
'Originally written by: Doug Glancy, Zack Barresse
'Modified by: Troy Pilewski
'Date: 2015-03-31
'==========================================================================================================================
Option Explicit

Function GetChoiceFromChooserForm(strChoices() As String, strCaption As String) As String
'==========================================================================================================================
'Description: Function to populate the combo box on the userform and return the answer
'Originally written by: Doug Glancy
'Modified by: Troy Pilewski
'Date: 2015-03-31
'==========================================================================================================================

'Declare local variables
Dim ufChooser As frmChooser
Dim strChoicesToPass() As String

ReDim strChoicesToPass(LBound(strChoices) To UBound(strChoices))
strChoicesToPass() = strChoices()

'Initializes a new userform of frmChooser
Set ufChooser = New frmChooser

With ufChooser
    .Caption = strCaption
    .ChoiceList = strChoicesToPass
    .Show
    If .ClosedWithOk Then
        GetChoiceFromChooserForm = .ChoiceValue
    End If
    Unload ufChooser
End With

End Function

Sub ShowTotalVulnerabilties()
'==========================================================================================================================
'Description: Procedure to calculate the sum total of vulnerabilities per asset for each category based on owner selection
'Originally written by: Troy Pilewski
'Date: 2015-03-31
'==========================================================================================================================

'Declare local variables
Dim wsData As Worksheet
Dim rngData As Range, rngWhole As Range, colOwner As Range, ColCategory As Range, colSummary As Range
Dim strOwner As String
Dim lngOwner As Long, lngCategory As Long, lngSummary As Long
Dim lngLastRow As Long, lngOwnerRow As Long
Dim lngCountCategoryI As Long, lngCountCategoryII As Long, lngCountCategoryIII As Long, lngCountCategoryIV As Long
Dim vntOwners() As Variant, Owners As Collection, strOwnerNames() As String, i As Long

'Sets the Datasheet as the active worksheet
If ActiveSheet Is Nothing Then
    Exit Sub
End If

Set wsData = ActiveSheet

'Turn off application events to speed up code
Call TOGGLEEVENTS(False)

'Determine the last row with values
lngLastRow = wsData.Range("A:J").Find( _
    What:="*", _
    After:=wsData.Range("A1"), _
    LookAt:=xlByRows, _
    SearchOrder:=xlByRows, _
    SearchDirection:=xlPrevious _
).Row

'Set the working ranges
Set rngWhole = wsData.Range("A2:J" & lngLastRow)
Set rngData = wsData.Range("A3:J" & lngLastRow)

'Determines column numbers for criteria columns
lngOwner = wsData.Range("A:J").Find( _
    What:="Owner", _
    After:=wsData.Range("A1"), _
    LookAt:=xlPart, _
    SearchOrder:=xlByColumns, _
    SearchDirection:=xlNext _
).Column
lngCategory = wsData.Range("A:J").Find( _
    What:="CAT", _
    After:=wsData.Range("A1"), _
    LookAt:=xlPart, _
    SearchOrder:=xlByColumns, _
    SearchDirection:=xlNext _
).Column
lngSummary = wsData.Range("A:J").Find( _
    What:="Not Compliant", _
    After:=wsData.Range("A1"), _
    LookAt:=xlPart, _
    SearchOrder:=xlByColumns, _
    SearchDirection:=xlNext _
).Column

'Creates and adds each owner to a collection
vntOwners = wsData.Range("A3:A" & lngLastRow).value
Set Owners = New Collection

'Loop through the array of all Owner values (duplicates will be in this list)
For lngOwnerRow = LBound(vntOwners, 1) To UBound(vntOwners, 1)

    'Check the first unique value of a Owner
    If KEYISINCOLLECTION(Owners, CStr(vntOwners(lngOwnerRow, 1))) = False Then

        'Add the first unique Owner to the collection
        Owners.Add CStr(vntOwners(lngOwnerRow, 1)), CStr(vntOwners(lngOwnerRow, 1))

    End If
Next lngOwnerRow

'Converts collection to a string
With Owners
    ReDim strOwnerNames(.Count) As String
    For i = 1 To .Count
        strOwnerNames(i) = .Item(i)
    Next i
End With

'Assigns column number to variable
With rngWhole
    Set colOwner = .Columns(lngOwner)
    Set ColCategory = .Columns(lngCategory)
    Set colSummary = .Columns(lngSummary)

    'Prompts user to select an vulnerability owner
    strOwner = GetChoiceFromChooserForm(strOwnerNames, "Owner Selection")

    'Validates that an owner was selected
    If strOwner = vbNullString Then
        Exit Sub
    End If

    'Calculate sum of vulnerabilities for Owner and Category
    lngCountCategoryI = WorksheetFunction.SumIfs(colSummary, colOwner, strOwner, ColCategory, "I")
    lngCountCategoryII = WorksheetFunction.SumIfs(colSummary, colOwner, strOwner, ColCategory, "II")
    lngCountCategoryIII = WorksheetFunction.SumIfs(colSummary, colOwner, strOwner, ColCategory, "III")
    lngCountCategoryIV = WorksheetFunction.SumIfs(colSummary, colOwner, strOwner, ColCategory, "IV")

    'Displays message box with results
    MsgBox Title:="Vulnerability Totals", _
        Prompt:="The total number of " & strOwner & " vulnerabilities for each category are:" & vbCrLf & _
            "Category I  : " & lngCountCategoryI & vbCrLf & _
            "Category II : " & lngCountCategoryII & vbCrLf & _
            "Category III: " & lngCountCategoryIII & vbCrLf & _
            "Category IV : " & lngCountCategoryIV
End With
End Sub

Sub TOGGLEEVENTS(blnState As Boolean)
'==========================================================================================================================
'Description: Toggles the application events for a boolean state
'Originally written by: Zack Barresse
'Date: 2014-09-15
'==========================================================================================================================


    Application.DisplayAlerts = blnState
    Application.EnableEvents = blnState
    Application.ScreenUpdating = blnState
    If blnState Then Application.CutCopyMode = False
    If blnState Then Application.StatusBar = False
End Sub

Public Function KEYISINCOLLECTION(CollTemp As Collection, KeyToCheck As String) As Boolean
'==========================================================================================================================
'Description: Validates the selection is not already in the collection
'Originally written by: Zack Barresse
'Date: 2014-09-15
'==========================================================================================================================

    On Error Resume Next
    KEYISINCOLLECTION = CBool(Not IsEmpty(CollTemp(KeyToCheck)))
    On Error GoTo 0
End Function
这是userform中使用的代码:

'==========================================================================================================================
'Description: Properties and procedure to run the userform
'Originally written by: Doug Glancy
'Modified by: Troy Pilewski
'Date: 2015-03-31
'==========================================================================================================================
Option Explicit

'Declare modules level variables
Private mblnClosedWithOk As Boolean
Private mChoiceList() As String

Private Sub cmdOk_Click()
'Turns on the boolean bit if the user clicks OK button
mblnClosedWithOk = True

'Hides the userform
Me.Hide
End Sub

Public Property Get ClosedWithOk() As Boolean
'Sets the property with the boolean bit of the procedure cmdOk_Click()
    ClosedWithOk = mblnClosedWithOk
End Property

Private Sub cmdCancel_Click()
'Turns off the boolean bit if the user clicks the Cancel button
mblnClosedWithOk = False

'Hides the userform
Me.Hide
End Sub

Public Property Get ChoiceValue() As String
'Assigns the selected value in owner drop-down
ChoiceValue = Me.cboOwner.Value
End Property

Public Property Let ChoiceList(PassedList() As String)
'Set values to select from in the combo box
mChoiceList() = PassedList()
End Property

上面的代码需要UserForm_Activate事件,在该事件中填充组合框:

Private Sub UserForm_Activate()
With Me.cboOwner
    .List = mChoiceList()
    .ListIndex = 0
End With
End Sub