Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Suchfunktion in einer Datenbank (https://www.delphipraxis.net/2683-suchfunktion-einer-datenbank.html)

gabi 2. Feb 2003 16:16


Suchfunktion in einer Datenbank
 
Hallo,
ich bin noch ziemlicher Delphi-Anfänger. Jetzt habe ich eine Wissensdatenbank programmiert, das funktioniert so weit. Jetzt will ich noch eine Suchfunktion programmieren, sodass man einen Begriff eingeben kann und es zeigt sich dann der dazu gefundene Datensatz.

Der Quelltext zu dem Formular, in dem man die Datensätze eingibt und das sie dann auch anzeigen soll sieht wie folgt aus:

Code:


  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  BeschreibungForm: TBeschreibungForm;


implementation

uses Typ, Suchen;

{$R *.dfm}

procedure TBeschreibungForm.FormClose(Sender: TObject;
  var Action: TCloseAction);
begin
  Action := caFree;
end;

  //Suchfunktion
 procedure TBeschreibungForm.BtSuchenClick(Sender: TObject);
begin
  TSuchForm.Create(Self);
  {DBLookupComboBox1.Color :=clMaroon;
  DBLookupComboBox1.Font.Color := clWhite;
  DBMemoSymptom.Color :=clMaroon;
  DBMemoSymptom.Font.Color := clWhite;
  DBMemoBeschreibung.Color :=clMaroon;
  DBMemoBeschreibung.Font.Color := clWhite; }
end;

end.
Von dort wird ein Fenster geöffnet in dem der Suchbegriff eingegeben werden kann in einem Editfeld.
Jetzt wollte ich dort mit:

Code:
TBeschreibungForm.TbNrBeschr.Locate('Name','V',[loPartialKey]);
die Suchfunktion einfügen. Dies hab ich mir aus meinem Buch rausgesucht, aber irgendwie klappt das alles nicht. Außerdem soll ja auch der Text aus dem EditFeld in der Datenbank gesucht werden. Leider hilft mir mein Buch nicht sehr viel weiter.

Vielleicht kann mir hier jemand weiterhelfen.

Vorab schon mal vielen Dank

Gruß
Gabi

Blizzard 2. Feb 2003 16:35

Bin mir zwar ned 100% sicher, da ich ned deinen kompletten quelltext kenne aber ich glaub damit es funktioniert muss das mit dem locate so lauten
Code:
TBeschreibungForm.TbNrBeschr.Locate('FeldInDemGesuchtWerden Soll',EditMitSuchtext.text,[loPartialKey]);
Delphi Hilfe meint zu locate:
function Locate(const KeyFields: String; const KeyValues: Variant; Options: TLocateOptions): Boolean; override;

Bei deiner Version hätte Delphi im datenbank Feld mit der Bezeichung "Name" nach allem gesucht was ein V enthält.

MfG
Blizzard

Sharky 2. Feb 2003 17:15

Re: Suchfunktion in einer Datenbank
 
Hai gabi,

erst einmal Hallo. :party:

In deinem Quellcode suchst Du, so wie ich das sehe immer nur nach "V".

Du musst deiner Suchfunktion schon dein gesamten Suchstring übergeben.

Ach ja: Mir welcher Datenbank arbeitest Du?

gabi 2. Feb 2003 18:19

Hallo Sharky,
erst einmal Danke für Deine Hilfe.
Ich arbeite mit der Paradox-Datenbank. Ich habe das V eingesetzt gemäß meinem Beispiel aus dem Buch, weil es mir nicht gelungen ist den Text, den ich in dem EditFeld auf dem Formular SuchForm eingegeben habe, dort zu suchen. Ich will ja eigentlich keinen festen String suchen, sondern der Anwender soll einen Suchbegriff eingeben können.

Gruß
Gabi

gabi 2. Feb 2003 18:40

Suchfunktion Datenbank
 
Hallo Blizzard,

danke erst einmal für Deine Hilfe
Habe die Zeile Quellcode entsprechend geändert in:

Code:
BeschreibungForm.TbNrBeschr.Locate('DBLookupComboBox1',EdSuchen.Text,[loPartialKey]);
Jetzt beschwert sich aber der Compiler, dass loPartialKey nicht deklariert wäre. ICh dachte dass müßte ich nicht, weil es ein Parameter sei der zu locate gehört?

MfG
Gabi

MrSpock 3. Feb 2003 08:08

Hallo gabi,

herzlich willkommen bei uns im Delphi-Praxis Forum.

Nun zu deinem Code:

Zitat:

Code:
Delphi-Quellcode:
BeschreibungForm.TbNrBeschr.Locate('DBLookupComboBox1',EdSuchen.Text,[loPartialKey]);

Wenn du DBLookupComboBox1 in '' einschließt, wird das Wort DBLookupComboBox1 als Feldname interpretiert, du willst aber wahrscheinlich nach dem Feld suchen, dessen Name in der ComboBox steht, deshalb mußt du folgendes schreiben:

Delphi-Quellcode:
BeschreibungForm.TbNrBeschr.Locate(DBLookupComboBox1.Text, EdSuchen.Text, [loPartialKey]);
Der Parameter loPartialKey ist in dbTables deklariert. Falls diese Unit nicht in deiner USES Klausel steht, mußt du sie noch manuell einfügen.

gabi 3. Feb 2003 22:08

Hi MrSpock,
vorab vielen Dank für Deine Hilfe und Deinen Willkommensgruß.

Nun habe ich gemäß Deinem Tip meinen Code abgeändert, doch leider bekomme ich immer noch "nicht deklariert und es heißßt Incompatible Typ: TLocateOption an Integer. Unter uses ist aber DBTables eingetragen.

Code:
BeschreibungForm.TbNrBeschr.Locate(BeschreibungForm.DBLookupComboBox1.Text, EdSuchen.Text, [loPartialKey]);
Leider weiß ich hier nicht weiter.

Danke nochmals für Deine Hilfe

Gruß
Gabi :angle:

MrSpock 3. Feb 2003 22:39

Hallo Gabi,

das deutet darauf hin, dass loPartialKey hier falsch erkannt wird. Ich habe gerade noch einmal bei Delphi 7 nachgeschaut, da sind die TLocateOption in der Unit DB deklariert und nicht in dbTables. Daran dürfte es aber eigentlich nicht liegen. Hast du vielleicht selbst eine Variable loPartialKey als Integer deklariert? Diese würde die Sichtbarkeit von DB bzw dbTables überschreiben.

gabi 4. Feb 2003 07:01

Hallo MrSpock,
nein ich habe keine Variable loPartialKey deklariert.

Gruß
Gabi

MrSpock 4. Feb 2003 08:36

Hallo Gabi,

du könntest mir mal das Programm schicken (oder hier als Attachment anhängen), dann würde ich es mal genauer anschauen.

Die Fehlermeldung deutet wie gesagt darauf hin, dass es ein Problem mit der Option gibt.

MrSpock 4. Feb 2003 22:19

Hallo Gabi,

ich hab das Programm jetzt einmal unter D7 compiliert und die Fehlermeldung erhalten, dass loPartialKey ein unbekannter Bezeichner ist. Deshalb habe ich die Unit DB hinzugefügt:

Delphi-Quellcode:
implementation

uses Beschreibung[b], DB[/b];
Dann funktioniert es bei mir fehlerfrei.

gabi 5. Feb 2003 20:20

Hallo MrSpock,
besten Dank, wenn ich auch DB so wie von Dir angegeben hinzufüge, klappt das Compilieren. Wenn ich dann aber einen Suchbegriff eingeben und auf Start klicke, bekomme ich wieder ne Fehlermeldung Violation Access usw.
Da muss ich in der Bezeichnung des Feldes in dem ich suchen will noch nen Fehler haben, denn dort springt der Cursor hin. Muss ich mir erst mal in Ruhe anschauen. Vielleicht kannst Du das auch mal testen und bekommst auch die Fehlermeldung. Dann hast Du vielleicht wieder einen guten Tip für mich.
Ich weiß, ich kann noch nicht viel in Delphi, werde auch wenn das Programm funktioniert erst noch mal einige Übungen machen aus meinem Buch:
Borland Delphi 6 Kochbuch.

Vielen Dank und
viele Grüße
Gabi

MrSpock 5. Feb 2003 21:16

Hallo Gabi,

der Fehler ist der, dass Locate als ersten Parameter den Namen des Feldes der Tabelle benötigt, in dem gesucht werden soll. Dieser steht aber nicht in der ComboBox, deshalb geht es schief.

Noch ein paar Kommentare:

1. Du solltes als DataBaseName nicht mit relativen Pfaden arbeiten, dass kann zu Problemen führen (wir hatten dazu gerade schon einmal einen Thread). Lege einfach einen ALIAS an (z.B. "Wissen"), der auf den Pfad zeigt oder erzeuge den absoluten Pfad im Programm:

Delphi-Quellcode:
DatabaseName := ExtractFilePath(Application.Exename)+'/DB';
2. Du solltest Feldnamen in Tabellen ohne Leerzeichen und ohne Sonderzeichen (z.B. / oder Umlaute) bilden, das verhindert auch Probleme.

3. Der schwarze Hintergrund in den Fenstern ist ungewöhnlich

gabi 6. Feb 2003 00:41

Hallo MrSpock,

Danke für Deine Tips.
Habe sie folgendermaßen bearbeitet:

1. wo muss ich den Quellcode genau hinschreiben? ich nutze bewußt keinen alias um nicht immer die bde beim Anwender zu installieren, wir wollen das Programm unkompliziert im Netz laufen lassen.

2. Den Feldnamen Software/Geräte hab ich geändert in Software_Hardware und hoffe das macht keine Probleme

3. wieso siehst Du die Fenster mit schwarzem Hintergrund, der ist eigentlich blau?

Bisher hab ich noch keinen Erfolg mit der Ausführung.

Viele Grüße
Gabi

MrSpock 6. Feb 2003 09:15

Hallo Gabi,

zu 1: da du die Tabellen nicht in ein eigenes Datenmodul gepackt hast, solltest du die Zuweisung in der OnCreate Methode des Formulars einfügen, das das entsprechenden Dataset enthält.

Zu 2: Der Feldname ist OK. (_) ist erlaubt und verursacht auch keine Probleme.

Zu 3: Gute Frage!? Kann ich nicht beantworten. :|

Wie sieht denn jetzt die Locate - Anweisung aus? Hast du den korrekten Feldnamen als ersten Parameter eingetragen?

gabi 6. Feb 2003 17:48

Hallo MrSpock,

zu 1.: in dem Formular Suchen find ich keine onCreate-Methode. Soll ich die dort erstellen? dachte eigentlich das macht wenig Sinn.
Im Main Formular finde ich eine bei dem Button Beschreibung, wenn ich die Anweisung dann aber dort einsetze erhalte ich nur Fehlermeldungen.

Meine Locate-Anweisung sieht so aus:

Code:
BeschreibungForm.TbNrBeschr.Locate(BeschreibungForm.DBLookupComboBox1.Text, EdSuchen.Text, [loPartialKey]);
Habe aber auch probiert wirklich den Namen des Feldes was ich durchsuchen will aus der Tabelle zu nehmen, aber da beschwert sich Delphi wieder über reichlich undeklarierte Variablen.

Code:
BeschreibungForm.TbNrBeschr.Locate(Software_Hardware.Text, EdSuchen.Text, [loPartialKey]);
Irgendwie bekomm ich das einfach nicht hin.

Viele Grüße
Gabi

MrSpock 7. Feb 2003 07:47

Hallo Gabi,

wähle das Suchen-Formular im Objektinspektor auf und klicke auf den Reiter "Ereignisse", dort findest du in der linken Spalte das "OnCreate" Event. Führe eine Doppelklick auf die rechte Spalte neben diesem Ereignis aus. Es wird dann die OnCreate Methode erstellt, in die du den DatbaseName setzen kannst.

Die richtige Locate Anweisung lautet:

Delphi-Quellcode:
BeschreibungForm.TbNrBeschr.Locate('Software_Hardware', EdSuchen.Text, [loPartialKey]);

gabi 11. Feb 2003 22:32

Liste der Anhänge anzeigen (Anzahl: 1)
Hallo MrSpock,
habe Deine Antwort vom 07.02.2003 erst jetzt eben gesehen. Wollte nochmal was nachfragen bei Dir und da hab ich sie gesehen. Vorher war sie in der Liste nicht zu sehen und ne Mail, dass ne Antwort für mich da ist, hab ich leider auch nicht bekommen.
Deshalb melde ich mich jetzt erst.

Habe mich nach Deinen Answeisungen gerichtet, aber beim Suchen erhalte ich immer noch die Meldung: Access violation at address usw.

Ich sende Dir nochmal mein Programm, dann kannst Dir einen besseren Überblick verschaffen, was ich da verzapft habe. Da der Compiler mir gemeldet hat, dass DatabaseName undeklariert ist, nehme ich an ich muss es als String deklarieren?

Viele Grüße
Gabi

MrSpock 14. Feb 2003 20:24

Hallo Gabi,

ich hab mir das Programm noch einmal genau angeschaut und habe zunächst einmal folgende Anmerkungen:

- der Hintergrund ist bei mir schwarz, weil du die Farbe des Hintergrundes auf clBackground gesetzt hast. Ich arbeite z.B. nicht mit der Windows Standardeinstellung und habe durch meine Einstellungen einen schwarzen Hintergrund, der aber nicht als Fensterfarbe benutzt werden sollte.

- die Art und Weise, in der du MDIChilds verwendest ist unüblich. MDI Anwendungen erlauben in der Regel das Öffnen von mehreren Fenstern desselben Typs (z.B. wie ein Texverarbeitungsprogramm). Du hast aber nur 2 Fenster, die es genau einmal gibt, deshalb ist MDI keine gute Wahl.

Das Problem hängt nun auch tatsächlich indirekt an der MDI Wahl. Ein MDI Fenster wird mit dem "Create" auch gleich angezeigt. Ein normales Fenster muss über "Create" erstellt und dann z.B. über ShowModal angezeigt werden.

Das Beschreibungsfenster erstellst du z.B. über:

Delphi-Quellcode:
TBeschreibungForm.Create(Self);
Dadurch zeigt aber die Variable BeschreibungForm noch nicht auf das so erzeugte Formular. Es muss heißen:

Delphi-Quellcode:
BeschreibungForm := TBeschreibungForm.Create(Self);
Dann kann auch Suchform korrekt auf BeschreibungForm zugreifen.

Ebenso sollte SuchForm erzeugt werden über:
Delphi-Quellcode:
procedure TBeschreibungForm.BtSuchenClick(Sender: TObject);
begin
    SuchForm := TSuchForm.Create(Self);
end;
Zum Thema DatabaseName: Du musst die Eigenschaft "DatabaseName" der beiden TTable Objekte auf den gewünschten Wert setzen. Da nicht auszuschließen ist (oder doch?), dass noch Tabellen oder Queries hinzukommen, kannst du alle TDBDataSet Objekte in einer Schleife setzen:

Delphi-Quellcode:
procedure TBeschreibungForm.FormCreate(Sender: TObject);
var
   compo   : Integer;
begin
   for compo := 0 to ComponentCount-1 do
      if Components[compo] is TDBDataSet then
      begin
         (Components[compo] as TDBDataSet).DatabaseName
                        := ExtractFilePath(Application.ExeName)+'DB';
         (Components[compo] as TDBDataSet).Open;
      end;
end;
Gibt es sicher keine weiteren Tabellen tuts auch:

Delphi-Quellcode:
procedure TBeschreibungForm.FormCreate(Sender: TObject);
begin
  TbNrBeschr.DatabaseName := ExtractFilePath(Application.ExeName)+'DB';
  TbTyp.DatabaseName := ExtractFilePath(Application.ExeName)+'DB';
  TbNrBeschr.Open;
  tbTyp.Open
end;
Wichtig ist, dass du die Eigenschaft "Active" der beiden Tabellenobjekte auf FALSE setzt, sonst kannst du die Eigenschaft DatabaseName nicht setzen. Ich habe deshalb in den beiden Code Beispielen mit "open" die Tabellen geöffnet.

Noch zwei Kommentare:

- mit der DBCombobox wählst du den Wert des Eintrages für den aktuellen Datensatz aus, d.h. wenn du hier einen Wert auswählst, änderst du den aktuellen Datensatz: willst du das wirklich?

- Im Suchenfenster suchst du ja nach einem Datensatz, der im Feld "Software_Hardware" den Suchwert enthält. Beachte aber, dass in diesem Feld nur Zahlen stehen, so findest du z.B. einen Datensatz über den Suchstring "6" aber nicht über "Elfried"

Puuuhh, das solls mal erst sein. :mrgreen:

gabi 15. Feb 2003 16:44

Hallo MrSpock,

vielen, vielen Dank für Deine ausführliche Anleitung. Ich werde mir die jetzt mal intensiv zu Gemüte führen und schauen wie ich mein Programm entsprechend abändere. Diese Tips bekommt man mit den Büchern einfach nicht. Wie beispielsweise die Erzeugung von neuen Fenstern. Im Buch gibt es nur eine Beschreibung wie man es grundsätzlich macht und damit war es das. Ich find es es ganz toll, dass es Foren wie diese gibt und man dort so hervorragend geholfen bekommt.

Sobald ich weiter gekommen bin, werde ich mich wieder bei Dir melden.

Viele Grüße
Gabi

gabi 15. Feb 2003 20:48

Hallo MrSpock,
so jetzt schicke ich Dir mal meine Änderungen. Mit denen funktioniert das Programm einwandfrei.
Als Fensterfarbe habe ich jetzt nicht mehr clBackground genommen, sondern clTeal, das müßte dann doch eigentlich bei Dir genau so angezeigt werden oder?

Nochmals vielen Dank für Deine Hilfe. Da hab ich jetzt mehr gelernt als wenn ich nur allein über meinen Büchern gebrütet hätte.

Viele grüße
Gabi :dancer2:

gabi 15. Feb 2003 21:08

Liste der Anhänge anzeigen (Anzahl: 1)
..sorry jetzt hatte ich zu schnell auf absendne geklickt, deshalb hier das angekündigte Programm.

viele Grüß0e
Gabi :bounce2:

Hansa 15. Feb 2003 21:18

Hi,

ich muß halt immer dazwischenfunken. 8) Kann mir das jetzt nur kurz ansehen, aber mir fiel direkt auf, daß die Schrift ungewöhnlich groß ist, hat das einen bestimmten Grund ? Ich habe nämlich da jemanden, der mit der Nase förmlich "am Bildschirm klebt". :mrgreen:

gabi 16. Feb 2003 10:54

Hi Hansa,
bei mir ist die Schrift nicht so groß, möglicherweise liegt es daran, dass ich ne sehr hohe Bildschirmauflösung habe und Du vielleicht nur mit 800 x 600 arbeitest. Leider weiß ich nicht, wie man programmiert um zu erreichen, dass sich die Schriftgröße variabel anpasst.

Viele Grüße
Gabi :dancer2:


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:33 Uhr.

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