2017-04-26 30 views
0

4 dbLookupCombobox'es를 기반으로 필터링 된 제품을 표시하는 DBGrid가 있습니다.
제조업체를 선택하면 Category1-3이 제조업체.
그런 다음 Category1을 선택하면 Category2-3이 업데이트/필터링되고 선택한 제조업체 및 범주 1의 제품에 대한 기존 범주 만 표시됩니다.
카테고리 1과 카테고리 2는 같지만 카테고리 1을 선택할 수 있습니다.SQL 델파이에서 DBGrid 필터링

또한 제조업체가 선택되지 않은 Category1 + 2 중에서 선택할 수 있기를 원합니다.

이 4 가지 콤보 중 무엇을 선택하든 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를 실행하고 이제 모든 제조업체 및 범주를 콤보로 채 웁니다.
  3. FDQuery5를 실행하고 DBGrid에서 제품의 필터링되지 않은 결과가 있습니다.
  4. 이제 SQL 필터링을 수행 할 준비가되었습니다.

질문 :
가 dbLookupComboBoxes이 작업에 대한 구성 요소의 올바른 선택인가?

이러한 종류의 필터링을 처리하는 것이 올바른 방법입니까?

필자는 FilterProducts 절차를 이해할 수 없습니다. 내 코드를 보여줄 수는 있지만, 나 자신의 삶을 살면서 실제로는 좋지 않습니다.

그런 긴 게시물을 가져 오니 죄송합니다. 나는 이것에서 많은 시간을 보내고 있으며 지금은 정말로 조언이 필요합니다.

답변

1

개인적으로 데이터베이스가 아니라 Delphi에서 로컬로 필터링합니다. 서버에서 더 가볍고 (아마도 필터 할 제품이 많지 않다면) 아마 더 빠를 것입니다.

필터링되지 않은 FDQuery5로드가 이미 가능한 모든 제품과 함께 시작됩니다. 이제 사용자가 필터링 할 옵션을 선택하면 새 SQL 문을 실행하는 대신 직접 로컬로 수행 할 수 있습니다.

또한 FilterProducts를 모든 선택 항목마다 다른 매개 변수로 변경하여 사용자가 두 번 이상 선택하도록 선택할 수 있습니다.당신은 여전히 ​​인해 필요하지 않도록 (새로운 SQL을 실행하는 데 선호하는 경우

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); 

그러나 :

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; 

이제 모든 콤보가 동일한 이벤트 핸들러를 호출 할 수

이 같은 일이 될 것이다 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가 다른 Comboboxes의 선택에 근거를 둔 유효한 선택으로 새롭게하고 싶다. - 나는 달리고 있었지만, 내 뇌를 죽인다. 왜냐하면 나는 이것에 대한 올바른 코드를 알 수 없기 때문이다. 예 : 제조업체와 Category 1 + 2를 선택하십시오. 그런 다음 범주 1을 변경하려고합니다. Boom, Manufacurer 콤보가 이제 비어 있습니다. 그리고 다시 초기화해야합니다. 이 모든 트릭이 있습니까? –