AW: Kundenliste
Wo 8?
|
AW: Kundenliste
Beim Update ist ja noch eine where Klausel dabei, die ja auch einen Parameter hat. Das musst du natürlich auch über ein if berücksichtigen.
Deswegen sind es einmal 7 und einmal 8. im insert wird die ID ja nicht benötigt. |
AW: Kundenliste
Ich verzweifele fast: Hoffentlich ist das nicht großer Blödsinn:
Delphi-Quellcode:
Ich bin wirklich nicht sicher, ob ich das wirklich packe. Ich sitze nun schon Tage über vermutlich ein einfaches Problem.
procedure TCustomerList.SavetoDB(con: TZConnection);
var zqryMain: TZQuery; i: Integer; begin zqryMain:=TZQuery.Create(nil); try zqryMain.connection:=con; for I := 0 to Self.Count-1 do begin if self[i].ID=-1 then zqryMain.SQL.Text:='UPDATE WARENVERKAUF1 SET KDNR=:KNR, NAME =:NAM, VORNAME=:VNA, FIRMA=:FIR, PRODUKT=:PRO, ANZAHL=:ANZ, PREIS=:PRE WHERE ID=:ID'; zqryMain.Params.ParamValues['ID']:=self[i].ID; zqryMain.params.ParamValues['KNR']:=self[i].KDNR; zqryMain.params.paramValues['NAM']:=self[i].Name; zqryMain.params.paramValues['VNA']:=self[i].Vorname; zqryMain.params.ParamValues['FIR']:=self[i].Firma; zqryMain.Params.ParamValues['PRO']:=self[i].Produkt; zqryMain.Params.ParamValues['ANZ']:=self[i].Anzahl; zqryMain.params.paramValues['PRE']:=self[i].Preis; zqryMain.ExecSQL; zqryMain.params.parseSQL(zqryMain.sql.text, True); end; for I := 0 to Self.Count-1 do begin zqryMain.SQL.text:='INSERT INTO WARENVERKAUF1(KDNR,NAME,VORNAME,FIRMA,PRODUKT,ANZAHL,PREIS) VALUES(:KNR, :NAM, :VNA, :FIR, :PRO, :ANZ, :PRE)'; zqryMain.params.ParamValues['KNR']:=self[i].KDNR; zqryMain.params.paramValues['NAM']:=self[i].Name; zqryMain.params.paramValues['VNA']:=self[i].Vorname; zqryMain.params.ParamValues['FIR']:=self[i].Firma; zqryMain.Params.ParamValues['PRO']:=self[i].Produkt; zqryMain.Params.ParamValues['ANZ']:=self[i].Anzahl; zqryMain.params.paramValues['PRE']:=self[i].Preis; zqryMain.ExecSQL; zqryMain.params.parseSQL(zqryMain.sql.text, True); end; finally zqryMain.free; end; end; Es ist doch wohl eine Nummer zu groß für mich.Auch mit dieser Lösung bleibt alles, wie es war. |
AW: Kundenliste
Das sieht doch soooo schlecht gar nicht aus :) Du scheinst aber noch einen Syntaxfehler drin zu haben wenn ich es richtig überflogen habe.
Zunächst reicht eine FOR-Schleife aus. Und bei der IF-Abfrage fehlt ein BEGIN...END. Pseudocode:
Delphi-Quellcode:
FOR [...] DO BEGIN
IF ID=-1 THEN BEGIN { INSERT } END ELSE BEGIN { UPDATE } END; {else} END; {for} |
AW: Kundenliste
alles schon gar nicht schlecht.
Aber es müssen lediglich die SQL-Statements in den If-Block und das Bestücken von ID. Außer dem, das parseSQL muss vor dem Zuweisen von Werten passieren. Danach macht's keinen Sinn mehr, bzw. wirkt sich nur auf den nächsten Schleifendurchlauf aus. In etwa so:
Delphi-Quellcode:
procedure TCustomerList.SavetoDB(con: TZConnection);
var zqryMain: TZQuery; i: Integer; begin zqryMain:=TZQuery.Create(nil); try zqryMain.connection:=con; for I := 0 to Self.Count-1 do begin if self[i].ID=-1 then zqryMain.SQL.Text:='UPDATE WARENVERKAUF1 SET KDNR=:KNR, NAME =:NAM, VORNAME=:VNA, FIRMA=:FIR, PRODUKT=:PRO, ANZAHL=:ANZ, PREIS=:PRE WHERE ID=:ID' else zqryMain.SQL.text:='INSERT INTO WARENVERKAUF1(KDNR,NAME,VORNAME,FIRMA,PRODUKT,ANZAHL,PREIS) VALUES(:KNR, :NAM, :VNA, :FIR, :PRO, :ANZ, :PRE)'; zqryMain.params.parseSQL(zqryMain.sql.text, True); if self[i].ID=-1 then zqryMain.Params.ParamValues['ID']:=self[i].ID; zqryMain.params.ParamValues['KNR']:=self[i].KDNR; zqryMain.params.paramValues['NAM']:=self[i].Name; zqryMain.params.paramValues['VNA']:=self[i].Vorname; zqryMain.params.ParamValues['FIR']:=self[i].Firma; zqryMain.Params.ParamValues['PRO']:=self[i].Produkt; zqryMain.Params.ParamValues['ANZ']:=self[i].Anzahl; zqryMain.params.paramValues['PRE']:=self[i].Preis; zqryMain.ExecSQL; end; finally zqryMain.free; end; end; |
AW: Kundenliste
Moin...:P
:warn: Warum benutzt du nicht die Anweisungen (SQL, ParamByName) die du in früheren Threads gelernt hast? http://www.delphipraxis.net/192351-g...-eingeben.html Mit dem Debugger würdest du selber sehen warum manche Sachen nicht aufgerufen werden oder die Werte nicht stimmen (Breakpoints). :? Ohne Debugger ist programmieren wie den Ast eines Baumes abschneiden mit einem glatten Messer. :kotz: Damit solltest du dich VOR den Objektlisten beschäftigen.
Delphi-Quellcode:
procedure TCustomerList.SavetoDB(con: TZConnection);
var zqryMain: TZQuery; I: Integer; begin zqryMain := TZQuery.Create(nil); try zqryMain.connection := con; // Connection zuordnen for I := 0 to Self.Count - 1 do // Liste durchlaufen begin if Self[I].ID = -1 then // !!!! Das hatten wir doch schonmal ähnlich...Ist die ID jedes Objektes in der Liste > -1 ???? begin // !!! begin-end Blöcke da du erkennst was zueinander gehört...auch bei einer Anweisung macht es Sinn. zqryMain.SQL.Text := 'UPDATE WARENVERKAUF1 SET KDNR = :KNR, NAME = :NAM, VORNAME =: VNA, FIRMA = :FIR, PRODUKT = :PRO, ANZAHL = :ANZ, PREIS = :PRE WHERE ID = :ID' // Parameter nur mit ID -1 zuordnen !!! zqryMain.ParamByName('ID').AsInteger := Self[I].ID; // As... übergibt gleich den "richtigen" Typ...Value ist was für Weicheier :-), die nicht wissen welcher Wert übergeben werden soll. end else begin zqryMain.SQL.Text := 'INSERT INTO WARENVERKAUF1(KDNR,NAME,VORNAME,FIRMA,PRODUKT,ANZAHL,PREIS) VALUES(:KNR, :NAM, :VNA, :FIR, :PRO, :ANZ, :PRE)'; // keine Codevervollständigung benutzt wegen Schreibfehler (text). :-( end; // zqryMain.params.parseSQL(zqryMain.sql.text, True); // Quatsch. ??? Wo hast du das her? Ich kenne kein Beispiel wo man das parseSQL benötigt...nur im Notfalle ist es "vorhanden". // Parameter zuordnen zqryMain.ParamByName('KNR').AsString := Self[I].KDNR; zqryMain.ParamByName('NAM').AsString := Self[I].Name; zqryMain.ParamByName('VNA').AsString := Self[I].Vorname; zqryMain.ParamByName('FIR').AsString := Self[I].Firma; zqryMain.ParamByName('PRO').AsString := Self[I].Produkt; zqryMain.ParamByName('ANZ').AsInteger := Self[I].Anzahl; zqryMain.ParamByName('PRE').AsString := Self[I].Preis; // besser Typ Float // As... übergibt gleich den "richtigen" Typ...Value ist was für Weicheier :-), die nicht wissen welcher Wert übergeben werden soll. // Ausführen zqryMain.ExecSQL; end; finally zqryMain.Free; // keine Codevervollständigung benutzt wegen Schreibfehler (free). :-( end; end; |
AW: Kundenliste
vielen Dank. Habe nun die else-Bedingung auch eingefügt und so sieht nun die SaveToDB-Methode aus:
Delphi-Quellcode:
ich hoffe, dass es nun so richtig ist. Leider bleibt alles beim alten, denn weiterhin kommt nach dem Programmaufruf und dem Versuch einen Datensatz zu löschen oder zu bearbeiten die Meldung "Argument außerhalb des Bereiches" und nach dem Aufruf von LoadFromDB und bearbeiten verschieben sich die Spalten nach links (Name steht unter KDNR Vorname unter Name usw) Da muss doch irgendwo ein Fehler mit der Spaltenzuordnung sein, den ich einfach nicht finden kann.Wenn sich die ganze Sache verschoben hat, kann ich jedoch den Datensatz bearbeiten und auch löschen. Im Listview ist dann nur ID nicht mehr sichtbar und die Tabelle ist wie erwähnt nach links gerückt.
procedure TCustomerList.SavetoDB(con: TZConnection);
var zqryMain: TZQuery; i: Integer; begin zqryMain:=TZQuery.Create(nil); try zqryMain.connection:=con; for I := 0 to Self.Count-1 do begin if self[i].ID=-1 then zqryMain.SQL.Text:='UPDATE WARENVERKAUF1 SET KDNR=:KNR, NAME =:NAM, VORNAME=:VNA, FIRMA=:FIR, PRODUKT=:PRO, ANZAHL=:ANZ, PREIS=:PRE WHERE ID=:ID' else zqryMain.SQL.text:='INSERT INTO WARENVERKAUF1(KDNR,NAME,VORNAME,FIRMA,PRODUKT,ANZAHL,PREIS) VALUES(:KNR, :NAM, :VNA, :FIR, :PRO, :ANZ, :PRE)'; zqryMain.params.parseSQL(zqryMain.sql.text, True); if self[i].ID=-1 then begin zqryMain.Params.ParamValues['ID']:=self[i].ID; zqryMain.params.ParamValues['KNR']:=self[i].KDNR; zqryMain.params.paramValues['NAM']:=self[i].Name; zqryMain.params.paramValues['VNA']:=self[i].Vorname; zqryMain.params.ParamValues['FIR']:=self[i].Firma; zqryMain.Params.ParamValues['PRO']:=self[i].Produkt; zqryMain.Params.ParamValues['ANZ']:=self[i].Anzahl; zqryMain.params.paramValues['PRE']:=self[i].Preis; zqryMain.ExecSQL; end else begin zqryMain.params.ParamValues['KNR']:=self[i].KDNR; zqryMain.params.paramValues['NAM']:=self[i].Name; zqryMain.params.paramValues['VNA']:=self[i].Vorname; zqryMain.params.ParamValues['FIR']:=self[i].Firma; zqryMain.Params.ParamValues['PRO']:=self[i].Produkt; zqryMain.Params.ParamValues['ANZ']:=self[i].Anzahl; zqryMain.params.paramValues['PRE']:=self[i].Preis; zqryMain.ExecSQL; end; end; finally zqryMain.free; end; end; Bei der Suche drehe ich mich im Kreis. Ich danke Euch jedoch für Eure Geduld mit mir. Ich würde es gern doch noch packen, um dann Zeile für Zeile alles nochmals durchzugehen und daraus zu lernen. Das ist überhaupt der tiefe Sinn des ganzen. |
AW: Kundenliste
Wo genau kommt denn der Fehler? Bemüh doch mal den Debugger, dafür ist er ja da.
|
AW: Kundenliste
Müsstest du nicht nach LoadFromDB usw. auch wieder FuelleListView aufrufen. Irgendwie bin ich mir nicht sicher ob CustomerList und ListView immer sauber synchron sind. Ausserdem verstehe ich nicht, warum du die Cutomerlist einmal in der Connect-Funktion von außen füllst und dann wieder mit der LoadFromDB-Methode von innern füllst, da reicht doch eine Version.
Dann hast du öfter solche Konstrukte:
Delphi-Quellcode:
Das wäre mir alles viel zu lang zum lesen, da würde ich mit Hilfsvariablen arbeiten und dem frmCustomer ein paar Propertys spendieren, die das füllen der ganzen TEdits intern erledigen:
if lvCustomer.Selected<>nil then
begin //Über den Index kann man nun auf jedes Object in der ObjektListe zugreifen //Damit bestücken wir das Formular mit den Werten aus den Eigenschaften des Objects frmCustomer.edtKDNR.Text:=inttostr(CustomerList[lvCustomer.Selected.Index].KDNR); frmCustomer.edtName.Text:=CustomerList[lvCustomer.Selected.Index].Name; frmCustomer.edtVorname.Text:=CustomerList[lvCustomer.Selected.Index].Vorname; //... if FRMCustomer.ShowModal=mrOK then begin //Object erzeugen nicht nötig, da es bereits besteht. Zugriff also möglich //für die Übertragung der Daten aus dem Formular CustomerList[lvCustomer.Selected.Index].KDNR:=strtoint(frmCustomer.edtKDNR.Text); CustomerList[lvCustomer.Selected.Index].Name:=frmCustomer.edtName.Text; //...
Delphi-Quellcode:
Läßt sich viel schöner lesen, denke ich. Alternativ könnte man dem frmCustomer auch einfach einen kompletten TCustomer übergeben und der regelt dann alles intern selbst, dann säh das nur noch so aus (man müsste dann aber das frmCustomer aufwendiger gestalten:
var index:integer;
customer:TCustomer; begin if lvCustomer.Selected<>nil then begin index:=lvCustomer.Selected.Index; customer:=CustomerList[index]; frmCustomer.KDNR:=customer.KDNR; frmCustomer.Nachname:=Customer.Name; frmCustomer.Vorname:=Customer.Vorname; //... if FRMCustomer.ShowModal=mrOK then begin //Object erzeugen nicht nötig, da es bereits besteht. Zugriff also möglich //für die Übertragung der Daten aus dem Formular Customer.KDNR:=frmCustomer.KDNR; Customer.Name:=frmCustomer.Nachname; //...
Delphi-Quellcode:
var index:integer;
begin if lvCustomer.Selected<>nil then begin index:=lvCustomer.Selected.Index; frmCustomer.customer:=CustomerList[index]; if FRMCustomer.ShowModal=mrOK then FuelleListView; end; end; |
AW: Kundenliste
Zitat:
Also nutze bitte den Debugger um die Stelle zu finden, die diese Meldung erzeugt! Zitat:
Wenn Du an genau einem Ort (Procedure/Funktion) Deine Liste Befüllst, dann hast Du auch den Überblick was da geschieht. Zitat:
Gruß K-H |
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:19 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