2017-01-30 12 views
2

AdoTable을 사용하여 데이터베이스 (mdb)와 DataSource에 연결했습니다. 이 데이터 소스는 DBGrid에서 사용됩니다 ...병합 된 열의 AdoDB 필터

사용자 입력을 기반으로 AdoTable을 필터링하려고했습니다. 이름, 성 및 ID라는 중요한 열이 있습니다. 나는 임시 해결책으로이 같은 내놓았다 : 그것은 내가 이름을 검색 때 (...하고 싶은 및 surename 것이 정확히 무엇을하지 않습니다

AdoTable.filter:='surname like ' + 
     QuotedStr('%'+edit1.text+'%')+' or name like ' + 
     QuotedStr('%'+edit1.text+'%')+' or ID like ' + 
     QuotedStr('%'+edit1.text+'%'); 
AdoTable.filtered:=true; 

그것은하지 작업하지만하지 않습니다 하나의 열에 만 보이는대로 찾을 수 있음). 그래서 나중에 나는이에 내 코드를 수정 :

이제
AdoTable.filter:='surname & " " & name like ' + 
     QuotedStr('%'+edit1.text+'%')+' or name & " " & surname like ' + 
     QuotedStr('%'+edit1.text+'%')+' or ID like ' + 
     QuotedStr('%'+edit1.text+'%'); 
AdoTable.filtered:=true; 

이 내가하고 싶은 것을 exacly 할 것이다, 그러나 예외 (EOleException 제기 인수, 잘못된 형식의 허용 범위를 벗어나거나 서로 충돌하고있다). SQL 명령에서 where 절로 작동해야한다고 생각하여 꽤 suprises입니다 (그리고 명령으로 완벽하게 작동합니다).

'&'을 '+'로 바꿔서 시도해 보았습니다. 입력 텍스트를 나눌 수는 있지만 그럴 필요가 없습니다. Robin van Persie, Ahmad ibn Hanbal 등의 이름을 사용하면 제대로 작동하지 않을 것입니다.

또는 전체 프로그램을 다시 쓸 수 있습니다. 테이블 대신 쿼리를 사용하고 싶지만 실제로 그렇게하고 싶지는 않습니다. 즉, 새로운 레코드 세트를 EVERYTIME으로 사용자가 편집하는 대신 edit1.text를 변경하게 될 것입니다.

아이디어가 있으십니까?

편집 :이

select * from person where surname & " " & name like '%John Smith%' or name & " " & surname like '%John Smith%' or ID like '%John Smith%' 

필터는 다음과 같습니다 (그리고 예외 트리거) 'HN 스미스'대신이 될 수 있다고

surname & " " & name like '%John Smith%' or name & " " & surname like '%John Smith%' or ID like '%John Smith%' 

주처럼 작동 때문에 명령이 보인다 'John Smith'도 'Kahn Smithers'등을 찾을 수 있습니다.

+0

일부 알 수없는 부분이 있습니다 : ID 유형은 무엇입니까? 코드는 그것이 올바르지 않은 것으로 들리는 문자열이라고 가정합니다. 대부분 ID는 숫자입니다. 두 번째 : 데이터베이스가 무엇입니까? 예를 들면 SQL Express '%'가 정확합니다. 액세스를 사용할 때 '*'를 사용해야합니다. 결과 필터 문자열을 표시 할 수 있습니까? –

+0

ID는 실제로 문자열입니다. 그것은 '123abc'와 같은 것일 수 있습니다. 그리고 Access에서 '%'('*'는 내가 시도하지 않음)를 사용한다는 사실을 발견했습니다. 결과 필터는 ''John Smith % ''또는 ''John Smith % ''와 같은 성 및 ''% John Smith % ''와 같은 성은 '성 & 이름이 '% 0123abcd %' '또는 이름이' '% 0123abcd %' '또는 ID가' '% 0123abcd %' '인 경우 이름 및 성 또는'성 '&'을 (를) 검색하고 있습니다. ID –

+0

을 찾고 있습니다 답변 해답을 – kobik

답변

1

아래의 코드는 employee ta에 액세스하는 AdoTable에서 잘 작동합니다. Delphi dbdemos.mdb 데이터베이스에 있습니다. AdoConnection에서 Microsoft Jet 4.0 OLE DB 드라이버를 사용하고 있습니다.

실수로 언급 한 액세스 관련 구문을 사용하고있는 것 같습니다. ADO 레이어를 통해 테이블에 액세스하고 있으며 AFAIK는 사용하는 것과 동일한 구문을 기대합니다. SQL Server 백엔드에 대한.

사용자 의견에서 사용자가 Edit1.Text에 입력 한 사례를 다루고 싶은 것처럼 보입니다. 첫 번째 이름의 단편 뒤에 단편 또는 성이 오는 공백이옵니다. 다음은 할 것이다 :

procedure TForm1.Button1Click(Sender: TObject); 
var 
    FilterExpr : String; 
    P : Integer; 
    S1, 
    S2 : String; 
begin 
    AdoTable1.Filtered := not AdoTable1.Filtered; 
    if AdoTable1.Filtered then begin 
    P := Pos(' ', Trim(Edit1.Text)); 
    if P > 0 then begin 
     S1 := Copy(Trim(Edit1.Text), 1, P - 1); 
     S2 := Copy(Trim(Edit1.Text), P + 1, MaxInt); 
     FilterExpr := '(FirstName like ' + QuotedStr('%' + S1 + '%') + ')'; 
     FilterExpr := FilterExpr + ' or (LastName like ' + QuotedStr('%' + S2 + '%') + ')'; 
    end 
    else 
     FilterExpr := 'FirstName like ' + QuotedStr('%' + Edit1.Text + '%') + ' or LastName like ' + QuotedStr('%' + Edit1.Text + '%'); 
    AdoTable1.Filter := FilterExpr; 
    end; 
end; 

업데이트 : 당신은 사용자가

HN 스미스 다음

대신이 같은 FilterRecord 이벤트를 사용할 수 같은 것을 입력 할 수 있도록하려면 위의 코드.

procedure TForm1.ADOTable1FilterRecord(DataSet: TDataSet; var Accept: Boolean); 
var 
    S : String; 
begin 
    S := LowerCase(DataSet.FieldByName('FirstName').AsString + ' ' + DataSet.FieldByName('LastName').AsString); 
    Accept := Pos(LowerCase(Edit1.Text), S) > 0; 
end; 

LowerCase로 변환하면 분명히 사용자가 사용한 대소 문자를 무시하는 것입니다.

+0

네,하지만 이것은 이름이나 성을 찾았을 것입니다 ... 맞습니까? 나는 일하도록하고 있지만 둘 다 필요합니다. D. 어느 쪽이든 나는 당신에게 대답 해 주셔서 감사하지만 나는 이미 해결책을 찾은 것 같아요. –

+0

@ RadimNyč : 죄송합니다, "둘 다 필요하다"는 것은 무엇을 의미합니까? firtname과 lastname이 Edit1.Text에있는 레코드를 포함하는 레코드를 찾기 위해 필터를 찾으려면 필터의 "or"를 "and"로 변경하십시오. – MartynA

+0

아니요 ... 'John Smith'와 (과) 같이 edit1.text가 필요합니다. 'John Smith'및/또는 'John Smith'이름을 찾고 아무 것도 찾지 못합니다. –

1

나는 이것을 찾았습니다 : Using LIKE statement for filtering 그리고 받아 들인 대답을 사용하고 그것은 잘 작동합니다. 테이블 필터에

(질문은 매우 다르므로 빨리 찾을 수 없습니다) : 편집 변화에

procedure TDataModule1.ADOTableFilterRecord(DataSet: TDataSet; 
    var Accept: Boolean); 
var 
    nameSurname :string; 
    surnameName :string; 
begin 
    nameSurname:= DataSet.FieldByName('name').AsString+' '+DataSet.FieldByName('surname').AsString; 
    surnameName:= DataSet.FieldByName('surname').AsString+' '+DataSet.FieldByName('name').AsString; 

    if assigned(MainForm) then 
    Accept := (Pos(MainForm.edit1.Text, nameSurname) > 0) 
    or (Pos(MainForm.edit1.Text, surnameName) > 0) 
    or (Pos(MainForm.edit1.Text, DataSet.FieldByName('ID').AsString) > 0); 
end; 

:

procedure TMainForm.edit1Change(Sender: TObject); 
begin 
    DataModule1.AdoTable.Filtered:=false; 
    if edit1.Text<>'' then 
     DataModule1.AdoTable.Filtered:=True; 
end; 

이 시간 내 주셔서 감사 ... 난 떠날거야 그것은 여기에 .. 결국 누군가가 그것을 필요로 할 수 있다고 생각합니다.