Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi DBASE Datenbunk aktualisieren (https://www.delphipraxis.net/55539-dbase-datenbunk-aktualisieren.html)

conny drexler 22. Okt 2005 21:45

Datenbank: DBASE • Version: III oder IV • Zugriff über: über datamodule und TTable

DBASE Datenbunk aktualisieren
 
Hallo alle zusammen,

ich habe ein problem mit dem Update meiner DBASE Datenbank.
Ich kann meine Daten über asinteger zwar ändern, sie aber mitdem Post - Befehl nicht zurückschreiben. Kann mir einer sagen was ich am Quellcode ändern??
Delphi-Quellcode:
  datamodule1.Table1.Open;
  datamodule1.Table1.First;
  while not(eof(journaldatei)) do
    Begin
      init_rechnungszeile(rechnungszeile);
      read(journaldatei,rechnungszeile);
      if rechnungszeile.artikel.dispaartikel then
        Begin
          datamodule1.Table1.First;
          gefunden := false;
          repeat
            datamodule1.table1.Next;
            if datamodule1.Table1ARTIKELNUM.asfloat = rechnungszeile.artikel.Artikelnummer then
              gefunden := true;
          until (datamodule1.Table1.eof) or
            (datamodule1.Table1ARTIKELNUM.asfloat = rechnungszeile.artikel.Artikelnummer);
          if gefunden then
            Begin
              datamodule1.Table1.Edit;
              datamodule1.Table1LAGERBEST.AsFloat := datamodule1.Table1LAGERBEST.AsFloat - rechnungszeile.anzahl;
              datamodule1.Table1.Post;
            end;
        end;
    end;
  closefile(journaldatei);
  datamodule1.Table1.Close;
[edit=Sharky]Code-Tags durch Delphi-Tags ersetzt. Das ist dann besser zu lesen. Mfg, Sharky[/edit]

marabu 22. Okt 2005 22:37

Re: DBASE Datenbunk aktualisieren
 
Willkommen in der Delphi-PRAXiS, Conny.

Mir scheint du hast mehr als ein Problem, wenn ich mir deinen Code so ansehe. Du möchtest einen Lagerbestand anhand eines Bewegungs-Journals aktualisieren? Du musst nicht ständig durch die Bestandstabelle iterieren, schau dir mal die Methoden FindKey() und Locate() in der Online-Hilfe von Delphi an. Eine Artikelnummer als Float-Wert ansprechen, ob das so richtig ist? Und beim Iterieren über eine Tabelle musst du eine kopf-gesteuerte Schleife verwenden, da die Eof-Bedingung erst nach einem fruchtlosen Vorsetzen des Satzzeigers signalisiert wird. Die eigentlichen drei Zeilen zum Aktualisieren sind in Ordnung.

Freundliche Grüße vom marabu

conny drexler 22. Okt 2005 22:55

Re: DBASE Datenbunk aktualisieren
 
Hallo Marabu,

kannst du mir das ganze jetzt auch noch auf deutsch erklären????

Was meinst du mit kopfgesteuerter Schleife. Die Artikelnummer mit float geht schon in Ordnung.

Danke für eine eventuelle Überstzung

marabu 22. Okt 2005 23:07

Re: DBASE Datenbunk aktualisieren
 
Kopfgesteuert ist der deutsche Begriff, im Englischen heißt es while - aber schau dir ruhig mal FindKey() an, dann kannst du dir die Schleife sparen.

marabu

conny drexler 23. Okt 2005 07:31

Re: DBASE Datenbunk aktualisieren
 
Naja, ein Versuch wars wert, die Kopfsteuerung. leider hat es keine Änderung nach sich gezogen. Das Update funktioniert immer noch nicht. Die Werte werden zwar geändert, aber nicht in die Datenbank geschrieben. Ich habe mal den geänderten Quellcode beigefügt. vielleicht hat jemand noch ein Idee.

Delphi-Quellcode:
  assignfile(journaldatei,konfig.stammverzeichnis + '\' + konfig.arbeitsverzeichnis + '\' + journaldateiname);
  reset(journaldatei);

  datamodule1.Table1.Open;
  datamodule1.Table1.First;
  while not(eof(journaldatei)) do
    Begin
      init_rechnungszeile(rechnungszeile);
      read(journaldatei,rechnungszeile);
      if rechnungszeile.artikel.dispaartikel then
        Begin
          datamodule1.Table1.First;
          gefunden := false;
          while (not(datamodule1.Table1.Eof)) or
            (datamodule1.Table1ARTIKELNUM.asfloat = rechnungszeile.artikel.Artikelnummer) do
              Begin
                datamodule1.table1.Next;
                if datamodule1.Table1ARTIKELNUM.asfloat = rechnungszeile.artikel.Artikelnummer then
                  gefunden := true;
              end;
          if gefunden then
            Begin
              datamodule1.Table1.Edit;
              datamodule1.Table1LAGERBEST.AsFloat := datamodule1.Table1LAGERBEST.AsFloat - rechnungszeile.anzahl;
              datamodule1.Table1.Post;
            end;
        end;
    end;
  closefile(journaldatei);
  datamodule1.Table1.Close;
[edit=Sharky]Auch hier die Delphi-Tags gesetzt. Mfg, Sharky[/edit]

Union 23. Okt 2005 11:46

Re: DBASE Datenbunk aktualisieren
 
Hallo,

die ganze while Schleife kannst Du ersetzen durch
Delphi-Quellcode:
gefunden := datamodule1.Table1.Locate('ARTIKELNUM', rechnungszeile.artikel.Artikelnummer, []);
Dafür, dass kein Update erfolgt kann es mehrere Gründe geben:
  • gefunden wird niemals true, weil die Artikelnummer nicht vorhanden ist
  • rechnungszeile.artikel.dispaartikel ist false
  • rechnungszeile.anzahl ist 0
Hast Du das mal mit dem Debugger durchlaufen lassen, mit einem Breakpoint in dem Edit-Block? Kommt das Programm überhaupt an die Stelle? Welchen Wert hat rechnungszeile.anzahl?

marabu 23. Okt 2005 11:58

Re: DBASE Datenbunk aktualisieren
 
Hallo Conny,

Zitat:

Zitat von marabu
Die eigentlichen drei Zeilen zum Aktualisieren sind in Ordnung.

Du musst woanders suchen. Gibt es eine Fehlermeldung? Wenn ja, dann teile sie bitte mit. Wenn nein, wie stellst du exakt fest, dass die Änderung gemacht bzw. nicht gemacht wurde?

Nur ein Versuch deine Neugier doch noch zu wecken - wenn du bei Table1 einen Index auf ARTIKELNUM einstellst, dann geht das hier anstelle der ewigen Schleife:

Delphi-Quellcode:
...
with DataModule1.Table1 do
  if FindKey([rechnungszeile.artikel.Artikelnummer]) then
  begin
    Edit;
    FieldValues['LAGERBEST'] := rechnungszeile.anzahl;
    Post;
  end;
...
Und mit der Query-Komponente könntest du noch einfacher zum Ergebnis kommen:

Delphi-Quellcode:
...
  with LagerQuery do
  begin
    SQL.Text := 'UPDATE lager SET best = best - :anzahl WHERE artnr = :artnr';
    Params.ParamByName('artnr').Value := rechnungszeile.artikel.Artikelnummer;
    Params.ParamByName('anzahl').Value := rechnungszeile.anzahl;
    ExecSql;
  end;
...
Wobei der SQL-Text sogar nur einmal gesetzt werden müsste, da er sich ja nicht ändert. Und noch einfacher würde es, wenn die Bewegungsdaten selbst auch in einer Datanbank-Tabelle gespeichert wären...

Sonntagsgrüße vom marabu

MarkusB 23. Okt 2005 12:39

Re: DBASE Datenbunk aktualisieren
 
Moin conny drexler!

1. Ist das, die richtige Syntax???
Delphi-Quellcode:
datamodule1.Table1LAGERBEST.AsFloat
Oder sollte es so sein:

Delphi-Quellcode:
datamodule1.Table1.FieldByName('LAGERBEST').AsFloat
2.Für bessere Lesbarkeit, benutze die "with" Anweisung:
z.B. statt:

Delphi-Quellcode:
DataModule1.Table1.First;
DataModule1.Table1.Next;
DataModule1.Table1.Edit;
DataModule1.Table1.FieldByName('VORNAME').AsString := 'John';
DataModule1.Table1.Post;
schreib:

Delphi-Quellcode:
with DataModule1.Table1 do
begin
  First;
  Next;
  Edit;
      
  FieldByName('VORNAME').AsString := 'John';
  Post;       
end;
3. Falls der gesuchte Artikel im ersten Record deiner Table1 ist, dann findest du ihn nicht!
Weil:

Delphi-Quellcode:
...
datamodule1.Table1.First;       <- hier wird auf den ersten Record in der Table1 positioniert
gefunden := false;
         
while (not(datamodule1.Table1.Eof)) or
(datamodule1.Table1ARTIKELNUM.asfloat = rechnungszeile.artikel.Artikelnummer) do
Begin
  datamodule1.table1.Next;      <- hier wird der erste Record übersprungen ohne ihn zu prüfen                                           <- und "gefunden" bleibt "false"
  if datamodule1.Table1ARTIKELNUM.asfloat = rechnungszeile.artikel.Artikelnummer then
  gefunden := true;
end;       
...
4. Die Abbruchbedingung „datamodule1.Table1ARTIKELNUM.asfloat = rechnungszeile.artikel.Artikelnummer“ in der while-Schleife hat keinen Sinn. Die „while“-Schleife wird für jeden in der Table1 gefundenen Record gemacht. Und das unabhängig von Artikelnummern, weil wenn einen Record gefunden wird, ist „not EOF“ true.

Also „while not datamodule1.Table1.Eof“ ist auf dieser Stelle vollkommen ausreichend.

5. Brauchst du die Variable "gefunden" auf einer anderen Stelle in deinem Programm? Wenn nicht, dann ist sie ueberflussig:

Und statt:

Delphi-Quellcode:
Begin
  datamodule1.Table1.First;
  gefunden := false;
  while (not(datamodule1.Table1.Eof)) or
  (datamodule1.Table1ARTIKELNUM.asfloat = rechnungszeile.artikel.Artikelnummer) do
  Begin
    datamodule1.table1.Next;
    if datamodule1.Table1ARTIKELNUM.asfloat = rechnungszeile.artikel.Artikelnummer then
      gefunden := true;
    end;
    if gefunden then
    Begin
      datamodule1.Table1.Edit;
      datamodule1.Table1LAGERBEST.AsFloat := datamodule1.Table1LAGERBEST.AsFloat - rechnungszeile.anzahl;
              datamodule1.Table1.Post;
    end;
  end;
end;
Kannst du so schreiben:

Delphi-Quellcode:
Begin
datamodule1.Table1.First;
         
while (not(datamodule1.Table1.Eof)) or
(datamodule1.Table1ARTIKELNUM.asfloat = rechnungszeile.artikel.Artikelnummer) do
Begin
  datamodule1.table1.Next;
               
  if datamodule1.Table1ARTIKELNUM.asfloat = rechnungszeile.artikel.Artikelnummer then
  begin
    datamodule1.Table1.Edit;
    datamodule1.Table1LAGERBEST.AsFloat := datamodule1.Table1LAGERBEST.AsFloat - rechnungszeile.anzahl;
    datamodule1.Table1.Post;
  end;
end;
6. An deiner Stelle würde ich den Ratschlägen von marabu und Union folgen.

Viele Grüße
Markus
:gruebel:

conny drexler 23. Okt 2005 18:23

Re: DBASE Datenbunk aktualisieren
 
Zunächst mal Danke für sämtliche Hilfen.
leider hat keine davon gefruchtet. Ich habe alle möglichen Änderungen durchgespielt, aber es erfolgt einfach kein Update in der Datenbank. Es scheint fast so, als ob der Befehl Post einfach ignoriert würde.
Fehlermeldungen beim Ausführen erhalte ich keine und die Werte prüfe ich einfach indem ich den Einzelschrittmodus ausführe.

Hat jemand noch irgendeine Idee??????

marabu 23. Okt 2005 18:47

Re: DBASE Datenbunk aktualisieren
 
Ich mag es kaum glauben, was du da schreibst. Füge direkt hinter deinem Post() bitte mal Code ein, der dir die gesuchte und die gefundene Artikelnummer ausgibt:

Delphi-Quellcode:
ShowMessage(Format('artnr: %d = %s ?', [
  rechnungszeile.artikel.Artikelnummer,
  datamodule1.Table1ARTIKELNUM.AsString,
]));
marabu


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:35 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