2013-10-05 3 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)과 같이 설정 한 다음 타이머 이벤트에서 필터를 수행하는 경우에만 사용해야합니다. 이 필터는 사용자가 0.5 초 동안 타이핑을 멈추기 전까지는 발생하지 않았습니다.
  • "퍼지"검색 (텍스트 필드에서 별표/퍼센트 사용)을 피하십시오. 지금 사용하고있는 것처럼 보이지 않습니다. 일반적으로 퍼지 검색은 소프트웨어를보다 사용자 친화적으로 만들어 주지만 성능에 중요한 영향을 줄 때 사용자 친화적이지 못하게 만듭니다.
  • 많은 양의 데이터로 작업 할 때 대부분의 성능 향상은 응용 프로그램 작동 방식을 신중하게 재구성하고 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 

은 내가 액세스 지역 사회에 조금 이상한 것 같아요하지만 일반적으로 내 컨트롤이 다른 컨트롤을 참조 할 수 없습니다. 귀하의 경우에는 목록 상자에있는 RowSource가 위치한 양식의 컨트롤을 참조합니다. 여러 가지 이유로 VBA 코드에서 SQL 문을 작성하는 것을 선호합니다. 특히 변경/필터링 작업을 수행 할 때 그렇습니다. 또 다른 일은 목록 상자 대신 데이터 시트 양식을 사용하는 것입니다. 폼의 RecordSource를 설정하고 폼의 Filter 속성에 WHERE 문을 적용하면됩니다. 데이터 시트 양식은 열 크기를 조정할 수 있고 프로그래머의 도움없이 정렬 할 수 있으므로 사용자가보다 유연하게 사용할 수 있습니다. 컨트롤을 잠글 수 있기 때문에 편집 할 수 없습니다. 이런 식으로 데이터 시트를 사용할 때 DoubleClick 이벤트를 사용하여 레코드를 열 수 있다고 생각합니다. 레코드를 열 수는 있습니다.

+0

감사합니다. HK1. 이것은 매우 도움이되었습니다. 저는 여러분의 코드 제안을 독자적으로 채택하려고합니다. – intruesiive

관련 문제