Glengamoi (Forum) · AspHeute · .NET Heute (RSS-Suche) · AspxFiles (Wiki) · .NET Blogs

Eine Eurokonvertierungskomponente in C# erstellen

Geschrieben von: Christoph Wille
Kategorie: C#

This printed page brought to you by AlphaSierraPapa

Die Einführung des "angreifbaren" Eurogeldes rückt immer näher, und die doppelte Preisauszeichnung ist mittlerweile auch schon überall zu sehen. Letztes Jahr haben wir uns im Artikel Preisauszeichnung in Euro mit ASP bereits mit diesem Thema beschäftigt, allerdings haben wir damals eine bereits bestehende Komponente von AlphaSierraPapa verwendet.

Heute werden wir diese Komponente mit C# nachprogrammieren - und zwar weil eine native .NET Komponente viel performanter ist als wenn man die existierende COM Komponente mit Interop in ASP.NET einbindet (siehe dazu auch der Artikel Verwenden von COM Komponenten in ASP.NET).

Die Funktionalität

Folgende öffentlich angreifbare Funktionen werden wir in die Komponente einbauen:

public double GetExchangeRate(String strCurrencySymbol);
public double ConvertToEuro(double dVal2Convert, string strCurrencyFrom);
public double ConvertFromEuro(double dVal2Convert, string strCurrencyTo);
public double Triangulate(double dVal2Convert, string strCurrencyFrom, 
                          string strCurrencyTo);

Diese Funktionen entsprechen dem, was die COM Komponente auch "leistet". Intern gibt es dann noch die Round Methode, die die korrekte Rundung nach den Richtlinien der EMU (European Monetary Union) durchführt.

Zum Programmieren der Komponente kann man aus einer Vielzahl von Tools wählen, so zum Beispiel Notepad, Visual Studio.NET uvm. Ich habe mich für den Open Source Editor SharpDevelop entschieden (siehe Screenshot).

Die Umrechnungsfaktoren

Die Umrechnungskurse für die Länder, die an der Währungsunion teilnehmen, finden sich bei der Euro Info der EU. Mit diesen Kursen ausgestattet, kann man beginnen, die Komponente zu programmieren.

Ich habe mich entschieden, die Zuordnung der Währungskurse zu den Währungssymbolen in einem Hashtable zu implementieren (geschützte Membervariable, Initialisierung im Konstruktor):

  protected Hashtable m_MapCurrencySymbol2Factor;
  
  public EuroConverter()
  {
    m_MapCurrencySymbol2Factor = new Hashtable();
    m_MapCurrencySymbol2Factor.Add("ATS", 13.7603);	// Austria
    m_MapCurrencySymbol2Factor.Add("BEF", 40.3399);	// Belgium
    m_MapCurrencySymbol2Factor.Add("LUF", 40.3399);	// Luxemburg
    m_MapCurrencySymbol2Factor.Add("FIM", 5.94573);	// Finland
    m_MapCurrencySymbol2Factor.Add("FRF", 6.55957);	// France
    m_MapCurrencySymbol2Factor.Add("DEM", 1.95583);	// Germany
    m_MapCurrencySymbol2Factor.Add("IEP", 0.787564);	// Ireland
    m_MapCurrencySymbol2Factor.Add("ITL", 1936.27);	// Italy
    m_MapCurrencySymbol2Factor.Add("NLG", 2.20371);	// Netherlands
    m_MapCurrencySymbol2Factor.Add("PTE", 200.482);	// Portugal
    m_MapCurrencySymbol2Factor.Add("ESP", 166.386);	// Spain
    m_MapCurrencySymbol2Factor.Add("GRD", 340.750);	// Greece
  }

Konvertieren von Landeswährung nach Euro

Der Funktion ConvertToEuro wird eine Dezimalzahl und ein Währungssymbol übergeben. Anhand des Währungssymbols wird der Umrechnungskurs aus dem Hashtable ausgelesen, und dann die Konvertierung durchgeführt:

  public double ConvertToEuro(double dVal2Convert, string strCurrencyFrom) 
  {
	if (!m_MapCurrencySymbol2Factor.ContainsKey(strCurrencyFrom))
	{
          throw new ArgumentException("Lookup of currency symbol failed!");
	}
	
	double dRate = (double)m_MapCurrencySymbol2Factor[strCurrencyFrom];
	return Round((dVal2Convert / dRate));
  } 

Sollte das Währungssymbol nicht in unserem Hashtable gespeichert sein, so lassen wir dies dem Benutzer der Komponente mit einer ArgumentException wissen. Der Rest der Rechnung ist einfach, bis auf die Verwendung der selbstgebastelten Round Funktion - es gibt nämlich eigene Rundungsregeln für das Rechnen mit Euro!

Hier ist ein korrekte Implementierung nach den Richtlinien der EMU:

  protected double Round(double dVal2Round)
  {
    // first, strip off everything after third decimal
    double dVal2 = 0.0;
    dVal2Round *= 1000;
    dVal2 = Fix(dVal2Round);
    
    // now, round the result
    dVal2 /= 10;
    dVal2Round = Fix(dVal2 + (dVal2 > 0 ? 0.5 : -0.5));
    
    // we are done.
    return (dVal2Round/100);
  }

Die Round Methode verwendet eine Funktion namens Fix, die ebenso nicht Bestandteil von C# oder dem .NET Framework ist - sie liefert genauso wie das VB Pendant den Ganzzahlteil der Double Variable:

  protected double Fix(double dVarIn)
  {
    if (Math.Sign(dVarIn) < 0)
    {
        // less than 0, negative values
        return Math.Ceiling(dVarIn);
    }
    else
    {
        return Math.Floor(dVarIn);
    }
    return -1;	// unreachable code; intentionally
  }

Damit hätten wir die Methode ConvertToEuro besprochen - ConvertFromEuro ist analog implementiert.

Triangulieren

Unter Triangulation versteht man den Vorgang des Konvertieren eines Geldbetrages von einer Eurowährung in eine andere, zum Beispiel Schilling in Deutsche Mark. Dabei rechnet man erst den Betrag in Schilling nach Euro, und dann von Euro nach Deutsche Mark. Eine direkte Umrechnung ist nicht gestattet.

Der entsprechende Sourcecode sieht wie folgt aus:

  public double Triangulate(double dVal2Convert, string strCurrencyFrom, 
                            string strCurrencyTo) 
  {
    if (!m_MapCurrencySymbol2Factor.ContainsKey(strCurrencyFrom) ||
        !m_MapCurrencySymbol2Factor.ContainsKey(strCurrencyTo))
    {
        throw new ArgumentException("Lookup of currency symbol failed!");
    }
    
    double dRateFrom =(double)m_MapCurrencySymbol2Factor[strCurrencyFrom];
    double dRateTo = (double)m_MapCurrencySymbol2Factor[strCurrencyTo];
    
    // do the conversion
    double dHelper = dVal2Convert / dRateFrom;
    dHelper *= dRateTo;
    
    return Round(dHelper);
  }

Damit hätten wir alle wichtigen Funktionen der Komponente durchbesprochen - klicken Sie hier, um den gesamten Sourcecode der Komponente zu betrachten.

Die Komponente verwenden

Natürlich muß man die Komponente zuallererst kompilieren - entweder mit Hilfe des Editors, oder über die Kommandozeile:

csc /out:EuroConv.dll /target:library EuroConv.cs

Wenn man die Komponente in ASP.NET einsetzt, kopiert man sie am besten in das bin Verzeichnis der Web Site - damit steht sie automatisch allen Seiten zur Verfügung, so zum Beispiel meiner Testseite simple.aspx:

<% @Page Language= "C#" %>
<% @Import Namespace="AlphaSierraPapa.Utilities" %>
<%
 EuroConverter ecuConv = new EuroConverter();
 Response.Write(ecuConv.ConvertToEuro(100, "ATS") + "<br>");
 Response.Write(ecuConv.ConvertFromEuro(100, "ATS") + "<br>");
 Response.Write(ecuConv.Triangulate(100, "ATS", "DEM") + "<br>");
 Response.Write(ecuConv.GetExchangeRate("ESP") + "<br>");
%>

Das ist natürlich nur eine äußerst einfach gehaltene Testseite, die alle zur Verfügung gestellten Methoden einmal einbindet. Im täglichen Betrieb wird die Komponente aber gute Dienste leisten.

Schlußbemerkung

Die heute vorgestellte Komponente stellt alle Funktionen bereit, die man zur korrekten Konvertierung von Geldbeträgen der Euroteilnehmerstaaten benötigt - und zwar als native .NET Komponente. Diese kann sowohl in ASP.NET als auch WinForms oder Kommandozeilenapplikationen eingesetzt werden.

This printed page brought to you by AlphaSierraPapa

Download des Codes

Klicken Sie hier, um den Download zu starten.
http://www.aspheute.com/code/20010123.zip

Verwandte Artikel

Eine Klasse für sich - die .NET Zip Library
http:/www.aspheute.com/artikel/20011115.htm
Preisauszeichnung in Euro mit ASP
http:/www.aspheute.com/artikel/19990827.htm
Verwenden von COM Komponenten in ASP.NET
http:/www.aspheute.com/artikel/20000828.htm

Links zu anderen Sites

Euro Conversion Component
http://www.alphasierrapapa.com/componentcenter/euro/
Euro Umrechnungsfaktoren
http://europa.eu.int/euro/html/dossiers/00232/html/index-DE.html
SharpDevelop
http://www.icsharpcode.net/opensource/sd/
Triangulation
http://www.alphasierrapapa.com/ComponentCenter/Euro/Help/triangulation.html

 

©2000-2006 AspHeute.com
Alle Rechte vorbehalten. Der Inhalt dieser Seiten ist urheberrechtlich geschützt.
Eine Übernahme von Texten (auch nur auszugsweise) oder Graphiken bedarf unserer schriftlichen Zustimmung.