一种解决方案是在 VBA 中自己调用传递查询,从而让您控制何时调用它。ListBox 支持可以填充列表的自定义编写函数。有关如何指定和编写函数的详细信息,请转到此处。
这可以让您更好地控制列表的数量,但我记得它不一定会删除重复调用。换句话说,你可能会发现它在初始化代码中多次调用了这个函数。通过跟踪调用,您也许可以确定模式并编写缓存值的代码,并且仅在必要时重新执行传递查询。
以下是一个旧应用程序的示例,其中包含我的一些评论,我希望它们对编写您自己的应用程序有用。我只需要使用过一次(在许多 ListBox 和 ComboBox 控件中),但效果很好。
Private Function ListBoxResult(Ctr As Control, ID As Variant, Row As Variant, Col As Variant, code As Variant) As Variant
'* listActionItems.[Row Source Type]
'* Called to populate listActionItems
'* PARAMETERS:
'* Ctr: A control variable that refers to the list box or combo box being filled.
'* Id: A unique value that identifies the control being filled. This is useful when you want to use the same user-defined function for more than one list box or combo box and must distinguish between them. (The example sets this variable to the value of the Timer function.)
'* Row: The row being filled (zero-based).
'* Col: The column being filled (zero-based).
'* Code: An intrinsic constant that specifies the kind of information being requested.
'* https://msdn.microsoft.com/en-us/library/office/ff845731.aspx
'* Microsoft Access calls your user-defined function once for acLBInitialize, acLBOpen, acLBGetRowCount, and acLBGetColumnCount. It initializes the user-defined function, opens the query, and determines the number of rows and columns.
'* Microsoft Access calls your user-defined function twice for acLBGetColumnWidth — once to determine the total width of the list box or combo box and a second time to set the column width.
'* The number of times your user-defined function is called for acLBGetValue and acLBGetFormat to get list entries and to format strings varies depending on the number of entries, the user's scrolling, and other factors.
'* Microsoft Access calls the user-defined function for acLBEnd when the form is closed or each time the list box or combo box is queried.
'* Whenever a particular value (such as the number of columns) is required, returning Null or any invalid value causes Microsoft Access to stop calling the user-defined function with that code.
Static days As Integer
Static dt As Date
Static result As Variant
Select Case code
Case acLBInitialize '0
'* Return Nonzero if the function can fill the list; False (0) or Null otherwise.
result = True
Case acLBOpen '1
'* Return Nonzero ID value if the function can fill the list; False or Null otherwise.
result = True
Case acLBGetRowCount '3
If rsTemplateActions Is Nothing Then
result = 0
Else
On Error Resume Next
result = rsTemplateActions.RecordCount
If Err.number <> 0 Then
result = 0
End If
End If
Case acLBGetColumnCount '4
'* Columns: Action Type, Scheduled Date, Description, Priority
result = 5
Case acLBGetColumnWidth '5
'* 1440 is twips per inch; -1 is default
Select Case Col
Case 0: result = 1.5 * 1440
Case 1: result = 0.8 * 1440
Case 2: result = 1# * 1440
Case 3: result = 1.8 * 1440
Case 4: result = 0.6 * 1440
Case Else
result = -1
End Select
Case acLBGetValue '6
result = "-"
If Not rsTemplateActions Is Nothing Then
On Error Resume Next
rsTemplateActions.MoveFirst
If Err.number = 0 Then
If Row > 0 Then rsTemplateActions.Move Row
Select Case Col
Case 0 'Action Type
result = rsTemplateActions![Type Text]
Case 1
days = 0
If IsNumeric(rsTemplateActions![DaysAdded]) Then
days = rsTemplateActions![DaysAdded]
result = "+" & days & " days"
Else
result = "?"
End If
Case 2 'Scheduled Date
days = 0
If IsNumeric(rsTemplateActions![DaysAdded]) Then
days = rsTemplateActions![DaysAdded]
End If
If IsDate(txtActionDate.value) Then
dt = CDate(txtActionDate.value)
dt = DateAdd("d", days, dt)
result = Format(dt, "mm/dd/yyyy")
Else
result = "?"
End If
Err.Clear
Case 3 'Descrip
result = rsTemplateActions!Description
Case 4 'Priority
result = ActionPriority(rsTemplateActions!Priority)
End Select
End If
End If
Case acLBGetFormat '7
'* 1440 is twips per inch
Select Case Col
Case Else
result = -1 'Default format
End Select
Case acLBEnd '9
'* Only called when form is closed, not for each requery (I suppose for closing resources)
'On Error Resume Next
'Case acLBClose '8
' 'NOT USED according to online resources.
'Case Else
' Debug.Print "ListBoxResult Code = " & Code
End Select
ListBoxResult = result
End Function