Entwickler-Ecke

Datenbanken - Ein Edit mehrere Spalten durchsuchen


Fliegerbenny - Fr 07.03.08 20:45
Titel: Ein Edit mehrere Spalten durchsuchen
Hallo,

ich stehe vor dem Problem, dass ich eine Tabelle habe mit 5 Spalten und ich sie gern mit einem Edit durchsuchen lassen möchte. Das ganze soll mittels Button ausgelöst werden.

Hier mein bisheriger Ansatz, was läuft da schief?


ADOTable1.Filter := 'Bezeichnung, ICAO, IATA, Rufname, Land='+ QuotedStr(Edit1.Text);
ADOTable1.Filtered := True;


mkinzler - Fr 07.03.08 21:20


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
var
    sl: TStrings;
...
    sl := TStringList.Create;
    sl.CommaText := Edit1.Text;
    ADOTable1.Filter := 'Bezeichnung = '+ QuotedStr(sl.Items[0)]+'  and ...
    ...
    sl.Free;


alzaimar - Fr 07.03.08 21:21

...eher mit ODER, oder?


mkinzler - Fr 07.03.08 21:27

Er scheint aber die gewünschten Werte durch Komma getrennt im Edit eingeben zu wollen


Fliegerbenny - Fr 07.03.08 21:50

die durch komme getrennten begriffe sind die felder der datenbanktabelle...

ich möchte wenn man so will mit einem edit alles durchsuchen können, egal in welchem feld es steht


mkinzler - Fr 07.03.08 21:55

Dann mit OR


Fliegerbenny - Sa 08.03.08 09:43

Ich habe nun folgenden ansatz aber scheinbar überspringt er die if anweisung und macht sofort bei else weiter und zeigt gleich die message an.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
procedure TForm4.SpeedButton1Click(Sender: TObject);
begin
if
        (ADOTable1.Filter = 'Bezeichnung='+ QuotedStr(Edit1.Text))
        or
        (ADOTable1.Filter = 'ICAO='+ QuotedStr(Edit1.Text))
        or
        (ADOTable1.Filter = 'IATA='+ QuotedStr(Edit1.Text))
        or
        (ADOTable1.Filter = 'Rufname='+ QuotedStr(Edit1.Text))
        or
        (ADOTable1.Filter = 'Land='+ QuotedStr(Edit1.Text))
then
begin
        ADOTable1.Filtered := True;
end
else
begin
      MessageDlg('Datensatz nicht gefunden',mtinformation,[mbOK],0);
      ADOTable1.Filtered := false;
end;
end;


Bin ratlos....


Agawain - Sa 08.03.08 10:21

Moin

Das ist ja auch völlig unlogisch. Im if fragst Du ab, welche Filter gesetzt sind.

Ist es wirklich nötig, dass er in allen Feldern nach dem Begriff sucht?
Sonst würde ich vorschlagen, Du machst eine Optiongroup mit den Feldern, in denen gesucht werden soll.

Wenn wirklich alle Felder durchsucht werden sollen, dann würde ichs doch lieber mit SQL machen.
Letztendlich solltest Du Dich ohnehin damit anfreunden, denn bei Deinem Projekt könnt ich mir vorstellen, dass Du schnell zu komplexeren Fragestellungen kommst.

Die Eigenschaft Filter ist ein schneller Weg, aber in letzter Konsequenz macht die Kompo nichts anderes, als ein SQL-Statement daraus zu generieren und das ist das einzige, was die Datenbank auch versteht.

Also Quick and Dirty, nur für einfache Sachen.

Dein SQL müßte bei Suche über alles so aussehen:

SELECT * FROM tb_meineflieger WHERE Feld1 = Edit.Text OR .....


Fliegerbenny - Sa 08.03.08 10:40

Ich habe mich schon mit SQL angefreundet, wusste bisher aber noch nie wie ich es in Delphi verwende.

Ich habe eine ADO Table, ADO Connection und eine DataSource, benötige ich eine ADOQuery?

Wie würde meine Abfrage dann ausschauen wenn ich sie in den "Button" schreibe?

ADOQuery1.SQL.Clear;
ADOQuery1.SQL.Add ('SELECT * FROM airline WHERE 'Bezeichnung = Edit1.text' or 'ICAO = Edit1.text' usw....);
ADOQuery1.Open;


alzaimar - Sa 08.03.08 10:41

user profile iconAgawain hat folgendes geschrieben:
...aber in letzter Konsequenz macht die Kompo nichts anderes, als ein SQL-Statement daraus zu generieren und das ist das einzige, was die Datenbank auch versteht.

Öhm. Nö. Jedenfalls nicht bei mir. Die Filter-Eigenschaft wird von ADO geparst und in-Memory ausgeführt. Daher gelten für die Syntax auch eingeschränkte Regeln, weil nicht jede DBMS die gleichen Konstrukte versteht.


Fliegerbenny - Sa 08.03.08 11:06

Sorry nochmal der Nachfrage aber ich versteh nicht ganz wie das funktionieren soll.

Hintergrund ist ja jener, dass ich ein Edit Fenster habe in den ich einen Begriff eingebe und er in der gesammten Tabelle sucht ob er den findet und mir dann den datensatz anzeigt.

deswegen auch die IF Anweisung wenn er was findet, soll er die tabelle filtern und wenn nicht zeigt er die message, Datensatz nicht gefunden,

Könnt ihr mir helfen, dass zu realisieren?
Ich würde es ja auch mit SQL machen aber ich habe das nicht so ganz verstanden. Mit dem Filter von ADOTable erschien es mir logisch.

Wäre cool, wenn mir das jemand erklären könnte bzw sagen könnte wie ich das in den Quelltext schrieben muss.



Benny


Fliegerbenny - Sa 08.03.08 18:11

Sorry für Doppelpost, aber wenn ich wie beschrieben mit SQL arbeite funktioniert das leider noch nicht.

Hat jemand von euch noch Ideen? Wenn ich diesen Schritt gepackt habe, ist mein Projekt um einiges weiter :)

Benny


alzaimar - So 09.03.08 20:33

Na denn....

Einfach so:


Delphi-Quelltext
1:
2:
MyTable.Filter := '(Feld1="Inhalt") or (Feld2="Inhalt") or (Feld3="Inhalt")';
MyTable.Filtered := True; // Damit schaltest Du den Filter an


Bei 'Feld1', 'Feld2' und 'Feld3' natürlich deine Feldnamen und 'Inhalt' der Text, nachdem Du suchen willst.


Fliegerbenny - Mo 10.03.08 20:11

Einfach so ist leider nicht...

bekomm beim drücken des buttons folgende fehlermeldung:

'Die Argumente sind vom falschen Typ, liegen außerhalb des Gültigkeitesbereiches oder sind miteinander unvereinbar.'

Wo ist das Problem?


Delphi-Quelltext
1:
2:
ADOTable1.Filter := '(Bezeichnung="Edit1.Text") or (ICAO="Edit1.text") or (IATA="Edit1.Text") or(Rufname="Edit1.Text") or (Land="Edit1.Text")';
        ADOTable1.Filtered := true;




Benny


alzaimar - Mo 10.03.08 20:16

Meinst Du nicht, Du solltest vielleicht zunächst ein paar Grundlagen lernen?


Fliegerbenny - Mo 10.03.08 21:00

Mir ist schon klar, dass man Dlephi nicht von heute auf morgen lernen kann aber ich bin eher ein Typ, der durch probieren rausfindet wie etwas funktioniert. Daher habe ich mich and as Projekt gesetzt, eigentlich wollte ich garnicht so tief in die Materie eindringen aber ich habe Gefallen gefunden. Ich bin mit meiner Datenbank sehr weit gekommen und nun möchte ich die letzten Schritte gern zuende bringen.

Deswegen kommen hier einige Fragen. Wie gesagt, ich hatte nicht vor Delphi bis in die Tiefen zu lernen und irgendwann Programmierer werden.


alzaimar - Mo 10.03.08 23:30

Na ja, das verstehe ich, aber mir scheint, Dir fehlen sehr viele Grundlagen.

Um was für Datentypen handelt es sich denn bei den Tabellenfeldern?

Probiere doch erstmal einen Filter mit einem Feld. Dann das nächste usw.


Fliegerbenny - Di 11.03.08 09:28

Hallo, danke für deine Hilfe ;)


Also mit einem Datenfeld funktioniert das bereits sehr gut. Ich habe mehrere Oberflächen in den gesucht wird und meistens ist es nur ein Feld was durchsucht wird. Es gibt aber auch zwei Oberflächen in denen mehrere Felder durchsucht werden sollen.

Hier mal der Ansatz für eine Spalte.


Delphi-Quelltext
1:
2:
ADOTable1.Filter := 'Bezeichnung='+ QuotedStr(Edit1.Text);
        ADOTable1.Filtered := True;


Das habe ich versucht auf mehrere aufzubauen...
Dabei kam das raus.


Delphi-Quelltext
1:
2:
ADOTable1.Filter := ('Bezeichnung='+ QuotedStr(Edit1.Text)) or ('ICAO='+ QuotedStr(Edit1.Text)) or ('IATA='+ QuotedStr(Edit1.Text)) or ('Rufname='+ QuotedStr(Edit1.Text)) or ('Land='+ QuotedStr(Edit1.Text));
        ADOTable1.Filtered := true;


Ich dachte, dass man mehrere Operationen einklammern muss. Bekomme aber noch folgende Fehlermeldung.
'Operator not applicable to this operand type'



Tut mir Leid, dass es scheinbar alles so einfache Probleme sind. Bis jetzt hat es funktioniert dieses Programm aufzubauen mit Hilfe von Tutorials, Foren und Büchern.

Würde mich trotzdem freuen, wenn ihr mir helfen könnt.

Zur Datenbank.

Es handelt sich um eine MS Access Datenbank welche mittels ADO eingefügt wurde.
Die Felddatentypen in Access sind alle auf Text eingestellt.

Benny


alzaimar - Di 11.03.08 09:34

Ein Feld nach dem anderen!

Der Fehler besagt, das Du z.B. eine Zahl mit einem Text vergleichen willst. Wenn z.B. ICAO eine Zahl ist, dann klappt

SQL-Anweisung
1:
(ICAO="foo")                    

nicht und es wird ein entsprechender Fehler angezeigt.


Fliegerbenny - Di 11.03.08 10:18

Interessant ist aber das alles Buchstaben sind. Also es bleibt alles ein Datentyp.


Ist mir echt ein Rätsel.

Wie meinst du das mit einem nach dem anderen?
Ist denn der Filter vom Aufbau her richtig?


Robert.Wachtel - Di 11.03.08 10:31

Wie user profile iconalzaimar schon ganz richtig sagte: Grundlagen! Du kannst doch nicht programmieren wollen ohne auch die einfachsten Grundlagen lernen zu wollen...

Du kannst Strings nicht mit einem logischen Oder verknüpfen und das Ergebnis dann auch noch einem String zuweisen. Das OR ist doch Teil des Filterausdrucks:


Quelltext
1:
ADOTable1.Filter := '(Bezeichnung='+ QuotedStr(Edit1.Text) + ') or (' + 'ICAO='+ QuotedStr(Edit1.Text) [...]                    


Fliegerbenny - Di 11.03.08 10:42

Es hat funktioniert!!! Ich danke euch!

Ich werde mal in Bibliothek stampfen und mir ein Grundlagen Buch besorgen ;)

DANKE

Benny


zuma - Di 11.03.08 11:14

der Filter ist meines Erachtens nicht richtig:

Versuchs mal so:
leg dir ne zwischenvariable vom Typ String an:

Quelltext
1:
var lTmpStr : String;                    


und befülle sie so:

Quelltext
1:
2:
3:
4:
lTmpStr := Format('Bezeichnung= ''%s'' or ICAO= ''%s'' or IATA= ''%s'' or Rufname= ''%s'' or Land= ''%s''', [QuotedStr(Edit1.Text)]);

ADOTable1.Filter := lTmpStr;
ADOTable1.Filtered := true;


wobei ich mir nicht sicher bin, ob das %s in doppelte Hochkomma gefaßt werden muss oder nicht (evtl. einfach mal die Hochkomma vor und nach einem %s weglassen


alzaimar - Di 11.03.08 13:32

@zuma: So isses besser:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
Const
  sFilter = '(Bezeichnung=%0:s= or (ICAO=%0:s) or (IATA=%0:s) or (Rufname=%0:s) or (Land= %0:s)';

Begin
  MyTable.Filter := Format (sFilter,[QuotedStr(Edit1.Text)]);
  MyTable.Filtered := True;
...


alzaimar - Di 11.03.08 13:37

user profile iconalzaimar hat folgendes geschrieben:
@zuma: So isses besser:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
Const
  sFilter = '(Bezeichnung=%0:s) or (ICAO=%0:s) or (IATA=%0:s) or (Rufname=%0:s) or (Land= %0:s)';

Begin
  MyTable.Filter := Format (sFilter,[QuotedStr(Edit1.Text)]);
  MyTable.Filtered := True;
...


[/edit:] Syntaxerror in Line 2[/edit]