AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Kundenliste

Ein Thema von EdAdvokat · begonnen am 14. Apr 2017 · letzter Beitrag vom 22. Apr 2017
Antwort Antwort
Seite 5 von 10   « Erste     345 67     Letzte »    
EdAdvokat

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

AW: Kundenliste

  Alt 18. Apr 2017, 12:30
Das ist der Stand der Dinge:
Delphi-Quellcode:
unit UCustomerList;

interface

uses
classes, system.Types, system.SysUtils, ZAbstractRODataset, ZAbstractDataset,
ZDataset, ZAbstractConnection, ZConnection ,contnrs, System.Generics.Collections;

type
  TCustomer=class
  private
    FID: integer;
    FKDNR : Integer;
    FName: string;
    FVorname: string;
    FFirma : string;
    FProdukt: string;
    FAnzahl : Integer;
    FPreis : Currency;
    procedure SetID(const Value: Integer);
    procedure SetKDNR(const Value: Integer);
    procedure SetName(const Value: string);
    procedure SetVorname(const Value: string);
    procedure SetFirma (const Value : string);
    procedure SetProdukt(const Value : String);
    procedure SetAnzahl (const Value : Integer);
    procedure SetPreis(const Value: Currency);
  public
    constructor Create;

  published
    property ID: integer read FID write SetID;
    property KDNR: integer read FKDNr write SetKDNR;
    property Name: string read FName write SetName;
    property Vorname: string read FVorname write SetVorname;
    property Firma: string read FFirma write SetFirma;
    property Produkt: string read FProdukt write setProdukt;
    property Anzahl: Integer read FAnzahl write SetAnzahl;
    property Preis: Currency read FPreis write SetPreis;
  end;

  TCustomerList=class(TObjectList<TCustomer>)//generische Liste (contnrs, System.Generics.Collections)
    procedure LoadFromDB(con: TZConnection);
    procedure SavetoDB(con: TZConnection);
  public

    function AddCustomer(KDNR: integer; Name: string; Vorname: string; Firma: string; Produkt: string; Anzahl: Integer; Preis: Currency):integer;
  end;

implementation

  { TCustomer }

constructor TCustomer.Create;
begin
  inherited;
  self.FID:=-1;
end;

procedure TCustomer.SetAnzahl(const Value: Integer);
begin
  FAnzahl := Value;
end;

procedure TCustomer.SetFirma(const Value: string);
begin
  FFirma := Value;
end;

procedure TCustomer.SetID(const Value: Integer);
begin
  FID := Value;
end;

procedure TCustomer.SetKDNR(const Value: Integer);
begin
  FKDNR:= Value;
end;

procedure TCustomer.SetName(const Value: string);
begin
  FName := Value;
end;

procedure TCustomer.SetPreis(const Value: Currency);
begin
  FPreis := Value;
end;

procedure TCustomer.SetProdukt(const Value: String);
begin
  FProdukt := Value;
end;

procedure TCustomer.SetVorname(const Value: string);
begin
  FVorname := Value;
end;

{ TCustomerList }

function TCustomerList.AddCustomer(KDNR: integer; Name, Vorname, Firma,
  Produkt: string; Anzahl: Integer; Preis: Currency): integer;
var
  Customer: TCustomer;
begin
  Customer:=TCustomer.Create;
  Customer.KDNR:=KDNR;
  Customer.Name:=Name;
  Customer.Vorname:=Vorname;
  Customer.Firma:=Firma;
  Customer.Produkt:=Produkt;
  Customer.Anzahl:=Anzahl;
  Customer.Preis:=Preis;
  self.Add(Customer);
end;

procedure TCustomerList.LoadFromDB(con: TZConnection);
var
  zqyMain: TZQuery;
  Customer: TCustomer;
begin
  zqyMain:=TZQuery.Create(nil);
  Try
    self.Clear; //Dank TObjectlist werden auch alle bereits vorhandenen Objecte automatisch freigegeben
    zqyMain.connection:=con;
    zqyMain.sql.text:='SELECT * FROM WARENVERKAUF1';
zqyMain.active:=True;
while not zqyMain.eof do
begin
  Customer:=TCustomer.Create;
  Customer.ID:=zqyMain.FieldByName('ID').AsInteger; //
  Customer.KDNR:=zqyMain.fieldbyname('KDNR').AsInteger;
  Customer.Name:=zqyMain.fieldbyname('Name').AsString;
  Customer.Vorname:=zqyMain.fieldbyname('Vorname').AsString;
  Customer.Firma:=zqyMain.fieldByName('Firma').AsString;
  Customer.Produkt:=zqyMain.fieldbyname('Produkt').AsString;
  Customer.Anzahl:=zqyMain.FieldByName('Anzahl').AsInteger;
  Customer.Preis:=zqyMain.fieldbyname('Preis').AsCurrency;

  self.Add(Customer);
  zqyMain.Next;
end;
  zqyMain.active:=False;
Finally
  zqyMain.free;
End;
end;

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=:IDelse
     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;
end.
und das Hauptformular:
Delphi-Quellcode:
//Programm Kundenliste als ersten Versuch eine Objectlist zur Aufnahme der Daten
//für eine SQLite DB einzusetzen.
//Hilfe dazu erhielt ich aus vorangegangenen Projekten in der DP vor allem von
//Hobbycoder, Haentschmann und P80286, dennen ich hiermit nochmals danke.
//Erstellt von EdAdvokat April 2017
unit uMainFRM;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
  Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, uFRMCustomer,
  uCustomerList, Vcl.ComCtrls, Data.DB, ZAbstractRODataset, ZAbstractDataset,
  ZDataset, ZAbstractConnection, ZConnection;

type
  TFRMMainCustomer = class(TForm)
    lvCustomer: TListView;
    btnAdd: TButton;
    btnMake: TButton;
    btnDelete: TButton;
    btnAutomatic: TButton;
    btnClose: TButton;
    conMain: TZConnection;
    zqryMain: TZQuery;
    btnSaveDB: TButton;
    btnloadDB: TButton;
    edtKDNR: TEdit;
    edtName: TEdit;
    edtVorname: TEdit;
    edtFirma: TEdit;
    edtProdukt: TEdit;
    edtAnzahl: TEdit;
    edtPreis: TEdit;
    lblKDNR: TLabel;
    lblName: TLabel;
    lblVorname: TLabel;
    lblFirma: TLabel;
    lblProdukt: TLabel;
    lblAnzahl: TLabel;
    lblPreis: TLabel;
    edtTestID: TEdit;
    procedure btnAddClick(Sender: TObject);
    procedure btnMakeClick(Sender: TObject);
    procedure btnDeleteClick(Sender: TObject);
    procedure btnAutomaticClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TOBject);
    procedure btnCloseClick(Sender: TObject);
    procedure btnSaveDBClick(Sender: TObject);
    procedure btnloadDBClick(Sender: TObject);
    procedure lvCustomerClick(Sender: TObject);

  private
    { Private-Deklarationen }
    CustomerList: TCustomerList;
    procedure FuelleListView;
    procedure connect;
    procedure clearAllFields;
    procedure saveTableData(ID,KDNR,NAME,VORNAME,FIRMA,PRODUKT,ANZAHL,PREIS:string );
  public
    { Public-Deklarationen }
  end;

var
  FRMMainCustomer: TFRMMainCustomer;

implementation

{$R *.dfm}

procedure TFRMMainCustomer.btnAutomaticClick(Sender: TObject);
var
  r: integer;
  I: Integer;
  KDN, KDN1, Name, Vorname, Firma, Produkt: string;
  KDNR, Anzahl: Integer;
  Preis: Currency;
begin
  Customerlist.Clear;
  Randomize;
  for I := 0 to 999 do
  begin
    r:=Random(10);
    case r of
      0: Name:='Lehmann';
      1: Name:='Krausnig';
      2: Name:='Karlsberg';
      3: Name:='Ludwig';
      4: Name:='Antonia';
      5: Name:='Delphenhorst';
      6: Name:='Erinig';
      7: Name:='Fiedler';
      8: Name:='Gurrlig';
      9: Name:='Henzener';
    end;
    r:=Random(10);
    case r of
      0: Vorname:='Dieter';
      1: Vorname:='Klaus';
      2: Vorname:='Paul';
      3: Vorname:='Helga';
      4: Vorname:='Bernd';
      5: Vorname:='Friedel';
      6: Vorname:='Gustaf';
      7: Vorname:='Heinz';
      8: Vorname:='Joachim';
      9: Vorname:='Manfred';
    end;
    r:=Random(10);
    case r of
      0: KDN:='11';
      1: KDN:='12';
      2: KDN:='13';
      3: KDN:='14';
      4: KDN:='15';
      5: KDN:='16';
      6: KDN:='17';
      7: KDN:='18';
      8: KDN:='19';
      9: KDN:='20';
    end;
    r:=Random(10);
    case r of
      0: KDN1:='21';
      1: KDN1:='22';
      2: KDN1:='23';
      3: KDN1:='24';
      4: KDN1:='25';
      5: KDN1:='26';
      6: KDN1:='27';
      7: KDN1:='28';
      8: KDN1:='29';
      9: KDN1:='30';
    end;
    r:=Random(10);
    case r of
      0: Firma:='Schulbedarf';
      1: Firma:='Schule&mehr';
      2: Firma:='Hausmeisterserv.';
      3: Firma:='Lernen KG';
      4: Firma:='Lehrbuch Co.';
      5: Firma:='Möbel KG';
      6: Firma:='Hefte/Bücher';
      7: Firma:='Buch4you';
      8: Firma:='Lernen4all';
      9: Firma:='Bedarf Schule';
    end;
    r:=Random(10);
    case r of
      0: Produkt:='Stühle';
      1: Produkt:='Tische';
      2: Produkt:='Hefte';
      3: Produkt:='Blöcke';
      4: Produkt:='Bilder';
      5: Produkt:='Kreide';
      6: Produkt:='Bücher';
      7: Produkt:='Tafeln';
      8: Produkt:='Werkzeug';
      9: Produkt:='Mappen';
    end;
    KDNR:=strtoint(KDN[1]+KDN1[1]+format('%.6d',[i]));
    Anzahl:=Random(20);
    r:=Random(10000);
    Preis:=r/100;
    CustomerList.AddCustomer(KDNR, Name, Vorname, Firma, Produkt, Anzahl, Preis );
  end;
  FuelleListView;
end;

procedure TFRMMainCustomer.btnCloseClick(Sender: TObject);
begin
  close;
end;

procedure TFRMMainCustomer.btnAddClick(Sender: TObject);
var
  Customer: TCustomer;
begin
  //Eingabeformular mit Defaultwerten bestücken

  FRMCustomer.edtKDNR.Text:='';
  FRMCustomer.edtName.Text:='';
  FRMCustomer.edtName.Text:='';
  FRMCustomer.edtVorname.text:='';
  FRMCustomer.edtFirma.text:='';
  FrmCustomer.edtProdukt.Text:='';
  FrmCustomer.edtAnzahl.text:='';
  FRMCustomer.edtPreis.text:='';

  if frmCustomer.ShowModal=mrOK then
  begin
    Customer:=TCustomer.Create; //Das Object Customer erzeugen.
    Customer.KDNR:=strtoint(frmCustomer.edtKDNR.Text); //Customer wird befüllt
    Customer.Name:=FRMCustomer.edtName.Text;
    Customer.Vorname:=FRMCustomer.edtVorname.text;
    Customer.Firma:=FRMCustomer.edtFirma.text;
    Customer.Produkt:=FRMCustomer.edtProdukt.text;
    customer.Anzahl:=strtoint(FRMCustomer.edtAnzahl.text);
    Customer.Preis:= StrToCurr(FRMCustomer.edtPreis.Text);
    CustomerList.Add(Customer); //Übergabe an CustomerList
    FuelleListView;
  end;
end;

procedure TFRMMainCustomer.btnDeleteClick(Sender: TObject);
begin
   if lvCustomer.Selected<>nil then
  begin
    //Hier löschen wir das Object aus der ObjectListe
    //Durch die Eigenschaft OwnObjects, die zu jeder TObjectList gehört,
    //kümmert sich die ObjectListe selber darum, das entsprechende Object Customer
    //frei zugehen. Brauchen wir also nicht selber mache.
    //Ansonsten gilt grundsätzlich, was ich selber erzeuge gebe ich auch selber wieder frei
    CustomerList.Delete(lvCustomer.Selected.Index);
    FuelleListView;
  end;
end;

procedure TFRMMainCustomer.btnloadDBClick(Sender: TObject);
begin
  CustomerList.LoadFromDB(conMain);
  FuelleListView;
end;

procedure TFRMMainCustomer.btnSaveDBClick(Sender: TObject);
begin
  CustomerList.SavetoDB(conMain);
end;

procedure TFRMMainCustomer.btnMakeClick(Sender: TObject);
begin
   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;
    fRMCustomer.edtFirma.Text:=CustomerList[lvCustomer.Selected.Index].Firma;
    frmCustomer.edtProdukt.text:=CustomerList[lvCustomer.Selected.Index].Produkt;
    frmCustomer.edtAnzahl.Text:=IntToStr(Customerlist[lvCustomer.Selected.Index].Anzahl);
    frmCustomer.edtPreis.Text:=CurrToStr(Customerlist[lvCustomer.Selected.Index].Preis);

    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;
      CustomerList[lvCustomer.Selected.Index].Vorname:=FRMCustomer.edtVorname.Text;
      CustomerList[lvCustomer.Selected.Index].Firma:=FRMCustomer.edtFirma.text;
      CustomerList[lvCustomer.Selected.Index].Produkt:=FRMCustomer.edtProdukt.text;
      CustomerList[lvCustomer.Selected.Index].Anzahl:=strtoint(FRMCustomer.edtAnzahl.text);
      CustomerList[lvCustomer.Selected.Index].Preis:=strtocurr(FRMCustomer.edtPreis.Text);
      FuelleListView;
    end;
  end;
end;

procedure TFRMMainCustomer.clearAllFields;
begin
  with FRMMainCustomer do
  begin
    edtKDNR.Clear;
    edtName.Clear;
    edtVorname.Clear;
    edtFirma.Clear;
    edtProdukt.Clear;
    edtAnzahl.Clear;
    edtPreis.Clear;
  end;
end;

procedure TFRMMainCustomer.connect;
begin
  conMain.LibraryLocation:=ExtractFilePath(application.ExeName)+'sqlite3.dll';
  conMain.Database:=ExtractFilePath(application.ExeName)+'WarenVK.sqlite';
  conMain.Connected:=true;

  zqryMain.SQL.Clear;
  zqryMain.Params.Clear;

  zqryMain.SQL.Text:='SELECT * FROM WARENVERKAUF1';
  zqryMain.Open;
  while not zqryMain.Eof do
  begin
    saveTableData(zqryMain.FieldByName('ID').AsString,zqryMain.FieldByName('KDNR').AsString,zqryMain.FieldByName('Name').AsString, zqryMain.FieldByName('Vorname').AsString,zqryMain.FieldByName('Firma').AsString,zqryMain.FieldByName('Produkt').AsString,zqryMain.FieldByName('Anzahl').AsString, zqryMain.FieldByName('Preis').AsString);
    zqryMain.Next
  end;
  zqryMain.Close;
end;

procedure TFRMMainCustomer.FormCreate(Sender: TObject);
begin
  CustomerList:=TCustomerList.Create;
  connect;
  clearAllFields;
end;

procedure TFRMMainCustomer.FormDestroy(Sender: TOBject);
begin
  CustomerList.Free;
end;

procedure TFRMMainCustomer.FuelleListView;
var
  li: TListItem;
  I: Integer;
begin
  lvCustomer.Items.BeginUpdate;
  Try
    //ListView mit Daten aus der ObjectList befüllen.
    lvCustomer.Items.Clear;
    for I := 0 to CustomerList.Count-1 do
    begin
      li:=lvCustomer.Items.Add;
      li.Caption:=inttostr(CustomerList[i].ID); //
      li.SubItems.Add(inttostr(CustomerList[i].KDNR)); //
      li.SubItems.Add(CustomerList[i].Name);
      li.SubItems.Add(CustomerList[i].Vorname);
      li.SubItems.Add(CustomerList[i].Firma);
      li.SubItems.Add(CustomerList[i].Produkt);
      li.SubItems.Add(inttostr(CustomerList[i].Anzahl));
      li.SubItems.Add(FormatCurr('#0.00 €', CustomerList[i].Preis));
    end;
  Finally
    lvCustomer.Items.EndUpdate;
  End;
end;

procedure TFRMMainCustomer.lvCustomerClick(Sender: TObject);
var CurrentCustomerID : string;
begin
  if lvCustomer.SelCount>=1 then
  begin
    CurrentCustomerID:=lvCustomer.Selected.Caption; //
    zqryMain.SQL.Clear;
    zqryMain.Params.Clear;
    zqryMain.SQL.Text:='SELECT * FROM WARENVERKAUF1 WHERE ID = :CID';
    zqryMain.ParamByName('CID').AsString := CurrentCustomerID; //
    zqryMain.Open;

    edtKDNR.text:=zqryMain.FieldByName('KDNR').AsString;
    edtName.text:=zqryMain.FieldByName('Name').AsString;
    edtVorname.Text:=zqryMain.FieldByName('Vorname').AsString;
    edtFirma.text:=zqryMain.FieldByName('Firma').asstring;
    edtProdukt.text:=zqryMain.FieldByName('Produkt').AsString;
    edtAnzahl.text:=zqryMain.FieldByName('Anzahl').AsString;
    edtPreis.Text:=zqryMain.FieldByName('Preis').AsString;
    zqryMain.Next; //
    zqryMain.close;
  end;
end;

procedure TFRMMainCustomer.saveTableData(ID, KDNR, NAME, VORNAME, FIRMA, PRODUKT, ANZAHL, PREIS: string);
var item:TListItem;
begin
  Item:=lvCustomer.Items.Add;
  item.Caption:=ID;
  item.SubItems.Add(KDNR); //
  item.SubItems.Add(Name);
  item.SubItems.Add(Vorname);
  item.SubItems.Add(Firma);
  item.SubItems.Add(Produkt);
  item.SubItems.Add(Anzahl);
  item.SubItems.Add(Preis);
end;

end.
Ich habe auch das gesamte Programm in der jetzigen Fassung hochgeladen.
Mein Debuggerversuch hat ergeben, dass vermutlich in der WiniNet.dll eine Kollision mit meinem Programm auftritt. Es ist die
procedure TListHelper.Check.InsertRange, die dazu führt, dass die Meldung "Argument außerhalb des Bereiches" auftritt. Dies geschieht, wenn ich nach Programmaufruf versuche einen Datensatz zu löschen oder ihn zu bearbeiten.
Rufe ich loadfromDB auf kann ich einen Datensatz bearbeiten und löschen. Auch die Verschieberei nach links in der Anzeige ist in diesem Fall nicht mehr aufgetreten. Blöd ist jetzt nur, dass beim Aufruf von SaveToDB ein Rödeln einsetzt und sich das Programm festfährt d.h. es dauert etwa 3 Minuten bis der Speicherungsprozess beendet ist. Ob die Methode SaveToDB wirklich so ok ist, oder sind da andere Unstimmigkeiten im Wege?

Noch ein Wort zu Ralf: Danke für Deine Hinweise. Die werde ich in Ruhe ansehen, doch habe Verständnis dafür, dass ich auf diesem Gebiet so etwas von neu und unbeleckt bin, dass ich mich erst einmal darauf konzentrieren möchte, das das ganze zum vernünftigen Laufen kommt.
Vermutlich habe ich an zu vielen Stellschrauben gedreht, dass nun das Speichern in die DB wieder Probleme macht.
Den Debuggerversuch habe ich so durchgeführt, dass ich einen Haltepunkt gesetzt habe und dann die entsprechenden Handlungen im Programm selbst ausgeführt habe um dann mit F7 Schritt für Schritt weiter zu gehen. Da kam ich an dem o.g. Punkt an. Was ich daraus ableiten muss, weis ich leider nicht.
Angehängte Dateien
Dateityp: rar customerList21.rar (4,02 MB, 2x aufgerufen)
Norbert
  Mit Zitat antworten Zitat
Hobbycoder

Registriert seit: 22. Feb 2017
955 Beiträge
 
#42

AW: Kundenliste

  Alt 18. Apr 2017, 14:15
Die Sache ist auch ganz einfach.

In der procedure connect öffnest du deine Datenbank und machst das Select über die Tabelle. Dort rufst du auch die Methode saveTableData auf, die wiederum die Daten auf deinem Listview ausgibt. Fertig.
Wenn du dann über den Button Bearbeiten ein Item der ObjectList holen willst, geht das nicht, weil du da auch nie was reingeschrieben hat.
Die ist nämlich leer.

Die Vorgehensweise ist auch nicht so schlau.
Besser wäre es (ich glaube so hatte ich es dir auch gezeigt) die Daten erst mal nur in die ObjectList einzulesen. Die entsprechende Methode "AddCustomer" gibt es in der CustomerList ja schon.
Und wenn dann das Query abgearbeitet ist, also nach dem zqryMain.Close, dann mit FuelleListView den Inhalt der CustomerList in die Listview schreiben zu lassen.

Und die Krönung wäre es noch, wenn die die Query-Abfrage noch in eine Methode der CustomerList übernimmst und die Objecte auch dort anlegen lässt. Die Connection könntest du als Parameter der Methode übergeben.

Gruß Hobbycoder


[Edit]:

Grad gesehen, die Laderoutine gibt es in der CustomerList ja auch schon. Sie heißt LoadFromDB(...);
Schaut die mal in der Mainform die proceudre btnloadDBClick an. Dort machst du es richtig.
Und wenn man auf den Button "DB laden" klickt kann man auch editieren, weil dann die Customerlist auch Daten hat.

Schmeiß das ganze Query mal aus der OnCreate raus und füge statt dessen mal btnloadDBClick(self) ein. Voila...dann geht's.

In den Proceduren der Buttons Bearbeiten, Neu, löschen ... machst du es ja richtig. Und dadurch, dass du im OnCreate nur die Listview bestückt hast, hast du nicht mehr gemerkt, dass die ObjectList nicht geladen wurde.
Fehler die mach zu Anfang gerne macht. Mit der Zeit kommt die Erfahrung und solche Fehler passieren dir nicht mehr.



Im Übrigen, lass dich durch die vielen (richtigen) Hinweise nicht entmutigen. Sie sind gut gemeint. Ich würde dir aber raten erst einmal bei deinem jetzigen Code zu bleiben. Sicherlich kann man das anders auch noch schöner und besser machen. Aber wenn du jetzt anfängst alles immer wieder umzubauen, dann verwirrt dich das mehr, als alles andere. Besser, sein Ziel erst mal, wenn auch unschön, zu erreichen. Wenn es dann erst mal soweit läuft, dann entweder langsam umbauen, oder noch besser, mit dem hinzugewonnenen Wissen und der Erfahrung noch mal ganz neu aufbauen. Meine ersten Gehversuche in Delphi vor 20 Jahren sahen noch viel schlimmer aus.

Geändert von Hobbycoder (18. Apr 2017 um 14:30 Uhr)
  Mit Zitat antworten Zitat
Jumpy

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

AW: Kundenliste

  Alt 18. Apr 2017, 14:16
Bei Start des Programmes füllst du in der Connect-Funktion über SaveTableData die ListView.
Die CustomerList ist aber noch leer. Somit funktionieren die Delete und Make funktionen nicht.

(Edit: also im Prinzip das, was Hobbycode auch sagt).

Folgende Änderung reicht aber schon:

Delphi-Quellcode:
procedure TFRMMainCustomer.connect;
begin
  conMain.LibraryLocation:=ExtractFilePath(application.ExeName)+'sqlite3.dll';
  conMain.Database:=ExtractFilePath(application.ExeName)+'WarenVK.sqlite';
  conMain.Connected:=true;

  //neu
  CustomerList.LoadFromDB(conMain);
  FuelleListView;

  //alt kann weg, die ganze Fkt. SaveTableData kann mMn weg
  //zqryMain.SQL.Clear;
  //zqryMain.Params.Clear;
  //zqryMain.SQL.Text:='SELECT * FROM WARENVERKAUF1';
  //zqryMain.Open;
  //while not zqryMain.Eof do
  //begin
  //saveTableData(zqryMain.FieldByName('ID').AsString,
  // zqryMain.FieldByName('KDNR').AsString,
  // zqryMain.FieldByName('Name').AsString,
  // zqryMain.FieldByName('Vorname').AsString,
  // zqryMain.FieldByName('Firma').AsString,
  // zqryMain.FieldByName('Produkt').AsString,
  // zqryMain.FieldByName('Anzahl').AsString, zqryMain.FieldByName('Preis').AsString);
  //zqryMain.Next
  //end;
  //zqryMain.Close;
end;
Ralph
  Mit Zitat antworten Zitat
Jumpy

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

AW: Kundenliste

  Alt 18. Apr 2017, 14:21
Wenn es damit dann erstmal läuft musst du noch folgendes bedenken:

Löchst du einen Eintrag und er wird aus der ListView und der CustomerList auch entfernt, bleibt der aber weiterhin in der DB gespeichert, d.h. bei nächsten Aufruf des Programmes mit allen Daten aus der DB, ist er wieder da.
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.
Ralph
  Mit Zitat antworten Zitat
Hobbycoder

Registriert seit: 22. Feb 2017
955 Beiträge
 
#45

AW: Kundenliste

  Alt 18. Apr 2017, 15:26
Wenn es damit dann erstmal läuft musst du noch folgendes bedenken:

Löchst du einen Eintrag und er wird aus der ListView und der CustomerList auch entfernt, bleibt der aber weiterhin in der DB gespeichert, d.h. bei nächsten Aufruf des Programmes mit allen Daten aus der DB, ist er wieder da.
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.
Das hängt jetzt aber vom Ziel ab. Es könnte ja sein, dass alle Änderungen erst durch den Button "DB speichern" wirklich in die DB geschrieben werden sollen und nicht OnDemand.
Wenn er es so lässt, wie es jetzt ist, könnte er zumindest ein versehentliches Löschen durch "DB laden" schnell wieder rückgängig machen.

Ansonsten könnte man das so machen.
  Mit Zitat antworten Zitat
Jumpy

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

AW: Kundenliste

  Alt 18. Apr 2017, 15:34
Wenn es damit dann erstmal läuft musst du noch folgendes bedenken:

Löchst du einen Eintrag und er wird aus der ListView und der CustomerList auch entfernt, bleibt der aber weiterhin in der DB gespeichert, d.h. bei nächsten Aufruf des Programmes mit allen Daten aus der DB, ist er wieder da.
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.
Das hängt jetzt aber vom Ziel ab. Es könnte ja sein, dass alle Änderungen erst durch den Button "DB speichern" wirklich in die DB geschrieben werden sollen und nicht OnDemand.
Wenn er es so lässt, wie es jetzt ist, könnte er zumindest ein versehentliches Löschen durch "DB laden" schnell wieder rückgängig machen.

Ansonsten könnte man das so machen.
Dann wird es aber komplizierter, weil man dann z.B. dem Customer in der CustomerList ein Delete-Flag o.ä. verpassen müsste, ggf. mit der Folge das in der ListView weniger Einträge stehen als in der CustomerList und dann funktionieren die ganzen Index-Dinge nicht mehr,...
Ralph
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#47

AW: Kundenliste

  Alt 18. Apr 2017, 15:40
"könnte.."
Darum insistiere ich ja so auf eine Struktur. Wenn ein Datensatz gelöscht werden soll, dann[LIST=1]
[/[*]soll er nicht mehr für die Anzeige zur Verfügung stehen[*]soll er sofort aus der Datenbank gelöscht werden
LIST]
oder[LIST=1]
[/[*]soll er nicht mehr führ die Anzeige zur Verfügung stehen[*]soll er als zu löschen markiert werden und irgendwann in der DB gelöscht werden
LIST]
oder [LIST=1]
[/[*]steht er als "Prototyp" in der Anzeige zur Verfügung[*]wird er sofort in der DB gelöscht
LIST]

und noch weiter Möglichkeiten ....
Für den Anfang sollte man sich für eine Kombination entscheiden, und die dann konsequent durchziehen.
Falls sich herausstellen sollte, das das Murks ist, dann dreht man an den entsprechenden Schrauben und gut ist.

Gruß
K-H
Programme gehorchen nicht Deinen Absichten sondern Deinen Anweisungen
R.E.D retired error detector
  Mit Zitat antworten Zitat
EdAdvokat

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

AW: Kundenliste

  Alt 18. Apr 2017, 16:30
vielen Dank erst einmal. Die connect-procedure sieht nun ganz kurz so aus:
Delphi-Quellcode:
procedure TFRMMainCustomer.connect;
begin
  conMain.LibraryLocation:=ExtractFilePath(application.ExeName)+'sqlite3.dll';
  conMain.Database:=ExtractFilePath(application.ExeName)+'WarenVK.sqlite';
  conMain.Connected:=true;

  btnloadDBClick(self);
end;
Somit kann ich Hinzufügen bearbeiten und löschen. Nur das Problem mit dem Speichern besteht noch. Er speichert und speichert ohne Ende. Das ging doch zuvor. Da muss doch eine Endlosschleife aufgerufen worden sein.? Wenn das noch klappt glaube ich wäre ich am Ziel.
Norbert
  Mit Zitat antworten Zitat
EdAdvokat

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

AW: Kundenliste

  Alt 18. Apr 2017, 18:43
Habe mir nun die procedure SaveToDB vorgenommen. Wenn ich sie aufrufe speichert er unendlich lange und die Datenbank wird immer größer. Er addiert vermutlich die besthenden Datensätze bis ich das Programm gewaltsam abbreche. Habe dann gesondert nur Insert mit den entsprechenden Werten aufgerufen, mit dem gleichen Ergebnis. Zwischenzeitlich wieder eine frühere Version der DB eingespielt mit weniger Datensätzen. Auch wenn ich nur mit Update arbeite das gleiche Ergebnis, jedoch wird der neu erstellte Datensatz nicht gespeichert.
Die for i:=0 to self.count-1 do Schleife ist doch notwenig. Er holt sich doch damit die Daten aus der Objectlist und speichert sie in der Datenbank - oder? Er sollte doch bei self.count-1 aufhören.
Mit dem Versuch den Debugger anzuwerfen bin ich gescheitert. Habe auf den Beginn der Procedure SaveToDB einen Haltepunkt gesetzt und dann den Button gedrückt und das Drama nahm seinen Lauf. Er speichert und speichert bis ich ihn abwürge.Natürlich kein Ergebnis dieses Versuches. Aber vielleicht mache ich das auch falsch. Jedenfalls glaube ich noch immer dass es doch klappen sollte. Ich sehe jedoch keine weiteren Stellschrauben in diesr procedure, nachdem ich alles schon gesondert probiert habe.
Ist die Procedure wirklich richtig?
Zwischenzeitlich habe ich mir den Programmablauf auf Zettel kommentiert, um genau nachzuvollziehen was wann passiert. Leider noch nicht abschließend.
Norbert
  Mit Zitat antworten Zitat
Hobbycoder

Registriert seit: 22. Feb 2017
955 Beiträge
 
#50

AW: Kundenliste

  Alt 18. Apr 2017, 19:44
also das speichern geht bei mir wunderbar. Wenn gleich es auch sehr lange dauert.

Generell ist es natürlich besser, die veränderten Daten gleich zu speichern. Du brauchst lediglich zu dem Object TCustomer zwei Methoden zum Speichern und zum Löschen hinzufügen. Beim Speichern wieder die ID rüfen, wenn =-1 dann insert sonst update. Und in der Mainform rufst du die dann bei den Buttons passen auf.

Wenn du aber bei deiner bisherigen Form bleiben willst, dann setzt die bei gelöschten Datensätzen die ID einfach auf -2. dann kannst du in der SaveToDB auf id=-2 prüfen und statt insert bzw. update machst du dir noch einen Remove-Statement dazu. Allerdings müsstest du dann dort auch das dazugehörige Object löschen, damit du hinterher auch mit FuelleListView die Anzeige neu aufbauen kannst. Und du müsstest in der SaveToDB entweder for i:=self.count-1 downto 0 machen, oder alle Object die ID=-2 habe erst nach dem Speichern und vor dem FuelleListview löschen.

Klinkt umständlich...ist es auch. Besser wie oben und gleich speichern, löschen und hinzufügen, und danach immer FuelleListView. Das hätte auch den Vorteil, dass dein Programm auch mit mehreren Clients funktionieren könnte. Denn zur Zeit würde ein Speichern der DB immer die Änderungen überschreiben, die ein anderer User eventuell gerade gespeichert hat, oder sogar zu Datenverlust führen.
Stell dir mal vor, du und ein anderer User laden die DB an 2 Rechnern. Jetzt löscht der andere einen Datensatz und speichert.
Anschließend änderst du den gleichen Datensatz. bei dir ist ja noch in der CustomerList vorhanden. Anschließend willst du speichern. Dein SQL-Statement UPDATE kann diesen Datensatz aber nicht finden (where ID=:id) und speichert ihn dem zur Folge auch nicht. Weg isser. Und so ließen sich noch weitere Szenarien darstellen.

Geändert von Hobbycoder (18. Apr 2017 um 19:49 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 5 von 10   « Erste     345 67     Letzte »    


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:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:34 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