2013-10-05 53 views
0

我正在構建一個將容納大量記錄的數據庫,因此我想要一個在服務器上最簡單的搜索功能。我正在使用下面的代碼,但我知道這對於更大的數據庫來說是不可持續的。它着眼於搜索框和運行查詢,以縮小搜索結果:適用於大型數據庫的MS Access搜索表格

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

首先,您在一篇文章中提出了兩個問題。我建議你在編輯模式下雙擊打開第二個問題。

盡我所知,您關心的是當前代碼的性能以及它提供的功能和靈活性的缺乏。

關於業績:

  • 不要使用變化的方法來執行濾鏡。如果您確實想要使用更改方法,請僅使用它將計時器間隔設置爲500(ms),然後在Timer事件上執行過濾器。這是過濾器不會發生,直到用戶停止鍵入半秒後纔會發生。
  • 避免「模糊」搜索(在文本字段中使用星號/百分比)。它看起來不像你現在使用它們。雖然模糊搜索通常會使軟件更加用戶友好,但當它們對性能產生重大影響時,它們會使用戶不太友好。
  • 處理大量數據時,大多數性能提升都來自於仔細重構應用程序的工作方式,升級到SQL Server並將服務器和網絡升級到更好的硬件。在使用JET/ACE後端數據庫容器時,您只能提高這麼多。帶有ADO和ODBC鏈接表的SQL Server與使用JET/ACE的DAO相比具有一些優勢。 ODBC鏈接表提供延遲加載,而ADO提供諸如斷開連接的記錄集之類的東西,可以在沒有額外的回調服務器的情況下進行過濾(這是有限制的)。
  • 如上所述,您可能需要仔細重新考慮應用程序的工作方式以及它的設計方式。最好儘量限制所需的複雜查詢的數量以及允許/需要的基於文本的搜索量。使用更多的查找/參考表。不要像存儲類似文本那樣存儲,而應考慮將它們存儲爲Long Number CategoryID。索引數字字段上的查詢通常比基於文本的字段上的查詢執行得更好,尤其是當您在查詢中使用帶星號的LIKE時。

就您的問題的其餘部分(靈活性和功能)而言,請考慮根據多個控件的值創建一個爲您創建criteria/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事件來允許他們打開記錄,然後使用列表框中的一次單擊就可以減少對用戶友好的記錄。

+0

謝謝,HK1。這非常有幫助 - 我正在努力將自己的代碼建議付諸實踐。 – intruesiive