Lade...
 

Rate-Tables an- und abmelden

Einheiten-Umrechnungstabellen beim ClassiX®-System an- und abmelden

Umrechnungstabellen

Umrechungstabellen definieren Verhältnisse zwischen unterschiedlichen Einheiten mit dem Ziel, bei der Arithmetik mit CX_VALUE die Umrechungsmöglichkeiten zu erweitern (unterschiedliche Währungen addieren usw.).
Eine Tabelle ist ein Objekte der Klasse CX_RATE_TABLE, ihre Elemente = die einzelnen Umrechnungs-Ratios sind CX_UNIT_RATE- bzw. CX_CURRENCY_RATE-Objekte. CX_UNIT_RATE::amount definiert Ratio und Einheiten.

Es gibt drei Ebenen, in denen Umrechnungs-Information im System gehalten wird:

Umrechnungstabelle registriert durch SetRate (Umrechnungen wie 5 Stück/Kiste)
Umrechnungstabelle(n) registriert durch RegisterRate (i.d.R. Währungsumrechnungen)
Feste Umrechnungs-Ratios (m in cm, kg in g, Minute in Sekunde usw.)

Die festen Umrechnungs-Ratios können nicht verändert werden.

Mit RegisterRate werden (i.d.R. beim Programmstart) Umrechnungstabellen angemeldet, die für das gesamte System gelten.
Das sind oft Tabellen für Währungsumrechnungen, z.B. von € zu $. Jedes RegisterRate fügt eine weitere Umrechnungstabelle in den Pool von Umrechnungstabellen ein. DeregisterRate meldet eine Tabelle wieder ab.

SetRate wird immer dann eingesetzt, wenn eine Tabelle für einen kurzen Zeitraum zusätzlich angemeldet werden soll, z.B. für Umrechnung von Stück in kg für ein bestimmtes Teil. Mit SetRate kann immer nur eine Tabelle angemeldet werden. Ein zweiter Aufruf von SetRate meldet zunächst die alte Tabelle ab, um anschließend die neue Tabelle anzumelden. SetRate mit NULL als Parameter meldet die Tabelle ab, ohne eine neue anzumelden.

All diese Umrechnungstabellen dürfen sich nicht widersprechen: Wenn in RegisterRate eine Umrechnung von € zu $ angemeldet wurde, darf eine solche Umrechnung nicht via SetRate angemeldet werden und umgekehrt.

Welche Umrechungstabellen wann aktiv sind, kann durch Einträge im Log-File verfolgt werden, siehe Logger-Name cx.rate. Damit wird die Suche nach Fehlern bei der Einheiten-Arithmetik unterstützt


Überschreibende Umrechnungen

Umrechnungen, die mit RegisterRate angemeldet werden, können dennoch überdeckt werden: Mit AddOverwriteRate können Umrechnungen angemeldet werden, die Umrechnungen aus RegisterRate überschreiben. Stellt man sich die verschiedenen Rate-Funktionen als Stack vor, fügt AddOverwriteRate eine Schicht zwischen SetRate und RegisterRate ein.

  • AddOverwriteRate überschreibt nur Umrechnungen, die mit RegisterRate angemeldet wurden; Umrechnungen, die mit SetRate angemeldet wurden, werden nicht überschrieben
  • Wird eine Umrechnung mit AddOverwriteRate angemeldet, ist die Umrechnung ab sofort bekannt, auch wenn sie kein Gegenstück in RegisterRate hat. Beispiel: Via RegisterRate wird ein €-$-Kurs angemeldet und via AddOverwriteRate ein €-¥- und €-$-Kurs. Der überschreibende €-¥-Kurs ist dem System jetzt ebenfalls bekannt: €-Werte können nun in ¥ umgerechnet werden (und umgekehrt).
  • Überschreibende Umrechnungen können mit DeregisterRate wieder abgemeldet werden; es gilt dann wieder die Umrechnung, die ursprünglich mit RegisterRate gesetzt wurde. Gibt es kein Gegenstück in RegisterRate, ist die Umrechnung unbekannt, und Umrechnungen führen zu einer Fehlermeldung.
  • Wird eine "Original"-Umrechnung (RegisterRate) abgemeldet, wirkt die überschreibende Umrechnung weiterhin. Wird die Umrechnung anschließend wieder angemeldet, hat das keine Auswirkung, da die Überschreibung weiterhin wirkt.
  • RemoveAllOverwriteRates meldet alle überschreibenden Umrechnungen ab.

Beispiel:

=> 100 cm/m, 1000g/kg, ... 1,50 $/€ 100 ¥/€ 2,00 CAD/€ 5 Stück/Kiste, 10 Kisten/Palette, ...
via SetRate         5 Stück/Kiste, 10 Kisten/Palette, ...
via AddOverwriteRate   1,50 $/€   2,00 CAD/€  
via RegisterRate   1,20 $/€ 100 ¥/€    
Feste Umrechnungstabellen 100 cm/m, 1000g/kg, ...        

Beim Systemstart wird der aktuelle €-$-Kurs von 1,20$/€ gesetzt. Nun soll ein Auftrag berechnet werden, bei dem ein €-$-Kurs von 1,50$/€ vereinbart wurde. Dieser Kurs wird mit AddOverwiteRate angemeldet (SetRate würde zu einem Widerspruch führen). Für jede einzelne Position im Auftrag wird die dazugehörige Umrechnungstabelle mit SetRate angemeldet. Bei einer Umrechnung (z.B. von € in $) geht das System die Ebenen der Reihe nach durch (im Beispiel: von oben nach unten) und rechnet in die gewünschte Einheit um, sobald eine passende Umrechnung gefunden wurde.

Umrechnungstabellen und Einheiten-Arithmetik - Hinweise zur Anwendungsprogrammierung

Arithmetischen Operationen (mit Einheiten) arbeiten aus Performance-Gründen nicht direkt mit den angemeldeten Umrechungstabellen. Für die InstantView-Programmierung (mit Fehlersuche) ist es gut, den internen Ablauf zu kennen:

Kurz zum Ablauf ohne Umrechungstabellen: alle arithmetischen Operationen mit Einheiten werden von einer internen Datenstruktur gesteuert (Name UnitTable). Die UnitTable hält Informationen wie
- dass m und s nicht addiert werden können, cm und km aber sehr wohl
- dass cm und km sich um 105 unterscheiden, bei s und min ein Faktor 60 mit einfließt ...
- dass 1N = 1kg * m / s2 ist, usw.

Nach einem Aufruf RegisterRate oder SetRate kennt das System eine neue Tabelle - tut aber weiter nichts damit, außer ein Flag für die Existenz neuer, noch nicht aktivierter Umrechungstabellen zu setzen.
Diese Flag testet jede arithmetischen Operation (mit Einheiten).
Ist das Flag aktiv, folgt ein Test, ob die Einheiten der aktuellen Rechen-Operation überhaupt in der Tabelle vorkommen. Wenn ja, wird interne UnitTable temporär verändert, und das Flag zurückgesetzt.

Beispiel: nachdem die Umrechnung 2g/0.5m aktiviert wurde, kann 0.5km + 7.5kg berechnet werden, und diese Operation läuft genauso ab wie 2min + 29s, oder 0.45m + 17inch ... - also auch mit der gleichen Performance!

Wird eine Tabelle wieder entfernt (DeregisterRate oder eine neues  SetRate), dann wird auch die entsprechende Änderung der internen UnitTable zurückgenommen. 

Der Test, ob eine Tabelle für die aktuelle Rechenoperation jetzt schon aktiviert werden muss, existiert auch aus Gründen der Performance, und der Performance wegen ist er unvollständig:
- wird die Tabelle gebraucht, wird sie in jedem Fall aktiviert
- wird sie nicht gebraucht, kann es vorkommen, dass sie trotzdem aktiviert wird.

Wenn eine Tabelle aktiviert wird, können folgende Fehler auftreten:
 

Fehler Beispiel Reaktion
einander widersprechende Umrechungen 2m / 4g,  3g / 3Stück,  7Stück / 8cm Fehlermeldung AMBIGUOUS_RATES
Null Ratio als Umrechung 0m / 2Stück wird ignoriert, aber Fehlermeldung im Log-File
Ratio als Umrechung 2m / 0Stück wird ignoriert, aber Fehlermeldung im Log-File
Umrechungsfaktoren der UnitTable können nicht mit der geforderten Genauigkeit berechnet werden Fehler im ClassiX®-System, muss dort gefixt werden, falls er jemals auftreten sollte Fehlermeldung RATES_TOO_COMPLEX

Die Fehler 0-Ratio und Ratio können das Ergebnis einer Berechung mit CX_FORMULA sein. Deshalb werden sie zunächst ohne Fehlermeldung ignoriert. Wird die Umrechung demnächst benötigt, erscheint der Fehler INCOMPATIBLE_VALUES.
 


Währungsumrechnungen

Währungsparitäten werden mit Objekten der von CX_UNIT_RATE abgeleitetn Klasse CX_CURRENCY_RATE beschrieben. Die hier beschriebene automatische Umrechung bei arithmetischen Operationen wird (wie bei allen anderen Einheiten) durch CX_UNIT_RATE::amount gesteuert. CX_CURRENCY_RATE::multiplyRate und dividerate sind für explizite Währungsumrechnungen vorgesehen.

Wenn im ClassiX®-System eine Umrechnung angemeldet wird, z.B. ein $-€-Kurs, dann wird die Einheit im Nenner zur "Basiseinheit", und die Einheit im Zähler mutiert zur Basiseinheit mit dem übergebenen Umrechnungsfaktor. Wird beispielsweise "1,50 $/€" angemeldet, mutiert die Einheit $ zur Einheit €. Wird umgekehrt "0,6667 €/$" angemeldet, würde die Einheit € zur Einheit $ mutieren. Wird zusätzlich noch der Kurs "2 €/CHF" angemeldet, wird die Einheit CHF zur Basiseinheit und die Einheiten $ und € mutieren zu CHF mit einem Faktor. Je mehr Währungsumrechnung angemeldet werden, desto größer können diese Faktoren werden - bis zu dem Punkt, wo sie zu groß werden, die Fehlermeldung "Angemeldete Umrechnungstabellen sind zu komplex" erscheint.
Um das zu verhindern wird
- ab ClassiX® 4.5.2.152678
  die Währung als Basis benutzt, auf die sich die meisten anderen beziehen

- vorher:
  die Währungsumrechnung nach Möglichkeit immer so im System abgelegt, dass die Standard-Währung (s. LOCALES.TXT und der Slot partner.currencyEnum im Mandant) die Basiswährung bleibt, egal, ob ein  €/$- oder $/€-Kurs angemeldet wird.

Garbage-Collection

Einheitentabellen schützen ihr Elemente nicht vor der Garbage-Collection. Alle transienten Umrechnungstabellen müssen daher in InstantView®-Variablen gespeichert sein.