Umrechnungen mithilfe einer Klasse handhaben

Aus RAD Studio
Wechseln zu: Navigation, Suche

Nach oben zu Maßeinheiten umrechnen


Es ist stets möglich, Umrechnungsfunktionen zur Registrierung von Maßeinheiten zu verwenden. Dieses Vorgehen kann jedoch in manchen Fällen die Definition sehr vieler Funktionen erfordern, die im Grunde dasselbe ausführen.

Statt einer Gruppe von Umrechnungsfunktionen, die sich nur in dem Wert eines Parameters oder einer Variablen unterscheiden, können Sie eine Klasse definieren, die diese Art von Umrechnungen handhabt. Beispielsweise werden seit der Einführung des Euro Standardformeln zur Umrechnung der verschiedenen europäischen Währungen eingesetzt. Obwohl die Umrechnungsfaktoren konstant bleiben (im Gegensatz zum Faktor für die Umrechnung von US-Dollar in Euro), ist es aus zweierlei Gründen nicht möglich, zur Umrechnung europäischer Währungen einfache Umrechnungsfaktoren zu verwenden:

  • Die Umrechnungsbeträge müssen auf eine währungsspezifische Anzahl von Stellen gerundet werden.
  • Der Umrechnungsfaktor, der für die Funktion Convert zu definieren ist, ist invers zu dem Faktor, der in den Euro-Umrechnungskonventionen festgelegt ist.

Dieses Schwierigkeiten lassen sich mit folgenden Umrechnungsfunktionen beheben:

Delphi:

 function FromEuro(const AValue: Double, Factor; FRound: TRoundToRange): Double;
 begin
   Result := RoundTo(AValue * Factor, FRound);
 end;
 function ToEuro(const AValue: Double, Factor): Double;
 begin
   Result := AValue / Factor;
 end;

C++:

double __fastcall FromEuro(const double AValue, const double Factor,
    TRoundToRange FRound) {
    return(RoundTo(AValue * Factor, FRound));
}

double __fastcall ToEuro(const double AValue, const double Factor) {
    return (AValue / Factor);
}

Problematisch ist hier, dass diese Umrechnungsfunktion zusätzliche Parameterangaben erfordert, sodass Sie nicht für jede europäische Währung dieselbe Funktion registrieren können. Damit Sie nicht für jede europäische Währung zwei Funktionen dieser Art definieren müssen, definieren Sie diese beiden Funktionen als Elementfunktionen einer Klasse.

Umrechnungsklasse definieren

Die Klasse muss von TConvTypeFactor abgeleitet werden. Die Klasse TConvTypeFactor definiert die beiden Methoden ToCommon und FromCommon, die Umrechnungen in die bzw. aus der Grundeinheit einer Umrechnungsfamilie durchführen (hier in und aus Euro). Wie die Funktionen, die beim Registrieren einer Maßeinheit verwendet werden, verarbeiten diese Methoden keine zusätzlichen Parameter. Sie müssen daher die Anzahl der zu rundenden Stellen und den Umrechnungsfaktor als private-Elemente der Umrechnungsklasse definieren. Dies wird im Beispiel "EuroConv" im Verzeichnis "demos\ConvertIt" (siehe euroconv.pas) gezeigt:

Delphi:

 type
 TConvTypeEuroFactor = class(TConvTypeFactor)
 private
 FRound: TRoundToRange;
 public
 constructor Create(const AConvFamily: TConvFamily;
 const ADescription: string; const AFactor: Double;
 const ARound: TRoundToRange);
 function ToCommon(const AValue: Double): Double; override;
 function FromCommon(const AValue: Double): Double; override;
 end;
 end;

C++:

class PASCALIMPLEMENTATION TConvTypeEuroFactor
		: public Convutils::TConvTypeFactor {
private:
	TRoundToRange FRound;

public:
	__fastcall TConvTypeEuroFactor(const TConvFamily AConvFamily,
			const AnsiString ADescription, const double AFactor,
			const TRoundToRange ARound);
	TConvTypeFactor(AConvFamily, ADescription, AFactor);
	virtual double ToCommon(const double AValue);
	virtual double FromCommon(const double AValue);
}

Der Konstruktor weist diesen private-Elementen Werte zu:

Delphi:

 constructor TConvTypeEuroFactor.Create(const AConvFamily: TConvFamily; const ADescription: string; const AFactor: Double; const ARound: TRoundToRange);
 begin
   inherited Create(AConvFamily, ADescription, AFactor);
   FRound := ARound;
 end;

C++:

__fastcall TConvTypeEuroFactor::TConvTypeEuroFactor
    (const TConvFamily AConvFamily, const AnsiString ADescription,
    const double AFactor, const TRoundToRange ARound)
    : TConvTypeFactor(AConvFamily, ADescription, AFactor); {
    FRound = ARound;
}

Die beiden Umrechnungsfunktionen verwenden einfach diese private-Elemente:

Delphi:

 function TConvTypeEuroFactor.FromCommon(const AValue: Double): Double;
 begin
   Result := RoundTo(AValue * Factor, FRound);
 end;
 function TConvTypeEuroFactor.ToCommon(const AValue: Double): Double;
 begin
   Result := AValue / Factor;
 end;

C++:

virtual double TConvTypeEuroFactor::ToCommon(const double AValue) {
    return (RoundTo(AValue * Factor, FRound));
}

virtual double TConvTypeEuroFactor::ToCommon(const double AValue) {
    return (AValue / Factor);
}

Variablen deklarieren

Nachdem die Umrechnungsklasse deklariert wurde, deklarieren Sie wie bei jeder anderen Umrechnungsfamilie zunächst die Bezeichner:

Delphi:

 var
   euEUR: TConvType; { Europäische Euro }
 euBEF: TConvType; { Belgische Francs }
 euDEM: TConvType; { Deutsche Mark }
 euGRD: TConvType; { Griechische Drachmen }
 euESP: TConvType; { Spanische Peseten }
 euFFR: TConvType; { Französische Francs }
 euIEP: TConvType; { Irische Pfund }
 euITL: TConvType; { Italienische Lire }
 euLUF: TConvType; { Luxemburgische Francs }
 euNLG: TConvType; { Holländische Gulden }
 euATS: TConvType; { Österreichische Schilling }
 euPTE: TConvType; { Portugiesische Escudos }
 euFIM: TConvType; { Finnische Mark }
   cbEuro: TConvFamily;

C++:

TConvFamily cbEuro;
TConvType euEUR; // Europäische Euro
TConvType euBEF; // Belgische Francs
TConvType euDEM; // Deutsche Mark
TConvType euGRD; // Griechische Drachmen
TConvType euESP; // Spanische Peseten
TConvType euFFR; // Französische Franc
TConvType euIEP; // Irische Pfund
TConvType euITL; // Italienische Lire
TConvType euLUF; // Luxemburgische Francs
TConvType euNLG; // Holländische Gulden
TConvType euATS; // Österreichische Schilling
TConvType euPTE; // Portugiesische Escudos
TConvType euFIM; // Finnische Mark

Umrechnungsfamilie und die anderen Units registrieren

Jetzt können Sie die Umrechnungsfamilie sowie die europäischen Währungen unter Verwendung der neuen Umrechnungsklasse registrieren. Sie registrieren diese Umrechnungsfamilie auf dieselbe Weise wie die anderen Umrechnungsfamilien:

Delphi:

 cbEuro := RegisterConversionFamily ('Europäische Währung');

C++:

cbEuro = RegisterConversionFamily("Europäische Währung");

Zur Registrierung der einzelnen Umrechnungstypen erstellen Sie jeweils eine Instanz der Umrechnungsklasse, die den Umrechnungsfaktor und die Zahl der zu rundenden Stellen für die betreffende Währung repräsentiert, und rufen die Methode RegisterConversionType auf.

Delphi:

 var
   LInfo: TConvTypeInfo;
 begin
   LInfo := TConvTypeEuroFactor.Create(cbEuro, 'EUEuro', 1.0, -2);
   if not RegisterConversionType(LInfo, euEUR) then
     LInfo.Free;
   LInfo := TConvTypeEuroFactor.Create(cbEuro, 'BelgianFrancs', 40.3399, 0);
   if not RegisterConversionType(LInfo, euBEF) then
     LInfo.Free;
   LInfo := TConvTypeEuroFactor.Create(cbEuro, 'GermanMarks', 1.95583, -2);
   if not RegisterConversionType(LInfo, euDEM) then
     LInfo.Free;
   LInfo := TConvTypeEuroFactor.Create(cbEuro, 'GreekDrachmas', 340.75, 0);
   if not RegisterConversionType(LInfo, euGRD) then
     LInfo.Free;
   LInfo := TConvTypeEuroFactor.Create(cbEuro, 'SpanishPesetas', 166.386, 0);
   if not RegisterConversionType(LInfo, euESP) then
     LInfo.Free;
   LInfo := TConvTypeEuroFactor.Create(cbEuro, 'FrenchFrancs', 6.55957, -2);
   if not RegisterConversionType(LInfo, euFFR) then
     LInfo.Free;
   LInfo := TConvTypeEuroFactor.Create(cbEuro, 'IrishPounds', 0.787564, -2);
   if not RegisterConversionType(LInfo, euIEP) then
     LInfo.Free;
   LInfo := TConvTypeEuroFactor.Create(cbEuro, 'ItalianLire', 1936.27, 0);
   if not RegisterConversionType(LInfo, euITL) then
     LInfo.Free;
   LInfo := TConvTypeEuroFactor.Create(cbEuro, 'LuxembourgFrancs', 40.3399, -2);
   if not RegisterConversionType(LInfo, euLUF) then
     LInfo.Free;
   LInfo := TConvTypeEuroFactor.Create(cbEuro, 'DutchGuilders', 2.20371, -2);
   if not RegisterConversionType(LInfo, euNLG) then
     LInfo.Free;
   LInfo := TConvTypeEuroFactor.Create(cbEuro, 'AustrianSchillings', 13.7603, -2);
   if not RegisterConversionType(LInfo, euATS) then
     LInfo.Free;
   LInfo := TConvTypeEuroFactor.Create(cbEuro, 'PortugueseEscudos', 200.482, -2);
   if not RegisterConversionType(LInfo, euPTE) then
     LInfo.Free;
   LInfo := TConvTypeEuroFactor.Create(cbEuro, 'FinnishMarks', 5.94573, 0);
   if not RegisterConversionType(LInfo, euFIM) then
     LInfo.Free;
 end;

C++:

TConvTypeInfo *pInfo = new TConvTypeEuroFactor(cbEuro, " EUEuro ", 1.0, -2);
if (!RegisterConversionType(pInfo, euEUR))
	delete pInfo;
pInfo = new TConvTypeEuroFactor(cbEuro, " BelgianFrancs ", 40.3399, 0);
if (!RegisterConversionType(pInfo, euBEF))
	delete pInfo;
pInfo = new TConvTypeEuroFactor(cbEuro, " GermanMarks ", 1.95583, -2);
if (!RegisterConversionType(pInfo, euDEM))
	delete pInfo;
pInfo = new TConvTypeEuroFactor(cbEuro, " GreekDrachmas ", 340.75, 0);
if (!RegisterConversionType(pInfo, euGRD) delete pInfo;
pInfo = new TConvTypeEuroFactor(cbEuro, " SpanishPesetas ", 166.386, 0);
if (!RegisterConversionType(pInfo, euESP) delete pInfo;
pInfo = new TConvTypeEuroFactor(cbEuro, " FrenchFrancs ", 6.55957, -2);
if (!RegisterConversionType(pInfo, euFFR) delete pInfo;
pInfo = new TConvTypeEuroFactor(cbEuro, " IrishPounds ", 0.787564, -2);
if (!RegisterConversionType(pInfo, euIEP) delete pInfo;
pInfo = new TConvTypeEuroFactor(cbEuro, " ItalianLire ", 1936.27, 0);
if (!RegisterConversionType(pInfo, euITL) delete pInfo;
pInfo = new TConvTypeEuroFactor(cbEuro, " LuxembourgFrancs ", 40.3399, -2);
if (!RegisterConversionType(pInfo, euLUF) delete pInfo;
pInfo = new TConvTypeEuroFactor(cbEuro, " DutchGuilders ", 2.20371, -2);
if (!RegisterConversionType(pInfo, euNLG) delete pInfo;
pInfo = new TConvTypeEuroFactor(cbEuro, " AutstrianSchillings ", 13.7603, -2);
if (!RegisterConversionType(pInfo, euATS) delete pInfo;
pInfo = new TConvTypeEuroFactor(cbEuro, " PortugueseEscudos ", 200.482, -2);
if (!RegisterConversionType(pInfo, euPTE) delete pInfo;
pInfo = new TConvTypeEuroFactor(cbEuro, " FinnishMarks ", 5.94573, 0);
if (!RegisterConversionType(pInfo, euFIM) delete pInfo;

Anmerkung: Wählen Sie Start | Programme | Embarcadero RAD Studio Rio | Beispiele, um das Beispiel ConvertIt (siehe Object Pascal\RTL\ConvertIt und \CPP\RTL\ConvertIt) zu suchen. ConvertIt stellt eine erweiterte Version dieses Beispiels bereit, die andere Währungen, für die keine festen Umrechnungskurse festgelegt sind, und umfangreichere Fehlerbehandlungsroutinen umfasst.

Neue Maßeinheiten verwenden

Die registrierten Maßeinheiten stehen nun Anwendungen für Umrechnungen zur Verfügung. Die globale Funktion Convert kann Beträge in alle europäischen Währungen, die in der neuen Familie cbEuro registriert sind, umrechnen. Mit dem folgenden Aufruf wird z.B. ein Wert von Italienischer Lire in Deutsche Mark umgerechnet:

C++:

Edit2->Text = FloatToStr(Convert(StrToFloat(Edit1->Text), euITL, euDEM));

Siehe auch