我读过Doug Glancy关于创建灵活选择器表单的文章。利用他的代码和一些以前工作过的代码,我试图动态读取字符串列表,将它们插入到集合中,并将集合作为值从自定义组合框中选择。虽然,当我打开正确的电子表格时,不会出现在组合框中。以下是我写的代码。
Doug Glancy的文章:http://yoursumbuddy.com/a-flexible-vba-chooser-form/
这是模块中使用的代码:
'==========================================================================================================================
'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
答案 0 :(得分:1)
上面的代码需要UserForm_Activate事件,这是组合框的填充位置:
Private Sub UserForm_Activate()
With Me.cboOwner
.List = mChoiceList()
.ListIndex = 0
End With
End Sub