大型数据库的MS Access搜索表单

时间:2013-10-05 01:43:34

标签: vba ms-access search access-vba

我正在构建一个容纳大量记录的数据库,所以我想要一个在服务器上最简单的搜索功能。我使用以下代码,但我知道它对于更大的数据库是不可持续的。它正在查看搜索框并运行查询以缩小搜索结果范围:

Private Sub SearchFor_Change()
'Create a string (text) variable
Dim vSearchString As String

'Populate the string variable with the text entered in the Text Box SearchFor
vSearchString = SearchFor.Text

'Pass the value contained in the string variable to the hidden text box SrchText,
'that is used as the sear4ch criteria for the Query QRY_SearchAll
SrchText.Value = vSearchString

'Requery the List Box to show the latest results for the text entered in Text Box
'SearchFor
Me.SearchResults.Requery


'Tests for a trailing space and exits the sub routine at this point
'so as to preserve the trailing space, which would be lost if focus was shifted from   
'Text Box SearchFor
 If Len(Me.SrchText) <> 0 And InStr(Len(SrchText), SrchText, " ", vbTextCompare) Then
 'Set the focus on the first item in the list box
 Me.SearchResults = Me.SearchResults.ItemData(1)
 Me.SearchResults.SetFocus
 'Requery the form to refresh the content of any unbound text box that might be feeding 
 'off the record source of  the List Box
 DoCmd.Requery
 'Returns the cursor to the the end of the text in Text Box SearchFor,
 'and restores trailing space lost when focus is shifted to the list box
  Me.SearchFor = vSearchString
  Me.SearchFor.SetFocus
  Me.SearchFor.SelStart = Me.SearchFor.SelLength

  Exit Sub
  End If
  'Set the focus on the first item in the list box
   Me.SearchResults = Me.SearchResults.ItemData(1)
   Me.SearchResults.SetFocus

   'Requery the form to refresh the content of any unbound text box that might be 
   'feeding off the record source of  the List Box
  DoCmd.Requery

'Returns the cursor to the the end of the text in Text Box SearchFor
 Me.SearchFor.SetFocus

If Not IsNull(Len(Me.SearchFor)) Then
Me.SearchFor.SelStart = Len(Me.SearchFor)
End If

理想情况下,我想要一个包含多个搜索字段的表单,以及一个运行查询的“查找”按钮,以便在列表框中返回结果。

我也不确定如何进行设置,以便当用户双击搜索结果中的选项时,所选记录将以编辑模式的形式打开。

非常感谢任何帮助,谢谢!

1 个答案:

答案 0 :(得分:1)

首先,你在一篇文章中提到了两个问题。我建议您在双击时解决有关在编辑模式下打开选择的第二个问题。

尽我所知,您关心的是当前代码的性能以及它提供的功能或灵活性的缺乏。

关于表现:

  • 请勿使用更改方法执行过滤器。如果您确实想要使用更改方法,请仅将其用于将计时器间隔设置为500(ms),然后对Timer事件执行过滤。这是在用户停止输入半秒之后才会发生过滤。
  • 避免“模糊”搜索(在文本字段中使用星号/百分比)。它现在看起来不像你在使用它们。虽然模糊搜索通常会使软件更加用户友好,但当它们对性能产生重大影响时,它们会降低用户友好性。
  • 在处理大量数据时,大多数性能提升来自于仔细调整应用程序的工作方式,升级到SQL Server,以及将服务器和网络升级到更好的硬件。使用JET / ACE后端数据库容器时,您只能进行大量改进。带有ADO和ODBC链接表的SQL Server与使用JET / ACE的DAO相比都具有一些优势。 ODBC链接表提供延迟加载,而ADO提供诸如断开连接的记录集之类的东西,可以在没有额外回调到服务器的情况下进行过滤(这有限制)。
  • 如上所述,您可能需要仔细重新考虑应用程序的工作方式及其设计方式。最好尝试限制所需的复杂查询量以及允许/需要的基于文本的搜索量。使用更多查找/引用表。不要将类似的类别存储为文本,而是考虑将它们存储为长号类别ID。对索引数字字段的查询通常比基于文本的字段上的查询执行得更好,尤其是在查询中使用带有星号的LIKE时。

就问题的其余部分(灵活性和功能)而言,请考虑根据多个控件的值创建一个为您构建条件/ where语句的过程。在像你这样的情况下,我的代码看起来像这样(下图)。请注意,我在描述搜索/过滤器中使用了星号(模糊搜索)。如果它表现不佳,你需要考虑将其取出并允许用户使用自己的星号。

Private Sub cmdSearch_Click()
    Call SetRowSource
End Sub

Private Sub txtSearch_AfterUpdate()
    Call SetRowSource
End Sub

Private Sub cboCategoryID_AfterUpdate()
    Call SetRowSource
End Sub

Private Sub txtBrand_AfterUpdate()
    Call SetRowSource
End Sub

Private Sub SetRowSource()
    Dim sSQL as String
    sSQL = "SELECT ItemID, Description, Brand FROM tblItems "
    sSQL = sSQL & GetWhere
    Me.lstSearchResults.RowSource = sSQL
End Sub

Private Function GetWhere() as String
    Dim sWhere as String
    If Nz(Me.cboCategoryID, 0) <> 0 Then
        sWhere = sWhere & "CategoryID = " & Me.cboCategoryID & " AND "
    End If
    If Nz(Me.txtSearch, "") <> "" Then
        sWhere = sWhere & "Description LIKE '*" & Replace(Me.txtSearch, "'", "''") & "*' AND "
    End If
    If Nz(Me.txtBrand, "") <> "" Then
        sWhere = sWhere & "Brand = '" & Replace(Me.txtBrand, "'", "''") & "' AND "
    End If
    If sWhere <> "" Then
        sWhere = Left(sWhere, Len(sWhere)-5)
        GetWhere = "WHERE " & sWhere
    End If
End Function

我认为在Access社区中我可能有点奇怪,但我通常不允许我的控件引用其他控件。在您的情况下,列表框中的RowSource引用它所在表单的控件。出于各种原因,我更喜欢在VBA代码中构建我的SQL语句,特别是当它们受到更改/过滤时。您可能考虑的另一件事是使用数据表表单而不是列表框。您可以设置表单的RecordSource,然后将WHERE语句应用于表单的Filter属性。数据表表单对于用户来说更灵活,因为他们可以在没有程序员帮助的情况下调整列的大小并进行排序。您始终可以锁定控件,以便他们无法进行任何编辑。当我以这种方式使用数据表时,我认为使用DoubleClick事件允许他们打开记录,这可以说是用户友好,然后单击列表框。