AGB  ·  Datenschutz  ·  Impressum  







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

Aufbau einer Währungstabelle

Ein Thema von DSP · begonnen am 20. Jan 2015 · letzter Beitrag vom 25. Jan 2015
Antwort Antwort
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#1

AW: Aufbau einer Währungstabelle

  Alt 21. Jan 2015, 12:38
Mein Vorschlag dazu wäre
SQL-Code:
DROP TABLE IF EXISTS "currency_rates";
DROP TABLE IF EXISTS "currencies";

-- Stammdaten Währungen

CREATE TABLE "currencies" (
    "ISOCODE" VARCHAR(3) NOT NULL,
    "ISONUM" int(3) NOT NULL,
    "ISONUMdate" date NOT NULL,
    "Name" text,
    "Format" text,
   PRIMARY KEY("ISOCODE")
);
CREATE INDEX "idx_currencies_ISONUM" ON currencies (ISONUM, ISONUMdate);
CREATE UNIQUE INDEX "idx_currencies_ISONUMCODE" ON currencies (ISONUM, ISONUMdate, ISOCODE);

-- Währungs-Daten

INSERT INTO "currencies" ( "ISOCODE", "ISONUM", "ISONUMdate", "Name", "Format" )
  VALUES ( 'EUR', 978, '1990-01-01', 'Euro', '%f €' );
INSERT INTO "currencies" ( "ISOCODE", "ISONUM", "ISONUMdate", "Name", "Format" )
  VALUES ( 'USD', 840, '1990-01-01', 'Dollar', '$ %f' );

-- Besonderheiten bei der Belegung der ISONUM Werte

INSERT INTO "currencies" ( "ISOCODE", "ISONUM", "ISONUMdate", "Name", "Format" )
  VALUES ( 'BUK', 104, '1952-07-01', 'Burma Kyat', '%f BUK' );
INSERT INTO "currencies" ( "ISOCODE", "ISONUM", "ISONUMdate", "Name", "Format" )
  VALUES ( 'MMK', 104, '1990-02-01', 'Myanmar Kyat', '%f MMK' );

INSERT INTO "currencies" ( "ISOCODE", "ISONUM", "ISONUMdate", "Name", "Format" )
  VALUES ( 'SUR', 810, '1923-01-01', 'Sowjetischer Rubel', '%f SUR' );
INSERT INTO "currencies" ( "ISOCODE", "ISONUM", "ISONUMdate", "Name", "Format" )
  VALUES ( 'RUR', 810, '1991-01-01', 'Russicher Rubel', '%f RUR' );
INSERT INTO "currencies" ( "ISOCODE", "ISONUM", "ISONUMdate", "Name", "Format" )
  VALUES ( 'RUB', 643, '1998-01-01', 'Neuer Russischer Rubel', '%f RUB' );

-- Wechselkurse

CREATE TABLE "currency_rates" (
    "sourceISOCODE" varchar(3) NOT NULL,
    "destinationISOCODE" varchar(3) NOT NULL,
    "ratetype" varchar(3) NOT NULL,
    "ratedate" "date" NOT NULL,
    "rate" real NOT NULL,
   PRIMARY KEY("sourceISOCODE","destinationISOCODE","ratetype","ratedate"),
   CONSTRAINT "fk_source_currency" FOREIGN KEY ("sourceISOCODE")
     REFERENCES "currencies" ("ISOCODE") ON DELETE CASCADE ON UPDATE CASCADE,
   CONSTRAINT "fk_destination_currency" FOREIGN KEY ("destinationISOCODE")
     REFERENCES "currencies" ("ISOCODE") ON DELETE CASCADE ON UPDATE CASCADE
);

-- Daten Wechselkurse

INSERT INTO "currency_rates" ("sourceISOCODE", "destinationISOCODE", "ratetype", "ratedate", "rate")
  VALUES ( "EUR", "USD", "AWK", date('2015-01-01'), 1.11 );
INSERT INTO "currency_rates" ("sourceISOCODE", "destinationISOCODE", "ratetype", "ratedate", "rate")
  VALUES ( "EUR", "USD", "AWK", date('2015-01-02'), 1.12 );
INSERT INTO "currency_rates" ("sourceISOCODE", "destinationISOCODE", "ratetype", "ratedate", "rate")
  VALUES ( "EUR", "USD", "AWK", date('2015-01-03'), 1.13 );
INSERT INTO "currency_rates" ("sourceISOCODE", "destinationISOCODE", "ratetype", "ratedate", "rate")
  VALUES ( "EUR", "USD", "AWK", date('2015-01-04'), 1.14 );
INSERT INTO "currency_rates" ("sourceISOCODE", "destinationISOCODE", "ratetype", "ratedate", "rate")
  VALUES ( "EUR", "USD", "AWK", date('2015-01-05'), 1.15 );
INSERT INTO "currency_rates" ("sourceISOCODE", "destinationISOCODE", "ratetype", "ratedate", "rate")
  VALUES ( "EUR", "USD", "AWK", date('2015-01-06'), 1.16 );
INSERT INTO "currency_rates" ("sourceISOCODE", "destinationISOCODE", "ratetype", "ratedate", "rate")
  VALUES ( "EUR", "USD", "AWK", date('2015-01-07'), 1.17 );

-- Abfrage eines konkreten Wechselkurs

SELECT *
FROM currency_rates
WHERE sourceISOCODE = 'EUR'
AND destinationISOCODE = 'USD'
AND ratetype = 'AWK'
AND ratedate <= date( '2015-01-03' )
ORDER BY ratedate DESC
LIMIT 1;
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)

Geändert von Sir Rufo (21. Jan 2015 um 12:41 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von smallie
smallie

Registriert seit: 8. Jan 2013
19 Beiträge
 
Delphi 10.3 Rio
 
#2

AW: Aufbau einer Währungstabelle

  Alt 21. Jan 2015, 14:31
Ich denke, es ist keine gute Idee, für jede beliebige Kombination von Währungen Umrechnungskurse vorzuhalten.

Besser wäre es nur den Umrechnungskurse Fremdwährung/EURO zu speichern und bei Bedarf zu rechnen. So sah das auch die EZB bei der EURO-Umstellung vor.
"There are two hard things in computer science: cache invalidation, naming things, and off-by-one errors."
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#3

AW: Aufbau einer Währungstabelle

  Alt 21. Jan 2015, 15:29
Ich denke, es ist keine gute Idee, für jede beliebige Kombination von Währungen Umrechnungskurse vorzuhalten.

Besser wäre es nur den Umrechnungskurse Fremdwährung/EURO zu speichern und bei Bedarf zu rechnen. So sah das auch die EZB bei der EURO-Umstellung vor.
Öhhh, wo steht das, dass das so gemacht wird? Und du wolltest wahrscheinlich auch sagen, dass man immer die Umrechnungskurse von seiner Basis-Währung zur Fremd-Währung speichert und die Umrechnung dann bei Fremd-Währung zu Fremd-Währung immer erst über die eigene Basis-Währung geht.

Und mit meinem Datenbank-Modell kann man doch tatsächlich mehrere Basis-Währungen verwalten (ergo geht auch nur eine). Aber warum soll ich das Design jetzt schon auf eine Basis-Währung festlegen, wenn es doch ohne Probleme auch für mehrere geht. Dann schreibe ich mir den gesamten Rotz einmal und kann den immer wiederverwenden und auch dann, wenn die Anwendung unterschiedliche Aspekte (unterschiedliche Unternehmen mit unterschiedlichen Basis-Währungen) verwalten soll? Das wäre dann doch einfach nur blind, oder?
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

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

AW: Aufbau einer Währungstabelle

  Alt 21. Jan 2015, 15:38
Ich denke, es ist keine gute Idee, für jede beliebige Kombination von Währungen Umrechnungskurse vorzuhalten.

Besser wäre es nur den Umrechnungskurse Fremdwährung/EURO zu speichern und bei Bedarf zu rechnen. So sah das auch die EZB bei der EURO-Umstellung vor.
und in der Praxis machen die Wechselkurshopper, die zb. USDollar -> türk. Lira -> Euro -> USDollar wechseln mit diesen minimalen Unterschieden ihr Geld.
Jede (frei konvertierbare) Währung hat eigene Wechselkurse. Aus diesem Grunde werden viele Geschäfte nur in USDollar (oder Euro,Schweizer Franken) abgewickelt, damit das Wechselkursrisiko möglichst gering bleibt.

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

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#5

AW: Aufbau einer Währungstabelle

  Alt 21. Jan 2015, 16:01
Gerade für dieses Währungs-Thema macht es Sinn eigene Daten-Typen anzulegen, denn dann wird man typsicher im Kontext.

Kleines Beispiel:
Delphi-Quellcode:
program dp_183568;

{$APPTYPE CONSOLE}
{$R *.res}

uses
  System.SysUtils,
  CurrencyValue in 'CurrencyValue.pas',
  MemoryCurrencyRepository in 'MemoryCurrencyRepository.pas';

procedure Prepare;
begin
  TDateType.Freezed := False;
  TCurrencyType.DEFAULT := 'EUR';
  TCurrencyValue.CurrencyRepository := TMemoryCurrencyRepository.Create;

  TCurrencyValue.CurrencyRepository.StoreConvertValue( TCurrencyConvertValue.Create( '01.01.2000', TCurrencyFactorValue.Create( 'EUR', 'DEM', 1.9558 ) ) );
  TCurrencyValue.CurrencyRepository.StoreConvertValue( TCurrencyConvertValue.Create( '01.01.2000', TCurrencyFactorValue.Create( 'EUR', 'ATS', 13.7603 ) ) );

  TCurrencyValue.CurrencyRepository.StoreConvertValue( TCurrencyConvertValue.Create( '01.10.2014', TCurrencyFactorValue.Create( 'EUR', 'USD', 1.00 ) ) );
  TCurrencyValue.CurrencyRepository.StoreConvertValue( TCurrencyConvertValue.Create( '01.11.2014', TCurrencyFactorValue.Create( 'EUR', 'USD', 1.10 ) ) );
  TCurrencyValue.CurrencyRepository.StoreConvertValue( TCurrencyConvertValue.Create( '01.12.2014', TCurrencyFactorValue.Create( 'EUR', 'USD', 1.20 ) ) );
  TCurrencyValue.CurrencyRepository.StoreConvertValue( TCurrencyConvertValue.Create( '01.01.2015', TCurrencyFactorValue.Create( 'EUR', 'USD', 1.30 ) ) );
end;

procedure OutputCurrencyValueIn( AValue: TCurrencyValue; ACurrency: TCurrencyType );
begin
  Writeln( AValue.ToString, ' ==(', TDateType.TODAY.ToString, ')=> ', AValue.Convert( ACurrency ).ToString );
end;

procedure Test;
var
  LValue: TCurrencyValue;
begin
  LValue := 500; // Wegen dem DEFAULT Wert sind das 500,00 EUR

  OutputCurrencyValueIn( LValue, 'DEM' );
  OutputCurrencyValueIn( LValue, 'ATS' );

  OutputCurrencyValueIn( LValue, 'USD' );
  TDateType.TODAY := '15.12.2014'; // TODAY-Datum festlegen
  OutputCurrencyValueIn( LValue, 'USD' );
  TDateType.Freezed := False; // TODAY folgt nun wieder dem SYSTEM-Datum
  OutputCurrencyValueIn( LValue, 'USD' );

  TDateType.TODAY := '15.11.2014'; // TODAY-Datum festlegen
  OutputCurrencyValueIn( LValue, 'USD' );
  TDateType.TODAY := '15.10.2014'; // TODAY-Datum festlegen
  OutputCurrencyValueIn( LValue, 'USD' );
  TDateType.TODAY := '15.09.2014'; // TODAY-Datum festlegen
  OutputCurrencyValueIn( LValue, 'USD' );
  TDateType.Freezed := False; // TODAY folgt wieder dem SYSTEM-Datum
end;

begin
  try
    Prepare;
    Test;
  except
    on E: Exception do
      Writeln( E.ClassName, ': ', E.Message );
  end;
  Readln;

end.
Oder um das Wechsel-Orgien-Beispiel aufzugreifen, würde man einfach nur schreiben
Delphi-Quellcode:
// Fremdwährung erfassen
LValue := TCurrencyValue.Create( 1000, 'USD' );
// Wechseldifferenz mit dem jeweiligen Ausgabe-Kurs berechnen
LChangeDiff := Lvalue.Convert( 'TRL', 'AGK' ).Convert( 'EUR', 'AGK' ).Convert( 'USD', 'AGK' );
// Haben wir etwas verdient?
if LChangeDiff.Value > 0 then
  WriteLn( 'Lass uns das machen, wir verdienen daran ', LChangeDiff.ToString, ' was aktuell ', LChangeDiff.Convert( 'EUR', 'AGK' ), ' entspricht.' );
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Antwort Antwort


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 23:30 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz