VBA:传递一个参数表示要添加到combobox的列数

VBA: passing a parameter to represent the number of columns to be added to combobox

我正在使用 MS Access 2013/VBA。初始化表单上所有组合框的函数。该函数在窗体的Load事件中被调用。

我正在为表单上的每个组合框添加一个初始化函数,这是非常多余的,更不用说表单上有超过 35 个组合框以及表单还有多个选项卡.

我的理想是只有一个初始化函数,并且仍然从加载事件调用它,也许多次,但传递必要的参数来处理每个单独的组合框。

我现在拥有的(每次调用都是调用一个功能基本相同的函数):

Private Sub Form_Load()

    Call InitializePriceCategory
    Call InitializePublisher
    Call InitializeAutoSearch
    Call InitializeConsultingFee
    Call InitializePermissionCode    

    On Error GoTo errhandler

eofit:

    Exit Sub

errhandler:

    z = ErrorFunction(Err, Err.Description, Erl, "Form_Load")

    Err = 0

    Select Case z
        Case 0: Resume Next
        Case 1: GoTo eofit
    End Select
End Sub

每个函数的唯一变化是执行的 select 查询、组合框以及每个特定组合框需要显示的列数。

InitializePriceCategory 函数示例:

Public Function InitializePriceCategory()

    Dim ADOCon As ADODB.Connection
    Dim ADORS As ADODB.Recordset
    Dim avarRecords As Variant
    Dim avarTransposedArray As Variant
    Dim avarOriginalArray As Variant
    Dim intRecord As Integer
    Dim strSQL As String

    On Error GoTo errhandler

    strSQL = "SELECT DISTINCT" & _
             "  [Category]" & _
             ", [ProductDescription]" & _
             ", [BasePrice]" & _
             ", [AdditionalPrintPrice]" & _
             ", [MinimumPurchaseAmount]" & _
             ", [isChoral]" & _
             ", [isScoringBasedMinAmount]" & _
             ", [isTierBased] " & _
             "FROM [dbo].[z_PriceCategories] " & _
             "ORDER BY [Category]"

    Set ADOCon = New ADODB.Connection
    With ADOCon
        .ConnectionString = GetConnectionString("Conn")
        .Open
    End With

    Set ADORS = New ADODB.Recordset
    With ADORS
        .ActiveConnection = ADOCon
        .Open strSQL, , adOpenStatic, adLockReadOnly
        .MoveLast
        .MoveFirst
        avarRecords = .GetRows(.RecordCount)
    End With

    For intRecord = 0 To UBound(avarRecords, 2)

        ' Check for commas within the string on column 1 (description),
        ' otherwise the value gets truncated
        If InStr(avarRecords(1, intRecord), ",") > 0 Then
            avarRecords(1, intRecord) = """" & avarRecords(1, intRecord) & """"
        End If

        PriceCategory.AddItem (avarRecords(0, intRecord) & ";" & _
                               avarRecords(1, intRecord) & ";" & _
                               avarRecords(2, intRecord) & ";" & _
                               avarRecords(3, intRecord) & ";" & _
                               avarRecords(4, intRecord) & ";" & _
                               avarRecords(5, intRecord) & ";" & _
                               avarRecords(6, intRecord) & ";" & _
                               avarRecords(7, intRecord))

    Next intRecord
eofit:

    On Error Resume Next

    ADOCon.Close: Set ADOCon = Nothing
    ADORS.Close: Set ADORS = Nothing

    Exit Function

errhandler:

    z = ErrorFunction(Err, Err.Description, Erl, "InitializePriceCategory", , True)

    Err = 0

    Select Case z
        Case 0: Resume Next
        Case 1: GoTo eofit
    End Select

End Function

在每个初始化函数中,为了让我只能有一个初始化函数,最大的不同和对我来说最具挑战性的是列数。

我的目标是在表单加载代码上做一些简单的事情:

Private Sub Form_Load()

    On Error GoTo errhandler

    Call InitializeCombo(Me.PriceCategory, "SELECT col1, col2, col3, col4, col5, col6, col7, col8 FROM PriceCategory ", 8, ",")
    Call InitializeCombo(Me.PublisherName, "SELECT col1, col2 FROM Publishers ", 2, """")

eofit:

    Exit Sub

errhandler:

    z = ErrorFunction(Err, Err.Description, Erl, "Form_Load")

    Err = 0

    Select Case z
        Case 0: Resume Next
        Case 1: GoTo eofit
    End Select
End Sub

然后InitializeCombo函数代码为(不完整思路):

Public Function InitializeCombo(pCombo As ComboBox, pQuery As String, pCols As Integer, Optional pSpecialCharacter As String)

    Dim ADOCon As ADODB.Connection
    Dim ADORS As ADODB.Recordset
    Dim avarRecords As Variant
    Dim avarTransposedArray As Variant
    Dim avarOriginalArray As Variant
    Dim intRecord As Integer    

    On Error GoTo errhandler

    Set ADOCon = New ADODB.Connection
    With ADOCon
        .ConnectionString = GetConnectionString("Conn")
        .Open
    End With   

    Set ADORS = New ADODB.Recordset
    With ADORS
        .ActiveConnection = ADOCon
        .Open pQuery, , adOpenStatic, adLockReadOnly
        .MoveLast
        .MoveFirst
        avarRecords = .GetRows(.RecordCount)
    End With

    ' ON THIS PART I AM NOT SURE HOW TO STILL BE ABLE TO DO THE SPECIAL CHARACTER CHECK 
    If InStr(avarRecords(1, intRecord), """") > 0 Then
        avarRecords(1, intRecord) = "'" & avarRecords(1, intRecord) & "'"
    End If

    For intRecord = 0 To UBound(avarRecords, 2)

        ' ON THIS PART, I DO NOT KNOW HOW TO INSTRUCT/ LOOP TO USE THE NUMBER OF COLUMNS PARAMETER 
        ' AND ADD THE NUMBER OF COLUMNS NEEDED; WHETHER ONE COMBO-BOX NEEDS 8 AND THE NEXT ONE ONLY NEEDS 2.
        pCombo.AddItem (avarRecords(0, intRecord) & ";" & _
                        avarRecords(1, intRecord) & ";")

    Next intRecord

eofit:

    On Error Resume Next

    ADOCon.Close: Set ADOCon = Nothing
    ADORS.Close: Set ADORS = Nothing

    Exit Function

errhandler:

    z = ErrorFunction(Err, Err.Description, Erl, "InitializeCombo", , True)
    Err = 0
    Select Case z
        Case 0: Resume Next
        Case 1: GoTo eofit
    End Select

End Function

我在想我需要的是在第一个遍历记录数组的 for 循环中添加另一个循环,但我不确定如何添加这部分。

我希望我能在这个问题上得到一些帮助,因为我认为我已经接近解决问题了,我只是 运行 遇到了一个我无法弄清楚的障碍。

在变量中构造字符串,然后将其传递给 AddItem() 函数。从空字符串 "" 开始,然后在循环中添加到先前的值。使用计数器作为 avarRecords() 函数的索引:

Dim c As Integer
Dim s As String

For intRecord = 0 To UBound(avarRecords, 2)
    s = ""
    For c = 0 To pCols
        s = s & avarRecords(c, intRecord) & ";"
    Next c

    pCombo.AddItem (s)
Next intRecord