Delphi-PRAXiS
Seite 4 von 10   « Erste     234 56     Letzte »    

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Kundenliste (https://www.delphipraxis.net/192392-kundenliste.html)

EdAdvokat 17. Apr 2017 19:07

AW: Kundenliste
 
Wo 8?

Hobbycoder 17. Apr 2017 19:17

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.

EdAdvokat 17. Apr 2017 20:04

AW: Kundenliste
 
Ich verzweifele fast: Hoffentlich ist das nicht großer Blödsinn:
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';
  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;
Ich bin wirklich nicht sicher, ob ich das wirklich packe. Ich sitze nun schon Tage über vermutlich ein einfaches Problem.
Es ist doch wohl eine Nummer zu groß für mich.Auch mit dieser Lösung bleibt alles, wie es war.

scrat1979 17. Apr 2017 22:08

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}

Hobbycoder 18. Apr 2017 07:14

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;

haentschman 18. Apr 2017 07:53

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;

EdAdvokat 18. Apr 2017 08:28

AW: Kundenliste
 
vielen Dank. Habe nun die else-Bedingung auch eingefügt und so sieht nun die SaveToDB-Methode aus:
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
   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;
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.
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.

DeddyH 18. Apr 2017 08:29

AW: Kundenliste
 
Wo genau kommt denn der Fehler? Bemüh doch mal den Debugger, dafür ist er ja da.

Jumpy 18. Apr 2017 09:56

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:
   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;
    //...
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:

Delphi-Quellcode:
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;
    //...
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:

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;

p80286 18. Apr 2017 11:01

AW: Kundenliste
 
Zitat:

Zitat von EdAdvokat (Beitrag 1368021)
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"

Diese Meldung fällt nicht vom Himmel, sondern wird von Deinem Programm Irgendwo erzeugt.
Also nutze bitte den Debugger um die Stelle zu finden, die diese Meldung erzeugt!

Zitat:

Zitat von EdAdvokat (Beitrag 1368021)
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.

da könnte man vermuten, daß die erste Spalte gar nicht mehr vorhanden ist, bzw die Inhalte der zweiten in der ersten, die der dritten in der zweiten usw. stehen.
Wenn Du an genau einem Ort (Procedure/Funktion) Deine Liste Befüllst, dann hast Du auch den Überblick was da geschieht.

Zitat:

Zitat von EdAdvokat (Beitrag 1368021)
Bei der Suche drehe ich mich im Kreis.

darum sollt Du ja dein Programm strukturieren, damit klar ist, wenn wenn ein Update fehlschlägt, daß der Fehler in der Datenbankroutinen zu finden ist, und nicht irgendwo zwischen der Routinen für die GUI.

Gruß
K-H


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:19 Uhr.
Seite 4 von 10   « Erste     234 56     Letzte »    

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