AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Delphi komplexe Berechnungen von abhängigen Datenbankfeldern

komplexe Berechnungen von abhängigen Datenbankfeldern

Ein Thema von Emilio · begonnen am 12. Feb 2006 · letzter Beitrag vom 22. Feb 2006
Antwort Antwort
Seite 1 von 5  1 23     Letzte » 
Emilio

Registriert seit: 14. Dez 2003
65 Beiträge
 
#1

komplexe Berechnungen von abhängigen Datenbankfeldern

  Alt 12. Feb 2006, 22:08
Datenbank: DBISAM • Version: 4.21 • Zugriff über: Native
Hallo Leute,

nachdem ich nun in mehreren Büchern und nach einigen DP-Sitzungen noch weniger schlau bzw. ausreichend verwirrt bin, möchte ich das Problem erstmal grob schildern:

Habe eine Query aus mittlerweile 12 tables und stelle die Werte mit DBLabels dar. Diese Werte werden für weitere Berechnungen, welche zunächst nicht gespeichert werden müssen, benötigt. Und zwar in der Form, dass der User z.B. einen neuen EK-Preis in ein Editfeld einträgt (hab bisher keine schlauere Idee), mittels einer Combobox einen Handlingsaufschlag wählt und damit den EK2 erhält. Dem User soll für den VK ein Vorschlag gemacht werden, den er aber ändern kann. Wenn er dies tut, so soll der Brutto-Preis errechnet werden (in Abhähngigkeit des MwSt-Satzes) und die Felder [Marge€], [Marge%], [Provision] sollen ausgefüllt werden. Jedoch soll der User auch die Möglichleit haben, in letztere Felder Werte seiner Wahl einzutragen und die vorhergehenden sollten errechnet werden. Zu allem Überfluss sollte eine Reihe von Feldern die Veränderungen eines jedes Feldes Alt zu Neu in % ausweisen.
Wichtig zu wissen ist, dass nur neue Datensätz erzeugt werden sollen, also keine Änderungen oder Löschungen.

Ich bekomme das bislang nur hin, in dem ich unter viel Formatierungsaufwand mit den Feldinhalten rechne - scheitere aber an dem Punkt, die neuen Werte so aufzubereiten, dass sie in die Tabelle die es betrifft eingefügt werden können.

Ein DP-Mitglied gab mir die Empfehlung den Rechenkram von der Visualisierung zu trennen - ist bestimmt gut - aber wie? Die neuen Werte müssen doch erst vom User teilweise eingegeben werden und sollen noch vor dem speichern mit allen Folgewerten vorliegen ???

memTable, ParambyName, subquery, Rembrandt?


Mir drehts sich auch schon im Kreis

Kann mir jemand sagen, auf welchen Weg ich mich begeben soll?

Viele Grüße
Emilio

[edit=MrSpock]Titel geändert. Mfg, MrSpock[/edit]
  Mit Zitat antworten Zitat
marabu

Registriert seit: 6. Apr 2005
10.109 Beiträge
 
#2

Re: Katze beißt sich in den eigenen Schwanz - komplexe Frage

  Alt 13. Feb 2006, 11:27
Hallo Emilio,

das römische Imperium ist untergegangen und so führen heute leider nicht mehr alle Wege nach Rom.

Aus dem thread, in dem ich dir den Rat gab alle Rechenvorschriften aus der Benutzerschnittstelle heraus zu halten, kenne ich zumindest eine Rechenvorschrift. Du wirst mehrere benötigen, da du ja von verschiedenen Punkten ausgehen willst.

Prinzipiell musst du fixe (Konstanten) und veränderliche (Variablen) Werte in deinen Berechnungen unterscheiden. Du hattest die Buchstaben a bis m vergeben - ich halte mich hier daran, auch wenn ich eine andere Benennung besser fände. Ich notiere Konstanten mit Großbuchstaben, Variablen mit Kleinbuchstaben.

Deine Rechenvorschrift hatte folgenden Aufbau:

Delphi-Quellcode:
procedure TForm1.cxLookupComboBox1PropertiesCloseUp(Sender: TObject);
var
  a, c, d , e, f , g, h, i, j, k, l, m, n : Double;
  b : Integer;
begin
  a := StrToFloat(cxTextEdit1.Text);
  b := StrToInt(cxLookupComboBox1.Text);
  c := a+(a*b/100);
  d := (a/60*100);
  e := (d-a);
  f := (d-a)*100/d;
  g := (d-c)*StrToFloat(cxDBLabel13.Caption)/100;
  h := (d*116/100);
  i := StrToFloat(cxDBLabel5.Caption);
  j := ((c/i)-1)*100;
  k := StrToFloat(cxDBLabel9.Caption);
  l := ((d/k)-1)*100;
  m := StrToFloat(cxLabel28.Caption);
  n := ((h/m)-1)*100;

  cxLabel14.Caption := Format('EUR ' + '%8.2f', [a+(a*b/100)]);
  cxTextEdit5.Text := Format('EUR ' + '%8.2f', [d]);
  cxTextEdit2.Text := Format('EUR ' + '%8.2f', [e]);
  cxTextEdit3.Text := Format('%5.2f', [f]) + '%';
  cxTextEdit6.Text := Format('EUR ' + '%8.2f', [g]);
  cxTextEdit4.Text := Format('EUR ' + '%8.2f', [h]);
  cxLabel18.Caption := Format('%4.2f', [j]) + '%';
  cxLabel19.Caption := Format('%4.2f', [l]) + '%';
  cxLabel24.Caption := Format('%4.2f', [n]) + '%';
end;
Ich gehe davon aus, dass alle cxTextEdit Eingabefelder darstellen. Aus deinem Code leite ich folgende funktionale Abhängigkeiten ab:

Code:
A=cxTextEdit1
b=cxLookupComboBox1
O=cxDBLabel13
I=cxDBLabel5
K=cxDBLabel9
M=cxLabel28

f_c(A,b)
f_d(A)
f_e(A,d)
f_f(A,d)
f_g(c,d,O)
f_h(d)
f_j(c,I)
f_l(d,K)
f_n(h,M)
Die Funktionen (f_c..f_h,f_j,f_l,f_n) realisierst du im implementation Abschnitt der Unit, in der du deine Rechenvorschriften speicherst. Im interface Abschnitt dieser Unit befinden sich die Funktionen für die Rechenvorschriften. Jede Rechenvorschrift hat eine bestimmte Signatur - das sind die Eingabe- und Ausgabeparameter.

Delphi-Quellcode:
unit CalcMdl;

interface

  procedure CalcRule01(A,I,K,M,O: Extended; b: Integer; var c,d,e,f,g,h,j,l,n: Extended);

implementation

  function f_c(A: Extended; b: Integer): Extended; forward;


function f_c(A: Extended; b: Integer): Extended;
begin
  Result := a + (a * b / 100);
end;


procedure CalcRule01(A,I,K,M,O: Extended; b: Integer; var c,d,e,f,g,h,j,l,n: Extended);
begin
  c := f_c(A, b);
  d := f_d(A);
  e := f_e(A, d);
  f := f_f(A, d);
  g := f_g(c, d, O);
  h := f_h(d);
  j := f_j(c, I);
  l := f_l(d, K);
  n := f_n(h, M);
end;

end.
Das Durchrechnen der Werte als Reaktion auf die Änderung in der ComboBox geschieht dann so:

Delphi-Quellcode:
procedure TForm1.cxLookupComboBox1PropertiesCloseUp(Sender: TObject);
var
  A, c, d , e, f , g, h, I, j, K, l, M, n, O: Extended;
  b : Integer;
begin
  A := StrToFloat(cxTextEdit1.Text);
  I := StrToFloat(cxDBLabel5.Caption);
  K := StrToFloat(cxDBLabel9.Caption);
  M := StrToFloat(cxLabel28.Caption);
  O := StrToFloat(cxDBLabel13.Caption);
  b := StrToInt(cxLookupComboBox1.Text);

  CalcRule01(A, I, K, M, O, b, c, d, e, f, g, h, j, l, n);

  cxLabel14.Caption := Format('EUR ' + '%8.2f', [c]);
  cxTextEdit5.Text := Format('EUR ' + '%8.2f', [d]);
  cxTextEdit2.Text := Format('EUR ' + '%8.2f', [e]);
  cxTextEdit3.Text := Format('%5.2f', [f]) + '%';
  cxTextEdit6.Text := Format('EUR ' + '%8.2f', [g]);
  cxTextEdit4.Text := Format('EUR ' + '%8.2f', [h]);
  cxLabel18.Caption := Format('%4.2f', [j]) + '%';
  cxLabel19.Caption := Format('%4.2f', [l]) + '%';
  cxLabel24.Caption := Format('%4.2f', [n]) + '%';
end;
Das verstehe ich unter Trennung. Beachte auch, dass ich Double durch Extended ersetzt habe - wegen der höheren Rechengenauigkeit. Wenn du alle Berechnungsvorschriften entworfen hast, dann wirst du eventuell feststellen, dass manche Elementarfunktion (f_c, f_d, ...) nur einmal verwendet wird. Es steht dir dann frei solche "internen" Funktionen zu integrieren. Und noch einmal mein Rat über eine Namenskonvention für dein Programm nachzudenken - du wirst es nicht bereuen.

Grüße vom marabu
  Mit Zitat antworten Zitat
Benutzerbild von sakura
sakura

Registriert seit: 10. Jun 2002
Ort: Unterhaching
11.412 Beiträge
 
Delphi 12 Athens
 
#3

Re: Katze beißt sich in den eigenen Schwanz - komplexe Frage

  Alt 13. Feb 2006, 12:03
Hi,

ändere bitte noch den Titel so, dass dieser auch aussagekräftig ist.

Danke,
......
Daniel Lizbeth
Ich bin nicht zurück, ich tue nur so
  Mit Zitat antworten Zitat
Emilio

Registriert seit: 14. Dez 2003
65 Beiträge
 
#4

Flut v. Rechenvorgängen v. Visualisierung trennen

  Alt 13. Feb 2006, 22:30
Hi Marabu,

vielen vielen Dank!
Bin dabei Deine Ausführungen umzusetzen (wobei für Dich der Code jetzt verständlicher ist, ist er für mich sehr viel aufwändiger zu lesen - ich tue mich mit der Abstraktion leichter, da ich dann die Rechenformeln leichter formulieren und lesen kann).

Eine Frage zur der Funktion, die Du beispielweise anführst: muss die Deklaration der Funktion nicht im Interface-Abschnitt erfolgen? Wenn nein, warum nicht?

So, jetzt bastel ich erstmal weiter an der "Übersetzung".

Viele Grüße

Emilio
  Mit Zitat antworten Zitat
Emilio

Registriert seit: 14. Dez 2003
65 Beiträge
 
#5

Re: Katze beißt sich in den eigenen Schwanz - komplexe Frage

  Alt 13. Feb 2006, 22:39
@sakura,

wie geht'n das mit dem sräd-Titel ändern?
  Mit Zitat antworten Zitat
marabu

Registriert seit: 6. Apr 2005
10.109 Beiträge
 
#6

Re: Katze beißt sich in den eigenen Schwanz - komplexe Frage

  Alt 13. Feb 2006, 22:44
Hi Emilio,

nur die Rechenvorschriften gehören in den interface Abschnitt, weil sie von außen erreichbar sein müssen. f_c() ist eine rein interne Funktion und gehört deswegen in den implementation Abschnitt. Da ich dort nicht ausschließen kann, dass die Basis-Funktionen sich in unterschiedlicher Reihenfolge gegenseitig rufen, deklariere ich sie zuerst mit der forward Direktive.

Gute Nacht

marabu

PS: du kannst den Titel ändern, wenn du deinen ersten Beitrag bearbeitest.
  Mit Zitat antworten Zitat
Benutzerbild von turboPASCAL
turboPASCAL

Registriert seit: 8. Mai 2005
Ort: Sondershausen
4.274 Beiträge
 
Delphi 6 Personal
 
#7

Re: Katze beißt sich in den eigenen Schwanz - komplexe Frage

  Alt 13. Feb 2006, 22:44
Zitat von Emilio:
wie geht'n das mit dem sräd-Titel ändern?
Im (Deinem) ersten Beitrag auf Edit klicken und im Titeleditfeld den Titel ändern
Matti
Meine Software-Projekte - Homepage - Grüße vom Rüsselmops -Mops Mopser
  Mit Zitat antworten Zitat
Emilio

Registriert seit: 14. Dez 2003
65 Beiträge
 
#8

Re: Katze beißt sich in den eigenen Schwanz - komplexe Frage

  Alt 14. Feb 2006, 22:22
Hi @all,

das mit dem Thema-Titel ändern geht nicht mehr ... vielleicht kann ja einer der Mods eingreifen?

@Marabu,


Zitat von marabu:
Hi Emilio,

nur die Rechenvorschriften gehören in den interface Abschnitt, weil sie von außen erreichbar sein müssen. f_c() ist eine rein interne Funktion und gehört deswegen in den implementation Abschnitt. Da ich dort nicht ausschließen kann, dass die Basis-Funktionen sich in unterschiedlicher Reihenfolge gegenseitig rufen, deklariere ich sie zuerst mit der forward Direktive.
Zitat von marabu:
Die Funktionen (f_c..f_h,f_j,f_l,f_n) realisierst du im implementation Abschnitt der Unit, in der du deine Rechenvorschriften speicherst. Im interface Abschnitt dieser Unit befinden sich die Funktionen für die Rechenvorschriften. Jede Rechenvorschrift hat eine bestimmte Signatur - das sind die Eingabe- und Ausgabeparameter.
Also schreibe ich die anderen Funktionen in ähnlicher Art und Weise in eine neue Unit. In der UnitMain entferne ich das Gerümpel und lasse i.B. die procedure mit der Combobox in derUnitMain stehen? - irgendwie stehe ich doch noch auf dem Schlauch: woher weiß dann die procedure der combobox was von den Rechenvorschriften?

Emilio
  Mit Zitat antworten Zitat
marabu

Registriert seit: 6. Apr 2005
10.109 Beiträge
 
#9

Re: Katze beißt sich in den eigenen Schwanz - komplexe Frage

  Alt 15. Feb 2006, 07:06
Guten Morgen Emilio,

ich unterscheide Berechnungsvorschriften von mathematischen Funktionen. Die Vorschriften müssen in den interface Abschnitt der Unit CalcMdl, weil sie für die ComboBox in deiner MainForm sichtbar sein müssen. Dazu bindest du die Unit CalcMdl per USES in den implementation Abschnitt deiner MainForm ein und schon kannst du aus dem event handler der ComboBox alle Vorschriften aufrufen. Die mathematischen Funktionen (z.B. Berechnung eines Prozentsatzes) werden nur von den Vorschriften benötigt und deshalb im implementation Abschnitt der Unit CalcMdl deklariert.

Du kannst alle Vorschriften und Funktionen in einer einzigen Unit (CalcMdl, dein Kalkulationsmodell) unterbringen. Dein Code wird wohl nie so umfangreich werden, als dass sich eine eigene Unit je Berechnungsvorschrift lohnen wird.

Grüße vom marabu
  Mit Zitat antworten Zitat
Emilio

Registriert seit: 14. Dez 2003
65 Beiträge
 
#10

Re: komplexe Berechnungen von abhängigen Datenbankfeldern

  Alt 15. Feb 2006, 11:22
Hi Marabu,

Die Calc-Unit habe ich eingebunden - das war kein Thema.

Beim Compilieren erhalte ich nun die Fehlermeldung:

"inkompatible Typen Integer und Extended",

sowie die Fehlermeldung

"nicht genügend wirkliche Parameter"

Der Cursor steht für beide Meldungen in der Zeile

(UnitMain wohlbemerkt): CalcRule01( ...);, welche ich aus Deinem script übernommen habe.

Sollte ich noch ne Kleinigkeit übersehen haben? Die Variablen a (jetzt "ekneu") und b (jetzt "zuschlag") sind als Integer deklariert, in beiden Units.

VG
Emilio
  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:

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