Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi ClientDataSet mit zwei Filtern (https://www.delphipraxis.net/193092-clientdataset-mit-zwei-filtern.html)

H.Bothur 19. Jun 2017 17:06

Datenbank: keine • Version: keine • Zugriff über: Delphi

ClientDataSet mit zwei Filtern
 
Moin,

ich habe eine ClientDataSet das ich mit folgendem Source filtere und anzeigen lasse:

Delphi-Quellcode:
function TKund.KundenSuchen(const KundenNummer: String; var KundenRec: TKundenRec): Boolean;
(* Anzeige des DBGrid aus Rückgabe des gewählten Datensatzes *)
begin
  DatenUebernahme := false;
  ClientDataSet_Kunden.Filtered := True;
  ClientDataSet_Kunden.Filter := CTitelKundenNr +'=' +KundenNummer;
  Kund.ShowModal;
  if DatenUebernahme then
  begin
    KundenRec.Firma1 := ClientDataSet_Kunden.FieldByName(CTitelFirma1).AsString;
    KundenRec.Firma2 := ClientDataSet_Kunden.FieldByName(CTitelFirma2).AsString;
  end;
  if DatenUebernahme then Result := true else Result := false;
end;
Das funktioniert auch wunderbar. Jetzt möchte ich aber nach einem zweiten Feld zusätzlichen Filtern .. also

Delphi-Quellcode:
  ClientDataSet_Kunden.Filter := CTitelKundenNr +'=' +KundenNummer +' AND ' +CTitelFirma1 +'=' +FilterString;

Wenn ich z. B. den FilterString auf den Text "RIO" setze dann bekomme ich eine Exception mit der Meldung "Das Feld 'Rio' wurde nicht gefunden." Also mache ich das irgendwie falsch - aber wie mache ich es richtig ??

Gruß
Hans

haentschman 19. Jun 2017 17:22

AW: ClientDataSet mit zwei Filtern
 
Hallöle...:P
Manchmal helfen ein paar Hochkommata...8-)
Delphi-Quellcode:
ClientDataSet_Kunden.Filter := CTitelKundenNr + '=' + KundenNummer + ' AND ' + CTitelFirma1 + '=' + QuotedStr(FilterString);

himitsu 19. Jun 2017 17:25

AW: ClientDataSet mit zwei Filtern
 
Wenn das RIO auch ein Text/String sein soll, dann solltest du es auch wie einen "String" schreiben.

Und warum nehmen Alle immer QuotedStr?
Das ist einfach nicht richtig.
Dafür gibt es irgendwo in den Units der DB-Komponente passende "Escape"-Funktionen (EscapeName, EscapeValue oder so), welche das richtig machen,
denn
Delphi-Quellcode:
'feld = ' + QuoteStr('Das ist ein Text mit " und \ drin')

H.Bothur 19. Jun 2017 19:17

AW: ClientDataSet mit zwei Filtern
 
Vielen Dank, so klappt das jetzt.

Zwei Dinge habe ich aber nicht verstanden:

1) Warum muss ich beim zweiten Text das QuotedStr nutzen, aber nicht beim ersten String (Kundennummer) ?
2) @himitsu: Was meinst Du mit der Bemerkung "'feld = ' + QuoteStr('Das ist ein Text mit " und \ drin')" ?
Wenn ich das in Delphi ausprobiere kommt genau das raus was ich erwarte !

Gruß
Hans

H.Bothur 20. Jun 2017 10:41

AW: ClientDataSet mit zwei Filtern
 
Sorry - eine Sache verstehe ich leider immer noch nicht:

Filter auf nur ein Feld - klappt !
Delphi-Quellcode:
  CTitelKundenNr := 'Nummer';
  CTitelFirma1 := 'Firma1';
  ClientDataSet_Kunden.FilterOptions := [foCaseInsensitive];
  ClientDataSet_Kunden.Filtered := True;
  ClientDataSet_Kunden.Filter := CTitelKundenNr +'=' +QuotedStr(KundenNummer);
Suche nach zwei Feldern, zweites Feld mit Anfangsbuchstaben und dann Asterix - klappt !
Delphi-Quellcode:
  FilterString := 'M';
  CTitelKundenNr := 'Nummer';
  CTitelFirma1 := 'Firma1';
  ClientDataSet_Kunden.FilterOptions := [foCaseInsensitive];
  ClientDataSet_Kunden.Filtered := True;
  ClientDataSet_Kunden.Filter := CTitelKundenNr +'=' +QuotedStr(KundenNummer) +' AND ' +CTitelFirma1 +'=' +QuotedStr(FilterString +'*');
Suche nach zwei Feldern, zweites Feld OHNE Anfangsbuchstaben und dann Asterix - klappt nicht sondern es gibt kein Ergebnis !
Delphi-Quellcode:
  FilterString := ''; { <- hier ist der Unterschied }
  CTitelKundenNr := 'Nummer';
  CTitelFirma1 := 'Firma1';
  ClientDataSet_Kunden.FilterOptions := [foCaseInsensitive];
  ClientDataSet_Kunden.Filtered := True;
  ClientDataSet_Kunden.Filter := CTitelKundenNr +'=' +QuotedStr(KundenNummer) +' AND ' +CTitelFirma1 +'=' +QuotedStr(FilterString +'*');
Meine Idee war das ich den Suchstring zeichen für Zeichen aufbaue und dann eben partiell danach suche. Nur - wenn ich noch keine Suchstring habe müsste der Filter
Delphi-Quellcode:
+CTitelFirma1 +'= *')
doch eigentlich alle Datensätze anzeigen, oder ?

Gruß
Hans

Jumpy 20. Jun 2017 10:54

AW: ClientDataSet mit zwei Filtern
 
Wie ist das denn, wenn du statt "=" ein "like" verwendest?

UNd nicht unbedingt relevant, aber sollte man nicht erst den Filter definieren und dann Filtered=True setzen?

H.Bothur 20. Jun 2017 11:22

AW: ClientDataSet mit zwei Filtern
 
Moin Jumpy,

Zitat:

Zitat von Jumpy (Beitrag 1374965)
Wie ist das denn, wenn du statt "=" ein "like" verwendest?

Dann bekomme ich in der Zeile

Delphi-Quellcode:
  ClientDataSet_Kunden.Filter := CTitelKundenNr +' LIKE ' +QuotedStr(KundenNummer) +' AND ' +CTitelFirma1 +' LIKE ' +QuotedStr(FilterString +'*');
Eine Exception in Modul MIDAS - Lesen von Adresse 000000

Zitat:

Zitat von Jumpy (Beitrag 1374965)
UNd nicht unbedingt relevant, aber sollte man nicht erst den Filter definieren und dann Filtered=True setzen?

Das hat keine Auswirkung - es wird immer noch nichts angezeigt :-(

Hans

jobo 20. Jun 2017 11:45

AW: ClientDataSet mit zwei Filtern
 
Wenn man "nach alles" sucht (also der Stern), kann man die Bedingung auch prima weglassen.
Bin nicht sicher, aber das Like gehrt glaub ich nicht zu dem Funktionsumfang bzw. dieser Filterimplementierung. Bzw. die Wildcard Funktion im Code Beispiel des TE mit <feld>='M*', die offenbar ein Ergebnis liefert, zeigt ja, dass die Implementierung so mit Gleichheitszeichen gedacht ist/funktioniert.
Könnte mir vorstellen, dass ein führendes "*" einfach nicht unterstützt ist wegen Performance. Müsste man mal Doku lesen.

H.Bothur 20. Jun 2017 11:52

AW: ClientDataSet mit zwei Filtern
 
OK - dann muss ich den Suchstring eben entsprechend per IF zusammensetzen - ich hatte nur gedacht das man sich das sparen kann.

Gruß
Hans

Uwe Raabe 20. Jun 2017 11:53

AW: ClientDataSet mit zwei Filtern
 
Zitat:

Zitat von H.Bothur (Beitrag 1374959)
Meine Idee war das ich den Suchstring zeichen für Zeichen aufbaue und dann eben partiell danach suche. Nur - wenn ich noch keine Suchstring habe müsste der Filter
Delphi-Quellcode:
+CTitelFirma1 +'= *')
doch eigentlich alle Datensätze anzeigen, oder ?

Das ist nicht zwingend der Fall. Die Dokumentation sagt:
Zitat:

Wenn ein String in einem Filter mit einem Sternchen endet (*), lassen sich auch Teil-Strings suchen.
Der Sonderfall eines leeren Teil-Strings ist damit nicht explizit abgedeckt. Ich schlage vor, in dem Fall den kompletten Vergleich zusammen mit dem AND wegzulassen.

himitsu 20. Jun 2017 12:27

AW: ClientDataSet mit zwei Filtern
 
Was erwartest du denn bei
Delphi-Quellcode:
Memo1.Text := 'WHERE feld = ' + QuotedStr('Das ist ein Text mit '' und \ drin');
?

Code:
Input: WHERE feld = Das ist ein Text mit " , ' und \ drin

Pascal (QuotedStr: WHERE feld = 'Das ist ein Text mit " , '' und \ drin'

SQL (EscapeValue): WHERE feld = 'Das ist ein Text mit " , \' und \\ drin'

SQL (EscapeName): WHERE feld = "Das ist ein Text mit \" , ' und \\ drin"
Bestimmt was Anderes als ich.

FilterText erwartet einen Text nach der Definition für SQL-Strings.
QuotedStr erzeugt aber einen Text nach der Definition für Pascal-Strings.
Und die sind nicht kompatibel, wenn es um Steuerzeichen geht.

H.Bothur 20. Jun 2017 12:53

AW: ClientDataSet mit zwei Filtern
 
OK - Danke !

Das wusste ich natürlich nicht.

Hans

haentschman 20. Jun 2017 14:58

AW: ClientDataSet mit zwei Filtern
 
@himitsu:
Zitat:

FilterText erwartet einen Text nach der Definition für SQL-Strings.
...wo hast du das her? Die Doku incl. dem Beispiel sagt was anderes. :gruebel:
http://docwiki.embarcadero.com/Libra...DataSet.Filter
Delphi-Quellcode:
with ADODataSet1 do begin
Filtered := False;
Filter := 'State = ' + QuotedStr('CA') + ' OR ' +
'State = ' + QuotedStr('CA');
Filtered := True;
end;

himitsu 21. Jun 2017 09:39

AW: ClientDataSet mit zwei Filtern
 
Nur weil in der Doku etwas Falsches drin steht, heißt es noch lange nicht, dass es richtig ist. :angle2:

Wie gesagt, QuotedStr hat ein anderes Verhalten beim Quoting/Escaping, welches nicht zu einem SQL-Statement passt.

Leider bringt Delphi nativ keine passenden SQL-Funktionen dafür mit, was auch ein bisschen verständlich ist, da es je nach DBMS/Dialekt leichte Unterschiede gibt. (wenn man damit sein SELECT zusammenbauen wöllte)
Aber bezüglich DataSet.Filter weiß ich jetzt nicht, ob das wirklich vom DBMS abhängt ... scheint ja meinstens nur eine Implementation im Delphi zu sein, welches eine minimale Untermenge der im SQL92 enthaltenen Möglichkeiten für ein WHERE-Statement darstellt, welches man quasi mit AND an das WHERE anghängen würde.

So lange keine Steuerzeichen oder irgendwas exotisches verwendet wird, also praktisch nur ASCII ohne ' / " und C0, dann gibt es keine Probleme.


Alle Zeitangaben in WEZ +1. Es ist jetzt 06:36 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz