AGB  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

Kundenliste

Ein Thema von EdAdvokat · begonnen am 14. Apr 2017 · letzter Beitrag vom 22. Apr 2017
Antwort Antwort
Seite 8 von 10   « Erste     678 910   
Foren-Tage 2017
DIE Konferenz für Delphi-Entwickler mit vielen Vorträgen und ganztägigen Workshops, veranstaltet u.A. von der Delphi-PRAXiS und Embarcadero.
21.-23. September 2017 in Hamburg · Mehr Infos unter forentage.de.
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
26.393 Beiträge
 
Delphi 10.2 Tokyo Enterprise
 
#71

AW: Kundenliste

  Alt 20. Apr 2017, 12:37
Nochmal ganz langsam: egal, was Du mit Deiner eigenen Liste tust, Du musst es auch in der DB tun. Das bedeutet:
- Neuer Listeneintrag -> INSERT INTO Tabelle
- Listeneintrag ändern -> UPDATE Tabelle
- Listeneintrag löschen -> DELETE FROM Tabelle

Ist doch eigentlich ganz einfach, man muss es nur tun.
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
5.551 Beiträge
 
Delphi 7 Personal
 
#72

AW: Kundenliste

  Alt 20. Apr 2017, 13:11
Wenn Du Recht hast, hast Du Recht. Aber ich vermute, daß der arme EdAdvokat Inhalt und Werkzeug nicht auseinander halten kann. Er wäre ja nicht der erste, dem das so geht.
@EdAdvokat
Dir ist mehrere Male vorgeschlagen worden, daß Du Dir ein Konzept/Schlachtplan/PAP was auch immer, erarbeiten solltest, damit Du weißt welche Baustellen Du beackern musst und Du kannst überprüfen ob Dein Programm alles hat was es benötigt.
Das Löschen von Datensätzen ist ja eigentlich kein Problem, wenn man den weiß welche. (Multiuserfähigkeit lassen wir mal außen vor)
Debuggen lernt man so en passant, das ist nicht wirklich ein Thema, wenn man weiß wofür ein Debugger gut ist, und was er leisten kann.
Also wenn Dir auffällt, daß Dein Programm etwas nicht kann/tut dann schau mal nach ob diese Fähigkeit auch in Deinem Entwurf enthalten ist. Wenn ja dann such diese Funktionalität in Deinem SourceCode, und falls Du dort etwas findest, dann überprüfst Du ob der Code korrekt ist.

Gruß
K-H
Programme gehorchen nicht Deinen Absichten
sondern Deinen Anweisungen
Do it with Delphi Programming
  Mit Zitat antworten Zitat
Jumpy

Registriert seit: 9. Dez 2010
Ort: Mönchengladbach
1.367 Beiträge
 
Delphi 6 Enterprise
 
#73

AW: Kundenliste

  Alt 20. Apr 2017, 13:38
Hallo EdAdvokat,

weil b) mMn wirklich die einfachste, weil am schnellsten umsetzbare Lösung ist zeige ich dir mal wie SaveToTB dafür zu ändern ist. Es ist nicht ideal oder effektiv, es ist nur damit es läuft.

Das Vorgehen (auf dem Papier) ist dabei wie folgt:
1) Du lädst ja die Daten aus der DB in die CustomerList. Hast du schon.
2) Dann bearbeitest du die Daten in der CustomerList oder du fügst neue hinzu oder löschst welche. Hast du schon.
3) Jetzt soll gespeichert werden, d.h. der Stand in der CustomerList soll jetzt in die DB: Dazu:
3a) Lösche einfach den kompletten Inhalt der Tabelle in der DB.
3b) Füge nun alles in der CustomerList wieder in die DB.
Beachte bei 3b) das nun nur noch Insert-Statements gebraucht werden (da die DB ja leer ist ist nichts upzudaten), aber es gibt Datensätze die bereits eine sinnvolle ID haben, die müssen mit einem anderen Statement Inserted werden

Delphi-Quellcode:
procedure TCustomerList.SavetoDB(con: TZConnection);
var
  zqryMain: TZQuery;
  i: Integer;
begin
  zqryMain:=TZQuery.Create(nil);
  try
    zqryMain.connection:=con;

    //Erst mal alles löschen:
    zqryMain.SQL.Text:='Delete From WARENVERKAUF1'; // oder heißt es 'Delete * From WARENVERKAUF1'?
    zqryMain.ExecSQL;
    
    for I:= 0 to self.Count-1 do
      begin
      if self[i].ID>-1 then //Insert-Statement für bekannte Datensätze mit sinnvoller ID
        zqryMain.SQL.text:='INSERT INTO WARENVERKAUF1(ID,KDNR,NAME,VORNAME,FIRMA,PRODUKT,ANZAHL,PREIS) ' +
                           'VALUES(:CID, :KNR, :NAM, :VNA, :FIR, :PRO, :ANZ, :PRE)';
      else //Insert Statement für wirklich neue Datensätze
        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 //Parameter ID wird nur in diesem Fall benötigt
        zqryMain.Params.ParamValues['CID']:=self[i].ID;

      //Restliche Parameter und ExecSQL wird eigentlich in beiden Fällen gleich benöigt
      //darum habe ich die Doppelung aus deinem Code mal rausgemacht (DRY).
      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;
Ralph

Geändert von Jumpy (20. Apr 2017 um 13:44 Uhr) Grund: Kommentare ergänzt
  Mit Zitat antworten Zitat
EdAdvokat

Registriert seit: 1. Mai 2016
Ort: Berlin
149 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#74

AW: Kundenliste

  Alt 20. Apr 2017, 15:06
Ralf (Jumpy) ich bin sowas von glücklich, dass es jetzt mit deinem Codevorschlag genau so funktioniert, wie ich es mir vorgestellt habe. Er tut all das, was ich zurückliegend beschrieben habe, sogar ohne zu murren.
Gestatte mir bitte einige Fragen dazu:
1.) Das Löschen aller Datensätze mit
Delphi-Quellcode:
zqryMain.SQL.Text:='Delete From WARENVERKAUF1';
    zqryMain.ExecSQL;
ist offensichtlich auf dem Desktop nicht sichtbar, da das Listview in dieser Phase nicht aktualisiert wird. Es bleiben alle Datensätze in der Tabelle und in der objectlist. Richtig?
2.) mit
Zitat:
Insert-Statement für bekannte Datensätze mit sinnvoller ID
meinst Du all jene Datensätze in der ObjectList mit ID <>-1, also die DS, die zuvor in der DB standen und die nun wieder in die DB zurückgeschrieben werden. Richtig?
3. Insert für wirklich neue Datensätze ist die Möglichkeit, die mit hinzufügen für eine ID= -1 sorgen und nun neu aufgenommen werden und dabei zugleich eine ID der DB (also <> -1 erhalten. Richtig?
4.) was bedeutet:
Delphi-Quellcode:
if self[i].ID>-1 then //Parameter ID wird nur in diesem Fall benötigt
        zqryMain.Params.ParamValues['CID']:=self[i].ID;
Parameter ID wird nur in diesem Fall benötigt. Davor gab es doch diese if-Bedingung bereits auch?
5.) Die procedure unterscheidet sich doch wesentlich von den Vorversionen, denn ein Update-Statement gibt es nun nicht nur Insert, da ja zunächst die DB völlig gelöscht wird, um dann "würdige Datensätze" und neue Datensätze aufzunehmen. Bearbeiten klappt auch, da auch in diesm Fall kein Update erforderlich ist, denn die Veränderung wird ja neu eingefügt. Das ist ja dialektisch!(3. dialektisches Grundgesetz Negation der Negation) Richtig in Bezug auf den programmtechnischen Inhalt?
6.) Wäre auch eine selektive Löschung des aktuellen Datensatzes über die Auswahl der ID= :CID möglich? Bedeutet dein Hinweis unter 3b dass die"würdigen Datensätze" trotz ID<> -1 eine völlig neue ID von der DB erhalten, die es zuvor nicht gab. Eigentlich logisch den sonst gäbe es ein Chaos.
Ich danke Dir ganz ganz herzlich, denn so hat das Programm zunächst seinen Ende gefunden und ich gehe daran alles zu kommentieren und einzuprägen.
Nochmals zu den grundsätzlichen Anmerkungen von K-H (p80286): Ich habe doch all das was Du angesprochen hast zuvor bereits formuliert, also ein "Pflichtenheft" erstellt, in dem ich dargelegt habe, was ich will und was das Programm soll und tun muss. Dann wurde Schritt für Schritt, mit Stolpern und Stürzen all das implementiert geprüft, verworfen und erneut eingefügt. Was hätte ich denn da noch darlegen sollen? Es geht darum, dass ich all das Schritt für Schritt auch so verstehe dass ich euren Hinweisen wirklich folgen kann.
Nochmals Danke für Eure Bemühungen, verbunden mit der voran geäußerten Bitte nach Tutorial-Hinweisen und int. Links. (Delphi-Starter-Tutorial bitte nicht, denn das habe ich bereits studiert und Bücher, die nun gut 15 Jahre als sind mit Stand Delphi 4 bis 7 habe ich auch, doch darin sind derartige Probleme leider überhaupt nicht enthalten.
Norbert

Geändert von EdAdvokat (20. Apr 2017 um 15:25 Uhr)
  Mit Zitat antworten Zitat
Jumpy

Registriert seit: 9. Dez 2010
Ort: Mönchengladbach
1.367 Beiträge
 
Delphi 6 Enterprise
 
#75

AW: Kundenliste

  Alt 21. Apr 2017, 09:08
Zu 1)
Es sind alle Datensätze in der ListView und in der CutomerList auf dem gleichen Stand. Es wird dann die komplette Tabelle in der DB geleert, d.h. darin sind keine Daten mehr, um dann im nächsten Schritt den kompletten Stand der CutomerList (so wie sie jetzt ist) in die DB zu schreiben.

Zu 2)
Genau. Die Datensätze, die bereits eine ID haben (ungleich -1) sollen ja auch mit dieser ID in die DB geschrieben werden, darum enthält das entsprechende Instert-Statement auch die ID und den Parameter :CID.

Zu 3)
Auch richtig. Hier hat der Datensatz noch keine ID (bzw. die ist ja -1). Daher wird beim Insert-Statement die ID weggelassen, wodurch die Datenbank automatisch eine ID vergibt.

Zu 4)
Hier habe ich nur versucht deinen Code zu verkürzen und Redundanz zu vermeiden. DRY (=Don't repeat yourself) ist so ein Programmierer Ding:

aus:
Delphi-Quellcode:
if self[i].ID>-1 then
   begin
     zqryMain.Params.ParamValues['CID']:=self[i].ID; //update
     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; //insert
     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;
wurde:
Delphi-Quellcode:
if self[i].ID>-1 then
  zqryMain.Params.ParamValues['CID']:=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;
Ist doch viel kürzer, macht aber das selbe.

Zu 5)
Richtig verstanden.

Zu 6)
Zur Wiederholung: Würdige Datensätze die bereits eine ID haben behalten diese, nur Unwürdige oder besser bisher Unbekannte bekommen eine neue ID. Genau das passiert, wie unter Zu2) und Zu3) beschrieben.

Grundsätzlich ist es natürlich auch möglich Datensätze über die ID selektiv zu löschen, aber dann muss man sich auch vorher merken, welche Datensätze das sind, und da hast du im jetzigen Stand deines Programmes keine Struktur für vorgesehen.

Schau dir nochmal in #64 meinen Vorschlag d) an. Da musst du dir mal gut überlegen (auf'm Papier) was man dazu machen müsste um das umzusetzen und wo man alles was ändern müsste. Das ist eigentlich gar nicht so viel und du solltest das schaffen können. Es würde dein Programm in der Performance - gerade beim Speichern - um einiges verbessern.
Ralph
  Mit Zitat antworten Zitat
EdAdvokat

Registriert seit: 1. Mai 2016
Ort: Berlin
149 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#76

AW: Kundenliste

  Alt 21. Apr 2017, 11:20
Danke Ralf (Jumpy). All das hat bei mir doch eine ganze Menge Licht ins Dunkele gebracht, einschließlich DRY, das kannte ich nicht und wollte aber nicht fragen. Ich habe Dein Statement verstanden. Auch glaube ich den von Dir angesprochenen Punkt d) aus #64 jetzt zu verstehen ohne dabei ins Detail zu gehen, denn das will ich erst einmal ganz allein für mich probieren.
Auch Punkt a) sehe ich jetzt etwas anders. Beim ButtonClick auf löschen den DS in der customerlist und danach auch in der DB selektiv löschen dann fülleListview und weg ist er. Das selektive Löschen mit SQL-Statement ala 'Delete * form Warenverkauf1 WHERE ID= :CID'
zu c) Will ich mal mein Verständnis darlegen: eine zweite Liste innerhalb der CustomerList einfügen statt Add Datensatz den zu löschenden Datensatz darin markieren, um ihn dann gesondert zu löschen. Dazu jedoch die alte Fassung von SaveToDB (die das löschen nicht ermöglicht hat) und dann für die
in der gesonderten Liste aufgeführten Datensätze ein Delete-Statement einfügen und weg damit aus der objectlist und dann auch aus der DB. Habe ich das so richtig verstanden?
Ich will mal so kühn sein und behaupten, ich habe #64 jetzt verstanden. (vorher war mir so, als würde jemand von mir verlangen, ich sollte japanische Verben konjuniern)
Ich werde also studieren und probieren. Ich wäre dir für eine kurze Antwort, ob ich prinzipiell richtig liege dankbar.
Norbert
  Mit Zitat antworten Zitat
Jumpy

Registriert seit: 9. Dez 2010
Ort: Mönchengladbach
1.367 Beiträge
 
Delphi 6 Enterprise
 
#77

AW: Kundenliste

  Alt 21. Apr 2017, 11:52
Punkt a) hast du glaub ich verstanden wie ich das meinte. Punkt c) Ansatzweise, drum erkläre ich den mal einfacher.

Stell dir vor in der Klasse CustomerList, die ja eine Objektlist beinhaltet, hast du noch eine weiter Liste enthalten, dass könnte z.B. nur eine einfache TStringlist sein.
Wenn du jetzt einen Datensatz Deletest in der CustomerList, gehst du erst hin und schreibst die ID des Datensatzes in die StringList, denn die ID ist ja alles, was du später zum löschen brauchst.
Dann löschst du den Datensatz/Customer aus der CustomerList und füllst die ListView neu.

Beim SaveToDB benutzt du dann die Funktion die du am Anfang hattest (ohne DRY ) mit dem Insert und Update. Anschließend gehst du dann noch die Stringliste durch und setzt für jede darin gespeicherte ID noch ein passendes DeleteStatement ab.
Ralph
  Mit Zitat antworten Zitat
EdAdvokat

Registriert seit: 1. Mai 2016
Ort: Berlin
149 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#78

AW: Kundenliste

  Alt 21. Apr 2017, 13:04
Ralf, in #44 hast Du geschrieben:
Zitat:
Du musst daher in deiner CustomerList auch die Funktion Delete der ObjektList überschreiben, damit an der Stelle der entsprechende Datensatz zusätzlich auch aus der DB gelöscht wird.
Da hast Du bereits meine späteren Qualen vorausgesagt. Aber das überschreiben der Funktion Delete in der CustomerList ist mir nicht klar, da ich dort nie eine Funktion Delete aufgenommen habe oder ist die bereits Bestandteil der objectlist oder gar der generischen List? Wie und wo sollte man sie überschreiben? In der CustomerList mit dem Ziel, den Datensatz aus der Datenbanktabelle zu löschen. Wenn das nicht zu weit führt, würde ich gern wissen was ich mir darunter vorstellen muss. (Das Überschreiben von Methoden in OOP ist mir vom Prinzip her bekannt), doch wie hast Du das hier konkret gemeint, wie zuvor beschrieben mit SQL-Statement DELETE...?
Norbert
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
5.551 Beiträge
 
Delphi 7 Personal
 
#79

AW: Kundenliste

  Alt 21. Apr 2017, 14:24
Das sollt ungefähr so sein:
Delphi-Quellcode:
type
  TMyList : Class(Tobjectlist);

  procedure Delete(idx:integer);
  
  end;

procedure TMylist.Delete(idx:integer); { lÖSCHEN DES DATENSATZES AUS DER lISTE }
begin
  if self.id>-1 then DeleteFromDB(self.id); { und aus der DB }
  inherited dELETE;
end;
Das ist nur das Prinzip!
die genaue Umsetzung ist dann Dein Problem

Gruß
K-H
Programme gehorchen nicht Deinen Absichten
sondern Deinen Anweisungen
Do it with Delphi Programming
  Mit Zitat antworten Zitat
Jumpy

Registriert seit: 9. Dez 2010
Ort: Mönchengladbach
1.367 Beiträge
 
Delphi 6 Enterprise
 
#80

AW: Kundenliste

  Alt 21. Apr 2017, 14:32
Es müsste glaub ich

Delphi-Quellcode:
if self[idx].id>-1 then DeleteFromDB(self[idx].id);
inherited Delete(idx);
sein, aber im Prinzip hat p80286 recht. Genauso hast du ja z.B. die Add oder Remove Funktion überschrieben, wenn ich deine CutomerList gerade richtig im Kopf hab.

Deine Aufgabe wäre dann natürlich noch die Prozedur DeleteFromDB(ID:String) oder so ähnlich zu schreiben.
Ralph
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es 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

Gehe zu:

Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:51 Uhr.
Powered by vBulletin® Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2017 by Daniel R. Wolf