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
我正在使用 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