2011-06-01 198 views
2

我目前正在研究一個相當複雜的數據庫,至少在我的能力級別上。本質上它是一個項目,結構和聯繫人的數據庫。在這些結構中,每個子結構都有獨特的屬性。MS Access:使用用戶輸入的主窗體和子窗體條件在表單中篩選/搜索記錄

項目,結構和聯繫人在一個主控窗體中連接在一起,並帶有選項卡窗格。並且在這些窗格中是具有多個子窗體的窗體。我試圖編寫一個搜索功能,我可以將其放在每個表單上,以便用戶可以選擇多個條件來過濾結果。但是,某些標準或表單和其他標準是從多個子表單中抽取出來的,並且在子表單中的某些字段中有多個條目。我知道這聽起來可能不是很健全的數據庫設計,但我被告知需要遵守一個特定的結構和佈局,這些結構和佈局我不夠熟練。

我一直在尋找關於搜索條件的allen的網站,但這只是一個單一的形式。我試圖將Subquery教程頁拼湊在一起,但無濟於事。基本上,我想知道是否完全有可能過濾信息,例如,在主窗體上的結構類型,然後例如...一系列數字,例如存在於子窗體中的長度和對象鄰近該表單存在於另一個子表單中,並且使主表單僅顯示滿足子表單和主表單中標準組合的記錄。

我很抱歉,如果這是模糊的,如果它會幫助我可以張貼我迄今爲止我的數據庫的一般框架。感謝您提供任何幫助。

編輯---增加了屏幕截圖更多信息 因爲我的代表處是低於10,我不能發表圖片,但希望我能包括鏈接

http://img829.imageshack.us/img829/1594/99258898.png http://img40.imageshack.us/img40/2186/27578829.png

這是很難看到這裏,但在組合框中有些是多值列表。右邊第一個圖像上的組合框根據從左上角組合框中選擇的類型進行切換,該組合框具有不同的屬性。理想情況下,我希望能夠搜索主窗體和子窗體。併產生僅滿足所有用戶輸入數據的記錄。現在我已經嘗試過使用過濾器,每個過濾器都有一個過濾器,但是所有這些過濾器都會在與過濾器標準不相符的子過程中出現信息。

回答

3

你有沒有截圖可以發佈?

這對我來說聽起來像一個更大的設計問題,可能大部分在您的用戶界面中,但也可能在您的表結構中。我試圖遵循的一個我自己的原則是限制單個屏幕/表單執行或顯示的內容。你的描述聽起來讓我感到困惑,我認爲普通用戶很容易被它所淹沒。

通常子表單是主表單的結果。也就是說,它們包含子記錄,並通過子記錄外鍵和主表單主鍵鏈接到主表單中的記錄。這並不是說沒有其他方式來設計你的表格,但這被認爲是「正常」或「標準」設計。您的描述表明過濾主窗體是由子窗體上設置的過濾器決定的。我想我想不出任何可能需要解決的問題,像這樣令人困惑和笨拙。我將這種可能性放開,我沒有遇到像你處理過的那樣困難或複雜的事情。

我想你可能會遇到一些困難在這裏得到更好的幫助,因爲你的問題確實更適合於討論論壇,如UtterAccess.com。您可以考慮在這樣的網站上發佈數據庫的副本,以便用戶可以查看您的設計,並可能推薦一種更加可靠和標準的方法。

EDIT1:
1)根據你的截圖,我認爲你正在試圖做太多的事情在一個形式。我通常會將每個頂部選項卡(項目,結構,公司,聯繫人)分別製作成各自的形式。 Access 2007和2010允許您本地使用選項卡式界面,並且我無法想到使用選項卡式容器控件來開發您自己的選項卡式界面的任何實際益處。

2)我的意見是,搜索通常應該在一個單一的主窗體中執行,它具有單個列表框,數據表視圖子窗體或連續窗體子窗體。無論你選擇哪一個都不太重要。執行搜索後,用戶應能夠單擊列表框或子表單中的結果記錄來選擇該記錄,並在細節視圖窗體中移至該窗體,類似於您在此處創建的內容。它可能需要幾個不同的搜索屏幕,以允許用戶搜索所有你想要的方式。例如,您可以構建一個屏幕來搜索項目,一個搜索結構,另一個搜索聯繫人,第四個搜索公司。應該可以在查詢中結合其中的一些內容,並允許用戶通過多個標準進行搜索,但如果您嘗試允許他們一次搜索太多字段,可能會引起混淆,特別是如果他們搜索的字段是在單獨的表格中。例如,如果您構建一個查詢,將所有項目,結構和公司一起顯示並將其用作數據表子表單的記錄源,則可以允許用戶按項目,結構或公司進行搜索。但是,如果一個項目有10個結構,那麼項目將在查詢/表單中列出10次,如果他們正在考慮按項目進行搜索,可能會使用戶感到困惑。如果他們按照結構進行搜索,那麼對於他們來說完全有意義的是,同一個項目有10個條目,因爲他們會看到10個不同的結構。

我的基本建議是,要小心嘗試將過多的函數構建爲單一形式。有一些類型的任務或數據集需要具有多個子表單和大量控件的複雜表單,但是一般情況下,您想盡量避免這種情況。建立每個表單的任務非常重要,只需構建更多表單即可完成所有必需的任務。當然,你也可以採取這種方法,但是你確實需要儘量減少複雜性,以免將來頭疼。就基於多個標準的過濾而言,我會看看我是否可以找到任何好的示例,或者可以將它們放在一起並使其可用。這並不難,但這是一個多步驟的過程,建立和經驗使我得到了一個我很滿意的總體設計,而且在任何可能的情況下,這個設計幾乎完美無瑕。

編輯2:
下面介紹如何創建多字段過濾器/搜索。

1)建立您的查詢。包括需要由用戶查看或由用戶搜索的所有表和字段。您可以在此處包含將被搜索但用戶無法查看的字段,但這可能會讓用戶感到困惑。保存你的查詢並給它一個合適的名字。請確保包含您的ID /主鍵字段,因爲步驟4中將需要這些字段。
2)現在在導航窗格中突出顯示您的查詢,轉到頂部菜單並選擇創建>更多表單>數據表(我使用Access 2007)。允許訪問創建並向您顯示我們將用作子窗體的數據表格。保存這個並給它一個合適的名字,比如fsubProjectSearch的subformProjectSearch。
3)獲取剛剛創建的新窗體的設計視圖。更改屬性以禁止添加,刪除和編輯,除非您確實想要允許這些操作。一般來說,我不允許以這些搜索形式輸入任何數據,除非我已經很好地計劃並測試了這些數據。
4)轉到此表單的代碼並添加代碼以雙擊彈出相關的詳細信息表單。例如,在投影或項目名稱字段中,允許用戶雙擊以調出項目詳細信息表單。假設您已選擇在查詢中包含一個或多個這些文本框,請將雙擊例程添加到用戶可能想要彈出結構,公司或聯繫人的任何其他文本框中。你的代碼看起來像DoCmd.OpenForm「ProjectDetails」,,「ProjectID =」& Me!ProjectID現在再次保存表單並關閉它。
5)現在創建一個新的空白表單並將第一個表單添加爲子表單。在頂部留出空間以添加過濾控件。此表單不需要設置任何記錄源。

轉向:我通常採取兩種不同的方法之一來過濾。最重要的是給用戶一個他們可以輸入的文本框。我認爲使用他們輸入的數據在一大堆不同的領域進行模糊搜索。這是一種非常糟糕的性能明智方法,特別是一旦數據庫增長超過大約20,000條記錄。它也可能導致一些混淆,因爲太短的通用搜索可能會產生太多結果。如果他們只輸入字母s並搜索,他們可能會得到幾乎所有的記錄。

我使用的第二種方法可能更常見。爲他們可能想要搜索的每個字段提供一個不同的文本框。您也可以將其設爲複選框或組合框,如果這符合他們正在搜索的字段。這些將不受限制的控制。這可以讓用戶獲得相當具體的信息,並且最有可能返回他們正在查找的確切結果。就代碼而言,我不認爲一種方法比另一種方法簡單得多。無論我在這裏列出的任何一種方法,在將它放入過濾器語句中的某些字段之前,您確實需要檢查它們輸入的數據的類型。例如,您不想嘗試使用非日期文本輸入來過濾日期字段。在第二種方法中,您可以通過使用驗證規則,輸入掩碼或設置文本框格式屬性來消除更多此類問題。組合還有助於禁止輸入不正確的數據。

第三種選擇是某種混合方法。您可以創建一個文本框在多個字段上進行搜索,但不一定在所有字段上進行搜索。例如,您可能創建一個文本框,用於在公司,名字或姓氏上進行搜索。您可以根據需要創建儘可能多的這些文本框。如何使用這些文本框中的輸入將完全由您在VBA代碼中確定。

6)現在你已經決定要採取哪種方法,你可以繼續添加你的控件。給他們適當的名字和標籤。
7)現在是時候創建將構建過濾語句的函數。使用下面列出的兩個想法之一。確保在用戶按下搜索按鈕或控件AfterUpdate事件時運行這些按鈕。

Private Sub txtSearch_AfterUpadate() 
     Call FilterSubformOption1 
    End Sub 

Private Sub FilterSubformOption1() 
    Dim strFilter as String 
    Dim sSearch as String 
    sSearch = Replace(Nz(Me.txtSearch, ""), "'", "''") 
    If sSearch <> "" Then 
     If IsDate(sSearch) = False Then 
      strFilter = "(ProjectName LIKE '*" & sSearch & "*' OR " 
      strFilter = strFilter & "StructureName LIKE '*" & sSearch & "*' OR " 
      strFilter = strFilter & "CompanyName LIKE '*" & sSearch & "*')" 
     Else 
      strFilter = "ProjectDate = #" & CDate(sSearch) & "#" 
     End If 
    End If 
    If strFilter <> "" Then 
     Me.fsubProjectSearch.Form.Filter = strFilter 
     Me.fsubProjectSearch.Form.FilterOn = True 
    Else 
     Me.fsubProjectSearch.Form.Filter = "" 
     Me.fsubProjectSearch.Form.FilterOn = False 
    End If 
End Sub 


Private Sub FilterSubformOption2() 
    Dim strFilter as String 

    If Nz(Me.txtProjectName, "") <> "" Then 
     strFilter = "ProjectName LIKE '*" & Replace(Me.txtProjectName, "'", "''") & "*' AND " 
    End If 
    If Nz(Me.txtStructureName, "") <> "" Then 
     strFilter = strFilter & "StructureName LIKE '*" & Replace(Me.txtStructureName, "'", "''") & "*' AND " 
    End If 
    If Nz(Me.txtCompanyName, "") <> "" Then 'Search on multiple fields from one textbox 
     strFilter = strFilter & "CompanyName LIKE '*" & Replace(Me.txtCompanyName, "'", "''") & "*' AND " 
    End If  
    If IsNull(Me.txtProjectDate) = False Then 
     If IsDate(Me.txtProjectDate) = True Then 
      strFilter = strFilter & "ProjectDate = #" & Me.txtProjectDate & "#" 
     End If 
    End If 
    If Right(strFilter, 5) = " AND " THEN strFilter = Left(strFilter, Len(strFilter) - 5) 
    If strFilter <> "" Then 
     Me.fsubProjectSearch.Form.Filter = strFilter 
     Me.fsubProjectSearch.Form.FilterOn = True 
    Else 
     Me.fsubProjectSearch.Form.Filter = "" 
     Me.fsubProjectSearch.Form.FilterOn = False 
    End If 
End Sub 

Private Sub FilterSubformOption3() 
    Dim strFilter as String 

    If Nz(Me.txtProjectName, "") <> "" Then 
     strFilter = "ProjectName LIKE '*" & Replace(Me.txtProjectName, "'", "''") & "*' AND " 
    End If 
    If Nz(Me.txtStructureName, "") <> "" Then 
     strFilter = strFilter & "StructureName LIKE '*" & Replace(Me.txtStructureName, "'", "''") & "*' AND " 
    End If 
    If Nz(Me.txtName, "") <> "" Then 'Search on multiple fields from one textbox, the "hybrid" solution 
     strFilter = strFilter & "(CompanyName LIKE '*" & Replace(Me.txtName, "'", "''") & "*' OR " 
     strFilter = strFilter & "FirstName LIKE '*" & Replace(Me.txtName, "'", "''") & "*' OR " 
     strFilter = strFitler & "LastName LIKE '*" & Replace(Me.txtName, "'", "''") & "*') AND " 
    End If  
    If IsNull(Me.txtProjectDate) = False Then 
     If IsDate(Me.txtProjectDate) = True Then 
      strFilter = strFilter & "ProjectDate = #" & Me.txtProjectDate & "#" 
     End If 
    End If 
    If Right(strFilter, 5) = " AND " THEN strFilter = Left(strFilter, Len(strFilter) - 5) 
    If strFilter <> "" Then 
     Me.fsubProjectSearch.Form.Filter = strFilter 
     Me.fsubProjectSearch.Form.FilterOn = True 
    Else 
     Me.fsubProjectSearch.Form.Filter = "" 
     Me.fsubProjectSearch.Form.FilterOn = False 
    End If 
End Sub  

而且這幾乎完成了我通常使用的多標準過濾解決方案。

+0

@ HK1我已經包含了我的db的一些屏幕截圖的鏈接,它的目的是成爲一個工程數據庫,存儲從聯繫人,公司,角色到結構類型特定信息的各種屬性。 – imprz 2011-06-01 20:30:58

+0

感謝您的幫助。我會試試這個。 – imprz 2011-06-02 04:19:31

+0

我的代碼中有一些錯誤會阻止它正常工作。我已經修復了它們,並且我還將Option2篩選從Option3篩選中劃分出來,以便您可以看到差異。這一切都很簡單,一旦你得到它。 – HK1 2011-06-02 12:11:32

0

我爲幾乎所有的Access應用程序創建了複雜的逐表單接口。爲什麼?因爲我的用戶需要他們!我的網站上有some screenshots of some older examples,但沒有一個真的很清楚。關鍵是我正在編寫SQL,並根據是否爲該表尋找標準來選擇是否查詢特定的表。

我可以說更多關於它的信息,但它很快就會隱藏到專有信息中。如果這些看起來像你想要走的方向,那麼爲什麼不用足夠的信息來創建一個新的問題來根據這些原則來建議如何完成。

+0

感謝David的輸入,當我進一步深入設計過程並更熟悉SQL語句創建時,我一定會創建一個新問題。你的數據庫模式看起來與我想要實現的類似,但是由於我唯一的正式教育,我對SQL和VBA都非常不熟練,因此這是一個單獨的第3年cpsc大學數據庫理論課程。 – imprz 2011-06-02 22:22:47

+0

1982年,我在計算機,施樂西格瑪IX的大型機BASIC中只進行了一個單學期的課程。可以在沒有課程的情況下學習這些東西。 – 2011-06-08 23:45:51

相關問題