|
![]() |
|
Registriert seit: 27. Apr 2006 Ort: Gieboldehausen 167 Beiträge |
#1
Auch wenn's viele besser wissen, hier eine kleine Anleitung, um von dem üblichen File-System wegzukommen. Auch in kleinen Anwendungen macht eine einfache Datenbank durchaus Sinn und ist allemal besser. Mit dieser kleinen Anleitung will ich dem Anfänger einmal zeigen, das es gar nicht so schwierig ist, dieses Thema anzufassen. Es ist nicht so tiefgreifend, das der Stoff schwierig wird. Ich denke, die vorgeschlagenen Routinen lassen sich auch für abgeleitete Anwendungen ausbauen und manch einer wird nun die Welt der Datenbankabfragen für seine Programme entdecken.
Beginnen wir mal ganz von vorn. Als Beispiel nehme ich eine Adressdatei. Verwaltet werden soll: Vorname, Name, Strasse, PLZ, Ort, Telefon und EMail Zuerst nehmen wir ein Datenmodul. Dies bekommt man unter Menüpunkt Datei-> Neu-> Datenmodul Wir benennen nun die Form mit MyForm und das Datenmodul mit MyDaten In das Datenmodul ziehen wir eine Database und zwei Query sowie eine UpDateSQL Diese Objekte nennen wir QAdressen, QTemp für die Queries und UpAdressen für das UpdateSQL-Objekt. Diese Elemente solltet ihr im Register Datenzugriff finden. Ich hoffe, ihr könnt es nachvollziehen, denn ich arbeite mit Delphi 3 und 4, daher sind die Vorgehensweisen vielleicht schon ein wenig betagt. Aber weiter Wieder im Delphi Menü gibt es einen Punkt Datenbank -> Explorer Hier ist der BDE - Explorer, der die Möglichkeit bietet, sich einen Treiber zu schaffen Einfach unter Objekt -> neu und man erhält die Standartvorlage, einen Paradox-Treiber mit Namen Standart1. Diesen kann man überschreiben, z.B. mit MySQLData. Es wird noch der Pfad erwartet, wo die Datenbank eingerichtet wird. Na ja, Datenbank ist etwas zuviel gesagt, aber immerhin, die Zugriffe sind (fast ) dieselben... Anschließend wird der eingerichtete Treiber, wieder unter Objekt, -> speichern unter.. mit dem angegebenen Defaultwert gespeichert. Damit ist der Treiber fertig. Was nun fehlt, ist die Verbindung vom der Database in MyDaten zur Datenbank. Um dies zu erreichen, klicken wir mit der rechten Maustaste hinein und erhalten ein Formular. In der Mitte ist eine Dropdownliste, in der wir unseren Treiber wiederfinden. Links das Feld wird mit einem Alias beschreiben, wie z.B. MyConnect. Rechts das Feld bleibt frei. Nun werden aus den beiden Checkboxen die Häkchen entfernt. Fertig. Wir müssten nun im Objektinspektor der Database schon connected auf true setzen können, ohne das es Beschwerden gibt. Bevor wir nun die QAdressen parametrieren, sollten wir unserer Datenbank eine Tabelle verpassen. Wir schreiben eine kleine Procedure in MyDaten und rufen diese über die MyDatenCreate-Routine auf Hier ein Beispiel
Delphi-Quellcode:
Procedure TMyDaten.Generate_Tabelle;
Var Tabelle : TTable; Begin Tabelle:=TTable.Create(MyDaten); Tabelle.DatabaseName:='MyConnect'; Tabelle.TableName:='Adressen'; Tabelle.TableType:=ttDefault; Tabelle.Name:='Adressen'; Tabelle.FieldDefs.Clear; Tabelle.IndexDefs.Clear; if not Tabelle.exists then // geht nur ab Delphi 4, sonst weglassen und später ausklammern begin Tabelle.FieldDefs.Add('Ident',ftInteger,0,True); // ich mach mir immer einen eigenen Ident Tabelle.FieldDefs.Add('Vorname',ftString,50,False); // Tabellenfeld Vorname 50 Zeichen Tabelle.FieldDefs.Add('Name',ftString,50,False); // Tabellenfeld Name 50 Zeichen Tabelle.FieldDefs.Add('Strasse',ftString,30,False); // Tabellenfeld Strasse 30 Zeichen Tabelle.FieldDefs.Add('PLZ',ftString,6,False); // usw Tabelle.FieldDefs.Add('Ort',ftString,30,False); Tabelle.FieldDefs.Add('Telefon',ftString,30,False); Tabelle.FieldDefs.Add('EMail',ftString,30,False); Tabelle.IndexDefs.Add('', 'Ident', [ixPrimary, ixUnique]); // und setzte ihn auch als einziartig Tabelle.CreateTable; end; end; Tabelle.Free; // nicht vergessen, Speicher freigeben, Tabelle liegt nun im angegebenen Verzeichnis end; Hierbei ist wichtig, das MyDaten vor MyForm aufgerufen wird. Wir erreichen dies im Delphi-Menüe unter Optionen, indem wir bei Formularen MyDaten einfach nach oben schieben. Nun können wir unsere Tabelle an die QAdressen anbinden. Wieder die rechte Maustaste in QAdressen und den SQL-Buider aufrufen. In Datenbank kommt über die DropDown Liste der Eintrag MyConnect. Danach müßte die Tabelle Personen im Tabellenfeld sichtbar, bzw.über die DropDown Liste erreichbar sein. Diese Tabelle holen wir uns und selektieren alle Felder. Anschließend schauen wir uns die SQL an und führen diese einmal aus. Nun können wir sicher sein, das unsere QAdressen mit der Tabelle verbunden ist. Folgende Anpassung nehmen wir nun im Objektinspektor von QAdressen vor: Active Schalten wir auf true. Funktioniert ? Gut, weiter. CachedUpdate ebenfalls True und ganz unten Updateobject, da wählen wir aus der Dropdown das zugehörige SQLUpdate-Objekt, unsere UpAdressen. (dürfte nur eines drin sein, aber irgendwann sind's vielleicht mal mehr....) Ok, jetzt noch einmal mit der rechten Maustaste in UpAdressen clicken und die UpdateSQL erzeugen. Dazu muß in den Schlüsselfeldern auf der linken Seite nur der Ident, in den UpdateFeldern rechte Seite alle Einträge markiert sein. Einmal bitteschön SQL erzeugen drücken und sich die SQL's für Insert, Modify und delete einmal ansehen, fertig. Gut, wir haben eine Tabelle für Adressen. In diese möchten wir nun gern ein paar Daten schreiben. Daher wechseln wir in unsere Anwenderform und bauen die Speichern-Routine auf. Dazu muß man wissen, Der Eintrag, der gespeichert wird, ist entweder neu oder nur editiert und überarbeitet. Daher braucht man immer einen eindeutigen Schlüssel für einen neuen Datensatz und einen aktuellen Schlüssel für den editierten Datensatz. Um einen neuen Ident zu bekommen benutze ich eine temporäre Query, unsere QTemp. Dann schreibe ich eine Funktion, deren Aufgabe es ist, eine Zahl zu liefern, die um eins größer ist, als der höchste Ident in der Tabelle.
Delphi-Quellcode:
Funktion TMyForm.New_Ident(TabellenName: String):Integer; // könnte dann auch für andere Tabellen funktionieren
Var SQLSatz : String; // Ich nehme immer eine Variable zu hilfe Begin SQLSatz:='Select Ident from '+TabellenName'; //dadurch bleiben auch lange SQL's übersichtlich SQLSatz:=SQLSatz+' order by Ident'; // und natürlich nach ident sortiert MyFormDatamodule.QTemp.Close; MyFormDatamodule.QTemp.SQL.Clear; // alte SQL - Anweisung löschen MyFormDatamodule.QTemp.SQL.Add(SQLSatz); // und manchmal machts Sinn, hier nochmal zu prüfen MyFormDatamodule.QTemp.Open if MyFormDatamodule.QTemp.RecordCount>0 then begin MyFormDatamodule.QTemp.Last; // Zeiger auf letzten Datensatz Result:=MyFormDatamodule.QTemp['Ident']+1; // bedenkt, das der Ident nicht immer durchgängig ist end else Result =1; end; Nun setzen wir für jedes Tabellenfeld ein Edit-Feld und vergeben Namen Ed_Ident, ED_Vorname, Ed_Name, ED_Strasse,ED_Plz,ED_Ort,Ed_Telefon und ED_EMail ED_Ident wird auf Enabled:=False gesetzt, weil dort keine Eingaben gemacht werden darf. Zusätzlich plazieren wir ein Butten mit Namen Bt_Neu und ein Button mit Namen BT_Save und eine Combobox mit Namen CB_Namen. Mit Bt_Neu löschen wir alle Feldinhalte und rufen die Function New_Ident mit Angabe des Tabellennamens über die Zuweisung für Ed_Ident.Text auf.
Delphi-Quellcode:
procedure TMyForm.Bt_NeuClick(Sender: TObject);
begin ED_Ident.Text:=InttoStr(New_Ident('Adressen')); ED_Vorname.Text:='-'; Ed_Name.Text:='-'; ED_Strasse.Text:='-'; ED_Plz.Text:='-'; ED_Ort.Text:='-'; Ed_Telefon.Text:='-'; ED_EMail.Text:='-'; end; Das wir den Tabellennamen mitgeben, hat den Vorteil, ich kann diese Funktion auch für andere Tabellen nutzen, vorausgesetzt, mein Indexfeld ist immer gleich benannt mit 'Ident'. Anschließend füllen wir die restlichen Editfelder mit Werten. Stellt bitte sicher, das in keinem Editfeld ein Leerstring steht, manche Datenbanken mögen das gar nicht und bevor man da herumzaubert, ist es sinnvoll, in Felder mit Stringinhalten einfach '-' hineinzusetzen oder bei Zahlenwerten '0'. Dies kann wie bereits niedergeschrieben, in der Ereignisroutine der Bt_Neu geschehen. Nun kommt die Routine Speichern dran:
Delphi-Quellcode:
Wenn unsere Daten in die Editfelder eingetragen sind, können wir mit Bt_Save die Speicherroutine aufrufen.
Procedure TMyForm.Save_Adressen(Id: Integer;VName, ZName,Str,Plz,Ort,Tel,Mail:String);
Var SQLSatz: String; Begin SQLSatz:=Select * From Adressen '; // Tabellenname hier über Variable einzugeben macht keinen Sinn SQLSatz:=SQLSatz+' Where (Ident='''+IntToStr(ID)+''')'; // ich will den Eintrag mit der übergebenen ID MyFormDatamodule.QAdressen.Close; MyFormDatamodule.QAdressen.SQL.Clear; // alte SQL - Anweisung löschen MyFormDatamodule.QAdressen.SQL.Add(SQLSatz); // und manchmal machts Sinn, hier nochmal zu prüfen MyFormDatamodule.QAdressen.Open if MyFormDatamodule.QAdressen.RecordCount>0 then // ab hier ist klar, datensatz wurde editiert begin MyFormDatamodule.QAdressen.Edit; MyFormDatamodule.QAdressen['Vorname']:=VName; // Werte aus den Editfeldern.. MyFormDatamodule.QAdressen['Name']:=ZName; // meckert nicht rum, ich weiß auch elegantere Lösungen MyFormDatamodule.QAdressen['Strasse']:=Str; // ist aber für Anfänger besser, sie verstehen was da abläuft MyFormDatamodule.QAdressen['Plz']:=Plz; // und jeder kann sich seine eigenen Routinen ableiten... MyFormDatamodule.QAdressen['Ort']:=Ort; MyFormDatamodule.QAdressen['Telefon']:=Tel; MyFormDatamodule.QAdressen['EMail']:=Mail; MyFormDatamodule.UpAdressen.Apply(ukModify); // Falls unbekannt, zieht kurz eine Query in die Form // außerden ist die SQLUpdate umbenannt in UpAdressen end else Begin // hier ist ein neuer Datensatz erkannt MyFormDatamodule.QAdressen.Append; MyFormDatamodule.QAdressen['Ident']:=ID; // diese Zeile ist hier zusätzlich MyFormDatamodule.QAdressen['Vorname']:=VName; // die restlichen Zuweisungen entsprechen denen der Edit.. MyFormDatamodule.QAdressen['Name']:=ZName; MyFormDatamodule.QAdressen['Strasse']:=Str; MyFormDatamodule.QAdressen['Plz']:=Plz; MyFormDatamodule.QAdressen['Ort']:=Ort; MyFormDatamodule.QAdressen['Telefon']:=Tel; MyFormDatamodule.QAdressen['EMail']:=Mail; MyFormDatamodule.UpAdressen.Apply(ukInsert); end; end;
Delphi-Quellcode:
Natürlich sieht's ein bischen blöd aus, aber ich bin mir da sicher, es fällt euch was gescheiteres ein. Man hätte auch auf Parameter verzichten können und die Ed_xxx.Text - Felder direkt zuweisen können....
procedure TForm1.Bt_SaveClick(Sender: TObject);
begin Save_Adressen(StrToInt(Ed_Ident.Text),ED_Vorname.Text,ED_Name.Text,ED_Strasse.text, ED_Plz.Text,ED_Ort.Text,ED_Telefon.Text,Ed_EMail.Text); end; Also, ich mach es mit einem String, der die einzelnen Werte durch Semikolon getrennt in einem Rutsch rüberbringt. Innerhalb der Procedure wird er wieder zerlegt. Ist auch nicht soooo aufwändig, wie's erscheint. Aber das ist String-Bearbeitung. Da denkt selber mal drüber nach... und wenn's gar nicht klappt, na ja, dann fragt halt nach und ich schreib darüber ein separates Tutorial. So, Fehlt noch die Lese-Procedure. Wir möchten wir einzelne Datensätze aufrufen, am besten ausgewählt aus einer sortierten Namensliste. Die hatten wir ja schon eingebaut und Cb_Namen genannt. Nun gehen wir folgendermaßen vor: Wir schreiben eine Leseroutine, die nur den Namen und den Ident lädt und die Werte in die Listen einträgt. Für den Namen nehmen wir, klar, die Combobox Cb_Namen, für den Ident eine StringList mit Namen AdrIdentList. Nun kann man über Cb_Namen einen Namen selektieren und den eigentlichen Datensatz holen. Auch hier verwenden wir zum Lesen aller Namen die QTemp und wir sortieren nach Namen.
Delphi-Quellcode:
Procedure TMyForm.Load_Adressen;
Var SQLSatz : String; // Meine Stringvariable zum Aufbau der SQL-Anweisung i : Integer; // Laufzeitvariable definiere ich immer lokal Begin AdrIdentList.Clear; // diese Stringlist hier zuerst leeren CB_Namen.Items.Clear; // diese Combobox auch SQLSatz:=Select Ident, Name from Adressen '; // nur die beiden Felder Ident und Name SQLSatz:=SQLSAtz+' Order by Name'; // und sortiert nach Name MyFormDatamodule.QTemp.Close; MyFormDatamodule.QTemp.SQL.Clear; // alte SQL - Anweisung löschen MyFormDatamodule.QTemp.SQL.Add(SQLSatz); // und manchmal machts Sinn, hier nochmal zu prüfen MyFormDatamodule.QTemp.Open if MyFormDatamodule.QTemp.RecordCount>0 then begin MyFormDatamodule.QTemp.First; // Datensatzzeiger auf ersten Eintrag For i:=0 to MyFormDatamodule.QTemp.RecordCount-1 do // weil bei 0 angefangen, deshalb -1 begin AdrIdentList.Add(IntToStr(MyFormDatamodule.QTemp['Ident'])); // hier wird die Ident-Liste gefüllt Cb_Namen.Items.Add(MyFormDatamodule.QTemp['Name']); // und hier die Namen - Liste MyFormDatamodule.QTemp.Next; // Zeiger auf nächsten Datensatz end; end; end; Nun kommt noch eine Procedure, die nur einen ausgewählten Eintrag zur Anzeige bringt. Dazu nehmen wir wieder die QAdressen
Delphi-Quellcode:
Die Procedure Show_Adresse(x) rufen wir in der Ereignisroutine OnChange der Combobox auf. Dazu wissen wir, der Eintrag, den wir selektiert haben steht unter einem ItemIndex. Diesen können wir auch der Liste entnehmen und erhalten eine Integerzahl. An der gleichen Stelle steht in der AdrIdentList der Eintrag mit der Datensatznummer, dem Ident, und genau diesen brauchen wir auch wieder als Integer. Daher muß er vom String zurückgewandelt werden.
Procedure TMyForm.Show_Adresse(Id: Integer);
Var SQLSatz: String; // Meine Stringvariable zum Aufbau der SQL-Anweisung Begin SQLSatz:=Select * From Adressen '; // Tabellenname hier über Variable einzugeben macht keinen Sinn SQLSatz:=SQLSatz+' Where (Ident='''+IntToStr(ID)+''')'; // ich will den Eintrag mit der übergebenen ID MyFormDatamodule.QAdressen.Close; MyFormDatamodule.QAdressen.SQL.Clear; // alte SQL - Anweisung löschen MyFormDatamodule.QAdressen.SQL.Add(SQLSatz); // und manchmal machts Sinn, hier nochmal zu prüfen MyFormDatamodule.QAdressen.Open if MyFormDatamodule.QAdressen.RecordCount>0 then // ab hier ist klar, Daten vorhanden begin ED_Ident.Text:=IntToStr(MyFormDatamodule.QAdressen['Ident']); ED_Vorname.Text:=MyFormDatamodule.QAdressen['Vorname']; ED_Name.Text:=MyFormDatamodule.QAdressen['Name']:=ZName; ED_Str.Text:=MyFormDatamodule.QAdressen['Strasse']:=Str; ED_Plz.Text:=MyFormDatamodule.QAdressen['Plz']; ED_Ort.Text:=MyFormDatamodule.QAdressen['Ort']; ED_Tel.Text:=MyFormDatamodule.QAdressen['Telefon']; Ed_Mail.Text:=MyFormDatamodule.QAdressen['EMail']; end else begin Ed_Ident.Text:='0'; // und auch diesen Fall berücksichtigen.... ED_Vorname.Text:='-'; // das keine Daten gefunden werden ED_Name.Text:='-'; ED_Str.Text:='-'; ED_Plz.Text:=:='-'; ED_Ort.Text:='-'; ED_Tel.Text:='-'; Ed_Mail.Text:='-'; end; end; Aber so kompliziert ist das alles gar nicht, es geht in einer einzigen Zeile, das ich die Lese-Routine mit dem onChange der Combobox aufrufe;
Delphi-Quellcode:
So geht's natürlich auch unter Verwendung lokaler Variablen
procedure TMyForm.Cb_NamenChange(Sender: TObject);
begin Show_Adresse(StrToInt(AdrIdentList[CB_Namen.ItemIndex])); //geballte Ladung, kaum zu kommentieren... end;
Delphi-Quellcode:
procedure TMyForm.Cb_NamenChange(Sender: TObject);
Var ListPos : Integer; Id_String : String; DatensatzNr : Integer; begin ListPos:=CB_Namen.ItemIndex; // Position des Namens in der Liste Id_String:=AdrIdentList[ListPos]; // Inhalt aus der gleichen Position der AdrIdentList DatensatzNr:=StrToInt(Id_String); // String umwandeln in Integer Show_Adresse(DatensatzNr); // Aufruf der Laderoutine für einen den Datensatz, der zum Namen gehört end; Es macht vielleicht Sinn, die Variable DatensatzNr global zu vereinbaren, denn wenn ein Datensatz gelöscht wird, wäre diese Variable geeignet, übergeben zu werden. Bedenkt nur, das ihr beim Programmstart auch diese Variable setzt. Hier versuche ich es noch einmal zu erklären, falls es doch noch nicht verstanden ist: Show_Adresse soll einen Eintrag über Ident finden. Dieser Ident steht unter dem gleichen Index in der IdentList, wie der zugehörige Name. Und ItemIndex ist der Index, der uns den Eintrag aus der Identliste holt, allerdings als String, daher müssen wir noch diese Function StrToInt um das ganze basteln.... Ihr könnt aber auch gern lokale Variable vereinbaren und die Selektion schritt für Schritt machen. Und nicht vergessen, die Stringlist bei den globalen Variablen deklarieren und in der FormCreate generieren ! Also,
Delphi-Quellcode:
var
.......... AdrIdentList : TStringList; .........
Delphi-Quellcode:
Begin
......... AdrIdentList:=TStringlist.Create; ......... Ach ja, fast hätt ich's vergessen. Da hatt doch neulich einer eurer Freunde den gesammten Biervorrat gekillt und ihr habt euch entschlossen, diesen Schmarotzer ein für allemal aus eurer Adressliste zu strei c h e n......, nur wie ? Ok, das ist auch ganz schnell abgehakt: Schnell noch ein Button Bt_Del in eure Form und eine Procedure
Delphi-Quellcode:
Ich glaube, jetzt habt ihr einen kleinen Einstieg in Datenbankzugriffe über SQL bekommen. Ach ja, nach Speicher- und Löschaktionen solltet ihr unbedingt die Daten neu einlesen und die Listen aktualisieren.
Procedure TMyForm.Del_Eintrag(EintragNr:Integer); // EintragNr wird zur eindeutigen Identifizierung benötigt.
Var SQLSatz: String; // Meine Stringvariable zum Aufbau der SQL-Anweisung Begin SQLSatz:=Select * From Adressen '; // Tabellenname hier über Variable einzugeben macht keinen Sinn SQLSatz:=SQLSatz+' Where (Ident='''+IntToStr(ID)+''')'; // ich will den Eintrag mit der übergebenen ID MyDaten.QAdressen.Close; MyDaten.QAdressen.SQL.Clear; // alte SQL - Anweisung löschen MyDaten.QAdressen.SQL.Add(SQLSatz); // und manchmal machts Sinn, hier nochmal zu prüfen MyDaten.QAdressen.Open if MyDaten.QAdressen.RecordCount>0 then // ab hier ist klar, Datensatz vorhanden begin ..... // baut hier noch eine Sicherheitsabfrage ein. // Messagedlg ist gut geeignet If MessageDlg('soll er wirklich gehen ?',MtInformation,[mbYes,mbNo],0)=mrYes then MyDaten/.UpAdressen(ukDelete); // bevor ihr eure Freunde in die Wüste schickt..... end; end; nun noch ein Hinweis: Um über den gesamten Umfang SQL Informationen zu bekommen, ich habe mit den Microsoft Unterlagen gearbeitet Sprachverzeichnis Datenzugriff Office 95. Da steht eine ganze Menge über SQL-Zugriffe drin. Aber für ein Adressbuch sollte es erst einmal reichen. Und nun viel Spaß Gruß oldmax Ps: Wer Schreibfehler findet, der darf sie behalten...
Noch ist mein Rechner mir zu Diensten.... ansonsten habe ich die Macht ihn zu vernichten !
|
![]() |
Ansicht |
![]() |
![]() |
![]() |
ForumregelnEs ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.
BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus. Trackbacks are an
Pingbacks are an
Refbacks are aus
|
|
Nützliche Links |
Heutige Beiträge |
Sitemap |
Suchen |
Code-Library |
Wer ist online |
Alle Foren als gelesen markieren |
Gehe zu... |
LinkBack |
![]() |
![]() |