Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Letzte Rechnungsnummer um 1 hochzählen (https://www.delphipraxis.net/74353-letzte-rechnungsnummer-um-1-hochzaehlen.html)

LOMBI 1. Aug 2006 20:07

Datenbank: Paradox • Version: 7 • Zugriff über: TQuery, TDataSource

Letzte Rechnungsnummer um 1 hochzählen
 
Guten Abend,

benötige bitte Hilfe bei folgender Lösung:

Delphi-Quellcode:
TFormRechnungen.QueryRechnungenBeforeInsert(DataSet: TDataSet);
var
  letzte_nummer: Integer;
  QueryRNr: TQuery;
begin
  letzte_nummer := 0;
  QueryRNr := TQuery.Create(nil);
try
  QueryRNr.SQL.Clear;
  QueryRNr.DatabaseName := QueryRechnungen.DatabaseName;
  QueryRNr.SQL.Add('SELECT LAST(RNr) FROM Rechnungen');
  QueryRNr.Open;
  letzte_nummer : QueryRNr.Fields[0].AsInteger;
finally
  QueryRNr.Close;
  QueryRNr.Free;
  inc(letzte_nummer); // Rechnungsnummer um 1 erhöhen
  EditRNr.Text := Format('%.10d',[letzte_nummer]);
Ich möchte gerne erreichen, dass die Hochzählung generell bei der
zuletzt eingetragenen oder geänderten Rechnungsnummer startet.
Wie bitte kriege ich das hin?

Gruß
Lombi

Cyberbob 1. Aug 2006 21:12

Re: Letzte Rechnungsnummer um 1 hochzählen
 
Machs doch direjt über sql.

Ich hab in meiner SQL-Datenbank im Feld "gid" unter extras "auto_increment" stehen. Also wird bei jedem neuanlegen der wert um 1 erhöht.


Ich hoffe, ich konnte dir Helfen!

marabu 1. Aug 2006 21:19

Re: Letzte Rechnungsnummer um 1 hochzählen
 
Hallo Lombi,

dir scheinen die von Paradox mitgebrachten AutoInc-Felder nicht zu gefallen. Getippt und nicht getestet:

Delphi-Quellcode:
function NextKey(tblName, fldName: String): Integer;
begin
  with TQuery.Create(nil) do
  begin
    DatabaseName := Global.DatabaseName;
    SQL.Text := Format('SELECT MAX(%s) FROM %s', [fldName, tblName]);
    Open;
    Result := Succ(Fields[0].AsInteger);
    Close;
  end;
end;

procedure TFormRechnungen.QueryRechnungenBeforeInsert(DataSet: TDataSet);
begin
  DataSet.FieldByName('RNR').AsInteger := NextKey('RNR', 'Rechnungen');
end;
Gute Nacht

marabu

hoika 2. Aug 2006 07:26

Re: Letzte Rechnungsnummer um 1 hochzählen
 
Hallo,

Guten Morgen,

da fehlt dann noch irgendwo ein +1.


Heiko

sakura 2. Aug 2006 07:30

Re: Letzte Rechnungsnummer um 1 hochzählen
 
Zitat:

Zitat von hoika
da fehlt dann noch irgendwo ein +1.

Ist doch da
Delphi-Quellcode:
Succ(Fields[0].AsInteger);
Succ holt den Successor, also den Nachfolger (+1).

...:cat:...

hoika 2. Aug 2006 07:53

Re: Letzte Rechnungsnummer um 1 hochzählen
 
Oh ;)

*Brille putz*

Stimmt ;)

Ein prinzipielles Problem ist baer:
Was passiert aber, wenn jetzt zwei Nutzer quasi gleichzeitig
eine Rechnung erstellen.

Dann würde die Nummer doppelt eingetragen.

Hier hilft dann nur ein unique index
oder man benutzt eine Extra-Tabelle mit dem Feld "LetzteRechnzungsNr",
auf die nur einer gleichzeitig Zugriff hat.

Das Feld könnte man auch verwenden, um z.B. am Ende des Jahres
den Wert zurückzustellen.


Heiko

Peinhard 2. Aug 2006 08:12

Re: Letzte Rechnungsnummer um 1 hochzählen
 
Zitat:

Zitat von hoika
... oder man benutzt eine Extra-Tabelle mit dem Feld "LetzteRechnzungsNr",
auf die nur einer gleichzeitig Zugriff hat.

Rischtisch. 'Exclusiv' öffnen und die hochgezählte Nummer im gleichen 'Zugriffszug' auch gleich wieder eintragen. Für den Zugriff mehrere Versuche mit jeweils ein bisschen sleep() dazwischen.

XChris 2. Aug 2006 08:56

Re: Letzte Rechnungsnummer um 1 hochzählen
 
Die "Lösung" hier ist schlecht. Warum keine Transaktion? So schreibt man doch ins Blaue ...

Außerdem sollte die Rechnungsnummer auch NIE dem Datenbank PK entsprechen.

Chris

mschaefer 2. Aug 2006 09:13

Re: Letzte Rechnungsnummer um 1 hochzählen
 
Paradox hat keine Transaktionen! Spannend wird es auch noch wenn beim Ausdruck der Rechnung zufälllig der Drucker das Papier frist, Toner alle ist oder jemand die besagte Rechnungsnummer per Hand vergeben hat. Tja wie ihr seht bin ich Optimist.

//Grüße // Martin

Peinhard 2. Aug 2006 10:15

Re: Letzte Rechnungsnummer um 1 hochzählen
 
Zitat:

Zitat von XChris
Die "Lösung" hier ist schlecht. Warum keine Transaktion? So schreibt man doch ins Blaue ...

Das exklusive Öffnen simuliert gewissermaßen eine Transaktion. Während des Auslesens des letzen Wertes, des Hochzählens und des anschließenden Wiedereintrags der hochgezählten Nummer kann niemand 'dazwischenfunken', die Konsistenz der Werte ist also sichergestellt.

Zitat:

Zitat von XChris
Außerdem sollte die Rechnungsnummer auch NIE dem Datenbank PK entsprechen.

Das hat aber auch niemand ernsthaft vorgeschlagen, gei odr?

LOMBI 2. Aug 2006 13:51

Re: Letzte Rechnungsnummer um 1 hochzählen
 
Hallo
und herzlichen Dank für das gezeigte Interesse!

@ marabu

Delphi-Quellcode:
DatabaseName := Global.DatabaseName;
Hier erhalte ich die Meldung: Undefinierter Bezeichner 'Global'.
D3-Problem?

Gruß
Lombi

gmc616 2. Aug 2006 14:42

Re: Letzte Rechnungsnummer um 1 hochzählen
 
Hi,

ohne mich mit Paradox auszukennen:

Ich nehme an marabu meint mit Global das TConnection-Objekt, welches die Verbindung zur Datenbank herstellt.

Edit:

sowas wie QueryRechnungenin deinem Fall. :zwinker:

LOMBI 2. Aug 2006 16:22

Re: Letzte Rechnungsnummer um 1 hochzählen
 
Brauche ich denn überhaupt die QueryRNr oder genügt bereits
QueryRechnungen?

Gruß
Lombi

marabu 2. Aug 2006 16:29

Re: Letzte Rechnungsnummer um 1 hochzählen
 
Hallo.

Global.DatabaseName soll eine String-Konstante sein:

Delphi-Quellcode:
unit Global;

interface

const
  DatabaseName = 'DBDEMOS';

implementation

end;
Ich wusste nicht wie die Datenbank heißt ...

marabu

LOMBI 2. Aug 2006 17:49

Re: Letzte Rechnungsnummer um 1 hochzählen
 
Hallo marabu,

Delphi-Quellcode:
unit Rechnungen;

interface
.
.
.
const
DatabaseName = ...

implementation
.
.
.
uses Kunden, KundenListe;

function NextKey(tblName, fldName: String): Integer;
begin
  with TQuery.Create(nil) do
  begin
  DatabaseName := Rechnungen.DatabaseName;
  ...
Meldung: Tabelle nicht vorhanden.
Ich habe doch die Rechnungen.DatabaseName angegeben?

Lombi

mschaefer 2. Aug 2006 20:35

Re: Letzte Rechnungsnummer um 1 hochzählen
 
Bei Paradox ist Databasename die vorgeschaltete Tdatabase-Komponente.
In der Databasekomponente ist Database der der Pfad zum Datenbankverzeichnis (z.B.: 'c:\Daten\Datebank')

Grüße in die Runde // Martin

Catbytes 3. Aug 2006 09:15

Re: Letzte Rechnungsnummer um 1 hochzählen
 
Hallo,

Du kannst auch mit Nummernkreisen arbeiten.

Rechnungen = 200000 - 299999
Lieferscheine = 300000 - 399999

In einer Tabelle speicherst Du dann die Nummernkreise ab und dazu immer den letzten Wert je Belegart. Die Belegarten kannst Du auch über ein Kürzel trennen, dann kannste alles mehr oder weniger in 3 oder 4 Tabellen unterbringen, wie z.B.:

VKBelege = Belegkopf mit Anschrift, Belegart etc.
VKBelegePositionen = die einzelnen Positionen, Menge, Preis etc.
Nummernkreise = die Nummernkreise der Belegarten
Belegarten = die verschiedenen Belegarten

Wenn Du jetzt noch das Belegjahr mit dazunimmst, kannst Du die Nummernkreise auch klein halten, weil es jedes Jahr wieder von vorne beginnt. Der DB-Key muß dann natürlich über mehrere Felder eindeutig sein (Belegjahr, Belegnummer, Belegart).

Die Belegnummer setzt sich dann wie folgt zusammen: Belegjahr-Belegnummer, also z.B. 2006-123456

So sind auch abweichende Fiskaljahre finanztechnisch abgedeckt und Du weißt schon anhand der Belegnummer in welchem Zeitraum der Beleg war.

Das gleiche kannst Du auch für den Einkauf machen mit Bestellungen, Wareneingang etc. Anstatt VKBelege nennst Du die dann einfach EKBelege nach gleichem Schema.

LOMBI 4. Aug 2006 10:20

Re: Letzte Rechnungsnummer um 1 hochzählen
 
Hallo,

@marabu

Zitat:

function NextKey(tblName, fldName: String): Integer;
...
end;

procedure TFormRechnungen.QueryRechnungenBeforeInsert(DataSe t: TDataSet);
begin
DataSet.FieldByName('RNR').AsInteger := NextKey('RNR', 'Rechnungen');
end;
Entschuldigung, ich hatte mich nach NextKey in der function gerichtet
und im BeforeInsert irrtümlich NextKey('Rechnungen', 'RNr') geschrieben. Deshalb wurde zunächst die Tabelle nicht gefunden.

Schon kämpfe ich mit einem neuen Problem:

'Datenmenge weder im Editier- noch im Einfügemodus'
Delphi-Quellcode:
TFRechnungenListe.BtnNeuClick(Sender: TObject);
begin
  with FRechnungen do
    begin
      Show;
      QueryRechnungen.Append; //Einfügemodus
      QueryRechnungen.FieldByName('RNr').AsInteger :=
      StrToInt(EditRNr.Text);
      ...
      end;
In QueryRechnungen.SQL(TStrings) steht: SELECT * FROM Rechnungen

Wer hilft mir bitte?

Gruß
Lombi

marabu 4. Aug 2006 11:37

Re: Letzte Rechnungsnummer um 1 hochzählen
 
Hallo Lombi,

an deinen gezeigten Code-Zeilen kann es eigentlich nicht liegen, dass die Datenmenge sich nicht im Editiermodus befindet.

Nur am Rande - wenn die Methode BtnNeuClick() ausgelöst wird, dann ist doch deine Form FRechnungen bereits sichtbar, wieso versuchst du sie dann noch mit Show() zu zeigen? Auch solltest du in einer Methode der Form nicht auf die Formvariable Bezug nehmen:

Delphi-Quellcode:
TFRechnungenListe.BtnNeuClick(Sender: TObject);
begin
  with QueryRechnungen do
  begin
    Append; //Einfügemodus
    FieldByName('RNr').AsInteger := StrToInt(EditRNr.Text);
    // ...
  end;
end;
Grüße vom marabu

LOMBI 4. Aug 2006 16:10

Re: Letzte Rechnungsnummer um 1 hochzählen
 
Hallo marabu,

Delphi-Quellcode:
Result := Succ(Fields[0].AsInteger);
Trotz "Succ" wird RNr.Text immer mit dem gleichen Wert gespeichert und nichts hochgezählt. Woran bitte könnte das liegen?

Lombi

LOMBI 5. Aug 2006 12:16

Re: Letzte Rechnungsnummer um 1 hochzählen
 
Nachtrag:

@marabu

Zitat:

procedure TFormRechnungen.QueryRechnungenBeforeInsert(DataSe t: TDataSet);
begin
DataSet.FieldByName('RNR').AsInteger := NextKey('RNR', 'Rechnungen');
end;
Damit es funktioniert muß der Code geändert werden:

Delphi-Quellcode:
procedure TFormRechnungen.QueryRechnungenBeforInsert(DataSet: TDataSet);
begin
  EditRNr.Text := IntToStr(NextKey('RNr', 'Rechnungen'));
end;
Noch ne Frage zu SQL.Text:
Delphi-Quellcode:
SQL.Text := Format('SELECT MAX(%s) FROM %s', [fldName, tblName]);
Damit wird immer die "größte" vorhandene Rechnungsnummer hochgezählt.
Ich möchte, dass die Nr. frei wählbar bleibt, d.h. wird nach "1000"
nur "100" eingegeben, dann soll die nächste Nr. mit 101 hochgezählt
werden. Was gibt's dafür als Ersatz für "MAX"?

Gruß
Lombi

mkinzler 5. Aug 2006 12:28

Re: Letzte Rechnungsnummer um 1 hochzählen
 
Dann nimmt man aucch max schränkt aber die Ergebnismenge ein.

marabu 5. Aug 2006 12:33

Re: Letzte Rechnungsnummer um 1 hochzählen
 
Hallo Lombi,

es fällt mir erst jetzt auf, aber OnBeforeInsert() ist nicht der beste Zeitpunkt für das Zuordnen der neuen Rechnungsnummer. Probiere es mit OnBeforePost(), dann ist auch die Zuweisung an das Feld kein Problem, weil der DataSet sich nicht im Browse-Modus befindet. Du versuchst das Problem offensichtlich zu umgehen, indem du eine Zuweisung an ein Edit-Control machst.

Ich rate dir zu fortlaufenden Rechnungsnummern, welche durch dein Programm vergeben werden. Eine gleichzeitig mögliche Eingabe durch den Benutzer schafft mehr Probleme als sie löst. Der Nummernverbrauch dürfte den Vorrat nie erschöpfen, wenn du den Wertebereich für Rechnungsnummern ausreichend dimensionierst. Sollte es aus welchen Gründen auch immer Lücken geben, dann ist eine Betriebsprüfung das Letzte was du dir wünschst.

Grüße vom marabu


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