2017-04-26 134 views
0

我想要一個DBGrid顯示基於4 dbLookupCombobox'es過濾的產品
如果我選擇一個製造商,那麼Category1-3將更新/過濾並僅顯示所選產品的現有類別製造商。
如果我然後選擇一個Category1,那麼Category2-3將更新/篩選並僅顯示所選製造商和Category1的產品的現有類別。
與Category2相同,但包含Category1的選擇。SQL在Delphi中過濾DBGrid

此外,我希望只能從Category1 + 2中選擇,沒有選擇製造商。

無論我從這4個Combos中選擇什麼,我都希望DBGrid更新並顯示過濾後的產品。

完成過濾後,我需要重置過濾器按鈕重新開始。

場景:

1x FDConnection, Firebird. 
5x FDQuery and Datasources 
1x DBGrid 
4x dbLookupComboBox 
1x Button 

的查詢:

FDQuery1: FDQ_Manufacturers: 
    select distinct MANUFACTURERNAME from Products where 
    upper (CATEGORYTEXT1) like upper(:CATEGORYTEXT1) 
    and upper(CATEGORYTEXT2) like upper(:CATEGORYTEXT2) 
    and upper(CATEGORYTEXT3) like upper(:CATEGORYTEXT3) 

FDQuery2: FDQ_Category1 
    select distinct CATEGORYTEXT1 from Products where 
    upper(MANUFACTURERNAME) like upper(:MANUFACTURERNAME) 

FDQuery3: FDQ_Category2 
    select distinct CATEGORYTEXT2 from Products where 
    upper(MANUFACTURERNAME) like upper(:MANUFACTURERNAME) 
    and upper(CATEGORYTEXT1) like upper(:CATEGORYTEXT1) 

FDQuery4: FDQ_Category3 
    select distinct CATEGORYTEXT3 from Products where 
    upper(MANUFACTURERNAME) like upper(:MANUFACTURERNAME) 
    and upper(CATEGORYTEXT1) like upper(:CATEGORYTEXT1) 
    and upper(CATEGORYTEXT2) like upper(:CATEGORYTEXT2) 

FDQuery5: FDQ_Products 
    select first 100 * from Products where 
    and upper(MANUFACTURERNAME) like upper(:MANUFACTURERNAME) 
    and upper(CATEGORYTEXT1) like upper(:CATEGORYTEXT1) 
    and upper(CATEGORYTEXT2) like upper(:CATEGORYTEXT2) 
    and upper(CATEGORYTEXT3) like upper(:CATEGORYTEXT3) 
    and upper(DESCRIPTION) like upper(:DESCRIPTION) 
    ORDER BY PRICE 

的dbLookupComboBox'es:

dbLookupComboBox1: LCB_Manufacturers: OnSelect: FilterProducts('MANUFACTURERNAME', LCB_Manufacturers.Text); 
dbLookupComboBox2: LCB_Category1:  OnSelect: FilterProducts('CATEGORYTEXT1', LCB_Category1.Text); 
dbLookupComboBox3: LCB_Category2:  Onselect: FilterProducts('CATEGORYTEXT2', LCB_Category2.Text); 
dbLookupComboBox4: LCB_Category3:  OnSelect: FilterProducts('CATEGORYTEXT3', LCB_Category3.Text); 

ListSource is the DataSources for each FDQuery. 
ListField and KeyField is respectively the MANUFACTURERNAME, CATEGORYTEXT1, CATEGORYTEXT2, CATEGORYTEXT3 
  1. 我初始化所有PARAMS以 '%%'
  2. 我運行FDQuery1-4,現在已經將所有制造商和類別填入Combos。
  3. 我運行FDQuery5並在DBGrid中有一個未經過濾的結果。
  4. 現在我們準備好進行SQL過濾了。

問題:
dbLookupComboBoxes是該任務組件的正確選擇嗎?

它是處理這種過濾的正確方法嗎?我想不出FilterProducts的過程。我可以展示我的代碼,但我真的不好,過着自己的生活..

對不起,帶來如此長的職位。 我在這花了很多時間,現在真的需要建議。

回答

1

我個人會在Delphi上本地過濾,而不是在數據庫上過濾。它在服務器上更輕,可能更快(除非你真的有很多產品要過濾)。

您已經開始加載未過濾的FDQuery5以及所有可能的產品。現在,當用戶選擇一個過濾選項時,您可以直接在本地執行該選項,而不是運行新的SQL語句。

此外,我會更改您的FilterProducts爲每個選擇有不同的參數,因此用戶可以選擇多個選項。

這將是這樣的:

procedure MyForm.FilterProducts(ManufacturerName: string; CategoryText1: string; CategoryText2: string; CategoryText3: string); 
var Filter: string; 
begin 
    Filter := 'MANUFACTURERNAME like ' + QuotedStr(ManufacturerName); 
    Filter := Filter + ' and CATEGORYTEXT1 like ' + QuotedStr(CategoryText1); 
    Filter := Filter + ' and CATEGORYTEXT2 like ' + QuotedStr(CategoryText2); 
    Filter := Filter + ' and CATEGORYTEXT3 like ' + QuotedStr(CategoryText3); 

    FDQuery5.FilterOptions := [foCaseInsensitive]; 
    FDQuery5.Filter := Filter; 
    FDQuery5.Filtered := True; 
end; 

現在所有的組合框可以調用同一個事件處理:

dbLookupComboBox1: LCB_Manufacturers: OnSelect: FilterProducts(LCB_Manufacturers.Text, LCB_Category1.Text, LCB_Category2.Text, LCB_Category3.Text); 
dbLookupComboBox2: LCB_Category1:  OnSelect: FilterProducts(LCB_Manufacturers.Text, LCB_Category1.Text, LCB_Category2.Text, LCB_Category3.Text); 
dbLookupComboBox3: LCB_Category2:  Onselect: FilterProducts(LCB_Manufacturers.Text, LCB_Category1.Text, LCB_Category2.Text, LCB_Category3.Text); 
dbLookupComboBox4: LCB_Category3:  OnSelect: FilterProducts(LCB_Manufacturers.Text, LCB_Category1.Text, LCB_Category2.Text, LCB_Category3.Text); 

但是,如果你還是喜歡運行新的SQL(由於沒有所有產品上FDQuery5,只是第100),那麼已通過所有的選擇,FilterProduts,獲取你想要的產品上FDQuery5應該是很簡單的:

procedure MyForm.FilterProducts(ManufacturerName: string; CategoryText1: string; CategoryText2: string; CategoryText3: string); 
begin 
    FDQuery5.Close; 
    FDQuery5.ParamsByName('MANUFACTURERNAME').Value := ManufacturerName; 
    FDQuery5.ParamsByName('CATEGORYTEXT1').Value := CategoryText1; 
    FDQuery5.ParamsByName('CATEGORYTEXT2').Value := CategoryText2; 
    FDQuery5.ParamsByName('CATEGORYTEXT3').Value := CategoryText3; 
    FDQuery5.Open; 
end; 
+0

我有大約40,000條記錄,因此將它們全部加載到數據集中不是一種選擇。本地過濾器也是如此。 FilterProducts工作完美。謝謝。但是,如果您閱讀我的第一篇文章,我希望4個Comboboxes根據其他Combobox的選擇進行有效選擇更新。 - 我運行了它,但它殺死了我的大腦,因爲我無法找出正確的代碼。例如。我選擇一個製造商,並選擇一個類別1 + 2。然後,我希望改變類別1. Boom,Manufacurer組合現在是空的。我必須重新初始化。有任何這樣的技巧? –