Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Mehrere Datensätze zwischenspeichern (https://www.delphipraxis.net/192527-mehrere-datensaetze-zwischenspeichern.html)

Luckner 26. Apr 2017 15:10

Datenbank: Firebird • Version: 2.1 • Zugriff über: Dataset

Mehrere Datensätze zwischenspeichern
 
Hallo,
programmiere eine kleine Auftragsverwaltung. Habe eine Tabelle mit Artikeln(Artikelstamm), eine Tabelle mit Hauptauftragsdaten (ID, Auftragsnr, Datum, Kunde usw.) und eine Tabelle mit mehreren Positionen in die die Artikel aus dem Artikelstamm, ggf. mit Änderungen gespeichert werden sollen. Diese Positionstabelle ist mit der Auftrags_ID bzw. Auftragsnr. mit den Hauptauftragsdaten verknüpft. Da ich nicht mit DBFeldern auf die entsprechenden Tabellen zugreife, sondern mit den Standard-Komponenten (TEdit usw.) erzeuge ich einen neuen Datensatz erst beim Speichern des Auftrages. Da ich jedoch die einzelnen Positionen des Auftrages irgendwo zwischenspeichern muss, fehlt mir jedesmal die AuftragsID, die erst nach dem Speichern des Gesamtauftrages generiert wird. Es sollen natürlich mehrere Anwender gleichzeitg Aufträge anlegen. Gibt es eine Möglichkeit eine Temporäre Tabelle(Komponente) zu erstellen und die Positionen bis dahin zwischenspeichern und nach dem Speichern des Autrages, zu leeren? Ich hoffe, dass ich mich irgendwie verständlich machen konnte.

Danke und Gruß,
Luckner

Olli73 26. Apr 2017 15:20

AW: Mehrere Datensätze zwischenspeichern
 
Du könntest alles in eine Transaktion packen und dann direkt eintragen und posten (ohne Commit!). Beim speichern machst du dann Commit, sonst Rollback.

p80286 26. Apr 2017 15:33

AW: Mehrere Datensätze zwischenspeichern
 
Wofür soll das gut sein?
Du willst einen Auftrag erstellen --> der Autragsdatensatz wird angelegt (Status:Entwurf)
Du erfasst die notwendigen Daten, hast noch ein paar Rückfragen, nach 2 Stunden werden die Auftragsdaten weggeschrieben --> (Status: Bereit)
Am nächsten Morgen kommt noch eine Ergänzung dazu (Status:Bereit) und dann schickst Du den Auftrag los (Status:Erteilt) oder aber Du löschst ihn, weil sich jemand einen Scherz mit Dir erlaubt hat (Status:Storniert)

Gruß
K-H

mkinzler 26. Apr 2017 16:59

AW: Mehrere Datensätze zwischenspeichern
 
Einfach AuftragsNr von PK trennen. Beim Anlegen wird Masterdatensatz ohne AuftragsNr erzeugt und die Positionen nicht mit der AuftragsNr sondern über dem (synthetischen) Primärschlüssel verknüpfen.

Blup 26. Apr 2017 17:01

AW: Mehrere Datensätze zwischenspeichern
 
Verknüpft werden Tabellen untereinander mit einer für den Anwender unsichtbaren ID. Die Reihenfolge IDs müssen deshalb nicht fortlaufend sein, nur eindeutig. Die ID kann man sofort erzeugen und die Auftragsdaten als Entwurf abspeichern.

Die Auftragsnummer wird erst erzeugt, wenn aus dem Entwurf ein Auftrag wird.

himitsu 26. Apr 2017 17:29

AW: Mehrere Datensätze zwischenspeichern
 
Oder CachedUpdate bei den Positionsdaten aktivieren, wenn der Hauptdatensatz noch nicht existiert.

Dann erst den Hauptdatensatz speichern,
nochmal alle Positionen durchgehen die PK eintragen
und zum Schluß das Commit der Positionen und CachedUpdate abschalten.


Alternativ:
Wir holen im AfterInsert die DefaultWerte von der DB und füllen damit das DataSet auf.
Der Benutzer sieht sofort was die DB nach dem POST als DEFAULT überall eingetratragen hätte und du hast auch sofort eine PK, auch bei mehreren Nutzern.
(nur beim Cancel bleibt dann natürlich eine Lücke in den PKs und anderen AutoInc-Feldern)

p80286 26. Apr 2017 17:57

AW: Mehrere Datensätze zwischenspeichern
 
@mkinzler @Blup
saubere Lösung, nur müßte dann irgendwann mal jemand die Auftragszombies (IDs ohne Nummer) entsorgen

Gruß
K-H

haentschman 27. Apr 2017 04:36

AW: Mehrere Datensätze zwischenspeichern
 
Moin...:P
Die Lösung sind Objekte. 8-) Die Auftragsklasse enthällt die kompletten Daten. Der Auftrag wird in einer Objektliste gehalten. Wenn der Auftrag gespeichert werden soll, werden die Daten auf die verschiedenen Tabellen aufgeteilt (in der procedure "SaveOrder") und in der DB gespeichert. :thumb: Die Löschung eines Auftragen erfolgt über die Objektliste. Die ID wird nur generiert wenn du die Order wirklich abschickst.

Nachteil: Du mußt dich von dem üblichen Datenbankzugriff (DB Controls) und der Datenhaltung in Querys trennen.

Pseudocode:
Delphi-Quellcode:
TArticle = class
  ...
end;
.
TOrder = class
private
  FArticleList: TObjectlist; // besser mit Generics: TObjectlist<TArticle>
...
public
  procedure AddArticle; // oder direkt in die Liste schreiben
end;
.
procedure SaveOrder;
begin
  // TOrder auf die Tabellen aufteilen mit mehreren SQL -> in einer Transaktion abschicken
end;

Jasocul 27. Apr 2017 06:40

AW: Mehrere Datensätze zwischenspeichern
 
Zitat:

Zitat von haentschman (Beitrag 1369237)
Die Lösung sind Objekte.

Theoretisch ja, praktisch Nein. (Natürlich ist es richtig, GUI und Daten zu trennen, aber darum geht es hier ja nicht.)
Auftrags-Positionen erfordern oft, dass Bestände reserviert werden müssen, damit andere Erfasser den Bestand nicht ins Minus fahren.
Das kann man sicher auch lösen, aber wozu? Es sind in jedem Fall DB-Zugriffe notwendig. Dann kann man auch gleich den Auftrag speichern und bastelt sich keinen Zwitter.
Abgesehen davon möchte ich nicht das Geschrei eines Anwenders sehen, der einen großen Auftrag bereits 2 Stunden erfasst und dann das Programm oder Rechner abschmiert. Alles nochmal Erfassen? Scheiß Programm :twisted:

Fortlaufende Auftragsnummern sind doch kein Problem. Stornierte Aufträge sind auch wichtige Infos (z.B. für das Qualitätsmanagement). Ansonsten kann man einen Auftrag auch einfach inhaltlich komplett wieder ändern/leeren. Dann steht die Nummer wieder zur Verfügung. Oder man lässt eine manuelle Korrektur der Auftragsnummer zu. Die Prüfung im Programm ist doch Kleinkram. Rechtlich sind fortlaufende Nummern nur für Rechnungen und Gutschriften relevant.

Hobbycoder 27. Apr 2017 07:19

AW: Mehrere Datensätze zwischenspeichern
 
Ich mache das immer so:

Da die Vorgansnummern immer fortlaufend sein soll (bei Aufträgen nicht zwangsläufig, bei Rechnungen aber definitiv) lege ich mir also eine Tabelle für die Nummernkreise an (vonNr, bisNr, istNr).
Aber eben nicht die Nummern für Rechnung, Auftrag, etc. sondern auch für Rechnungsentwurf, Auftragsentwurf, usw.
Bei erstellen eines Auftrags/Rechnung erhält dieser also erst einmal die nächste Nummer aus dem jeweiligen Entwurfsnummernkreis und erhöht dessen istNr.
Erst bei Fakturierung/Auftragerteilung wird für diesen Vorgang dann eine Nummer auf dem eigentlichen Nummernkreis gezogen und ausgetauscht.

Da die Nummernkreise aber in meinen Fällen umlaufend sind, werden die eigentlichen Datensätze / Positionen

Luckner 27. Apr 2017 10:08

AW: Mehrere Datensätze zwischenspeichern
 
Hallo an Alle,

danke für die Beiträge. Haben mir Gedanken gemacht und die Lösung von Hobbycoder finde ich passend für mich. Meine Idee ist jetzt eine zusätzliche Positionstabelle zu erstellen, die mit den aktl. Positionen gefüllt wird. Diese bekommt auch ein zusätzliches "Kennung". Das kann eine automatisch generierte Zahl sein, oder z.B. auch eine Userkennung. Wenn der Auftrag fertig ist, wird der Inhalt dieser Tabelle, selectiert nach der Kennung, in die Positionstabelle kopiert. Danach die alle Positionen mit der entsprechenden Kennung in dieser Tabelle gelöscht. So, dass jeder Anwender diese Tabelle mit der eigenen Kennung benutzen wird. Es muß nur ausgeschlossen sein, dass eine Anwender an mehreren Arbeitsplätzen gleichzeitig arbeiten kann.

Danke und Gruß,
Luckner

nahpets 27. Apr 2017 11:10

AW: Mehrere Datensätze zwischenspeichern
 
Wenn ein Nutzer (theoretisch) an mehreren Arbeitsplätzen arbeiten kann, dann kommt halt in die Nutzerkennung der Arbeitsplatz mit rein (z. B. Rechnername oder was ihr sonst so eindeutiges habt).

Frickler 27. Apr 2017 11:52

AW: Mehrere Datensätze zwischenspeichern
 
Zitat:

Zitat von haentschman (Beitrag 1369237)
Die Löschung eines Auftragen erfolgt über die Objektliste.

Was enthält denn diese famose Objektliste? Alle Aufträge? Nur die von mit neu erfassten und/oder geänderten? Alle, die ich (in dieser Sitzung) mal angeschaut habe? Wie wird die Liste synchronisiert, wenn jemand anders einen Datensatz ändert?

Jumpy 27. Apr 2017 12:09

AW: Mehrere Datensätze zwischenspeichern
 
Zitat:

Zitat von Frickler (Beitrag 1369294)
Zitat:

Zitat von haentschman (Beitrag 1369237)
Die Löschung eines Auftragen erfolgt über die Objektliste.

Was enthält denn diese famose Objektliste? Alle Aufträge? Nur die von mit neu erfassten und/oder geänderten? Alle, die ich (in dieser Sitzung) mal angeschaut habe? Wie wird die Liste synchronisiert, wenn jemand anders einen Datensatz ändert?

Ist doch egal! Ob nun Objektliste oder ClientDataset oder sonstwas. Wenn du die Daten einmal geholt hast kriegst du nicht mit wenn jemand anderes daran rumwerkelt... Es sei denn du kümmerst dich da auf irgendeine Art drum. Da ist die Objektliste nicht schlechter und nicht besser als anderes.

Hobbycoder 27. Apr 2017 13:38

AW: Mehrere Datensätze zwischenspeichern
 
Zitat:

Zitat von Luckner (Beitrag 1369279)
Hallo an Alle,

danke für die Beiträge. Haben mir Gedanken gemacht und die Lösung von Hobbycoder finde ich passend für mich. Meine Idee ist jetzt eine zusätzliche Positionstabelle zu erstellen, die mit den aktl. Positionen gefüllt wird. Diese bekommt auch ein zusätzliches "Kennung". Das kann eine automatisch generierte Zahl sein, oder z.B. auch eine Userkennung. Wenn der Auftrag fertig ist, wird der Inhalt dieser Tabelle, selectiert nach der Kennung, in die Positionstabelle kopiert. Danach die alle Positionen mit der entsprechenden Kennung in dieser Tabelle gelöscht. So, dass jeder Anwender diese Tabelle mit der eigenen Kennung benutzen wird. Es muß nur ausgeschlossen sein, dass eine Anwender an mehreren Arbeitsplätzen gleichzeitig arbeiten kann.

Danke und Gruß,
Luckner

Warum willst du das in verschiedene Tabellen halten?
Lass die Positionen doch gleich in endgültigen Tabelle, und mach dir ein Feld hinzu welches dann diese Kennung enthält, von der du spricht. Wofür brauchst du die überhaupt? Vielleicht damit die Entwürfe nur an dem einen Arbeitsplatz angezeigt werden? Dann speichere dir halt die Benutzerkennung in einem Feld ab.
Wird dann der Auftrag/Rechnung festgeschrieben, brauchst du nur die Nr austauschen und die Kennzeichen für Entwurf löschen.

Was das verhindern der Bearbeitung durch einen anderen Benutzer angeht, so mache ich das so, dass ich mir im Kopfsatz des Vorgangs eine Feld "InBearbeitung" anleget. In diesem Feld steht entweder gar nichts, dann kann jeder der Vorgang öffnen, oder der Benutzer, der ihn gerade in Bearbeitung hat. In dem Fall wird einem anderen Benutzer dann angezeigt, dass Vorgang gerade bearbeitet wird und vor allen Dingen von wem (ich hasse das, wenn Programme mir melden, dass irgendwas in Benutzung ist und ich suchen muss von wem).
beim Öffnen des Vorgang den Benutzer eintragen und hinterher wieder löschen.
Beim Beenden werden für den Fall der Fälle alle Datensätze des Benutzers freigegeben und bei Starten auch (ein Programm kann ja auch mal abstürzen, ein Rechner auch).

Man könnte das auch in eine separate Tabelle auslagern, die dann Vorgangsnummer und Benutzer vorhält. Dann muss man sich halt um die Konsistenz kümmern.

p80286 28. Apr 2017 13:26

AW: Mehrere Datensätze zwischenspeichern
 
[QUOTE=Hobbycoder;1369313]
Zitat:

Zitat von Luckner (Beitrag 1369279)
Es muß nur ausgeschlossen sein, dass eine Anwender an mehreren Arbeitsplätzen gleichzeitig arbeiten kann.

Zitat:

Zitat von Hobbycoder (Beitrag 1369313)
Dann muss man sich halt um die Konsistenz kümmern.

Hätte man dafür gesorgt, daß niemand die Welt umrundet, dann wüßte man noch heute, daß die Welt eine Scheibe ist.

Solche Lösungen sind Scheinlösungen, nach dem Motto wenn die Welt schon nicht so ist wie ich sie gerne hätte, dann bastele ich sie mir eben.

Gruß
K-H

Hobbycoder 28. Apr 2017 13:33

AW: Mehrere Datensätze zwischenspeichern
 
Zitat:

Zitat von p80286 (Beitrag 1369397)
Zitat:

Zitat von Hobbycoder (Beitrag 1369313)
Dann muss man sich halt um die Konsistenz kümmern.

Hätte man dafür gesorgt, daß niemand die Welt umrundet, dann wüßte man noch heute, daß die Welt eine Scheibe ist.

Solche Lösungen sind Scheinlösungen, nach dem Motto wenn die Welt schon nicht so ist wie ich sie gerne hätte, dann bastele ich sie mir eben.

Aus dem Zusammenhang gerissen trifft das zwar zu, aber ich habe ja auch dazu geschrieben: "Man könnte". Ist nicht gleich bedeutend mit "empfehlenswert".
Es ging mir in dem Zusammenhang darum, darauf hinzuweisen, dass man es in dem Fall tun muss.

p80286 28. Apr 2017 14:09

AW: Mehrere Datensätze zwischenspeichern
 
nichts für ungut aber "Nan könnte" wird viel zu gerne als Synonym für "das geht und ist nicht falsch" genommen. Der Nachsatz "aber dann.." fällt leider zu gerne unter den Tisch.

Gruß
K-H

P.S.
Und ich habe schon zu oft erlebt, daß das was nicht hätte sein dürfen, doch passiert ist.


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