Zum Hauptinhalt springen

Beispiel 6 - Tabelle für Wertebereiche

Aufgabe:

Zu einer Messgröße soll ein beschreibender Text einer Kategorie gefunden werden. Dazu wird z.B. die Messgröße TEMPERATURE mit einer Tabelle gegen Grenzwerte verglichen und ein entsprechender Text ausgelesen. Zusätzlich soll die Lage des Messwertes relativ zu den Grenzen der Kategorie bestimmt werden.

Lösung:

1. Erstellen der Tabelle

Wie schon in Beispiel 5 wird eine Tabelle mit den Kategorien im Ressourcen-Bereich des Mathemoduls aufgestellt. Die folgende Tabelle sei unter dem Ressourcen-Tag "Kategorien" angelegt:

Name         | T_Min           | T_Max
===========================================
extrem kalt | * | -10.0
sehr kalt | -10.0 | 2.0
kalt | 2.0 | 8.0
kühl | 8.0 | 15.0
normal | 15.0 | 21.0
warm | 21.0 | 28.0
heiß | 28.0 | 34.0
sehr heiß | 34.0 | 46.0
extrem heiß | 46.0 | *

2. Implementierung im Formeltext

_rowIdx = selectRow(TEMPERATURE, TEMPERATURE, {
table: 'Kategorien'     // verpflichtend
, keys: ['>= T_Min', '< T_max']  // verpflichtend
});
KatName = getField(_rowidx, {table: 'Kategorien', field: 'Name'});
_TMin = getField(_rowidx, {table: 'Kategorien', field: 'T_Min'});
_TMax = getField(_rowidx, {table: 'Kategorien', field: 'T_Max'});
_width = max(0.01, _TMax - _TMin);
RelPos = (TEMPERATURE - _TMin) / _width;

Verwendete Funktionen

Erläuterung:

Die Tabelle wird zeilenweise gelesen. Leerzeilen oder solche, die mit 3 gleichen "Linien"-Zeichen (hier z.B. '===') beginnen, werden übersprungen. Die Zeilen werden an den Default-Trennzeichen (diese enthalten auch ein | Zeichen) auseinander geschnitten, vorne und hinten von überflüssigen Leerzeichen befreit und als Variant interpretiert. Die erste Zeile liefert die Bezeichnungen für die Spalten (= Felder). Alle weiteren Zeilen liefern die Datenelemente zum Vergleichen oder Auslesen.

Mit selectRow() wird nun in der Tabelle eine passende Zeile gesucht und deren Index als Ergebniswert zurückgegeben. Dazu wird der Schlüsselwert, hier z.B. TEMPERATUR als <dbl>, zweimal an die Funktion übergeben, da er gegen zwei Spalten verglichen werden muss. Mittels keys werden die Felder T_Min und T_Max definiert, aus denen die Grenzwerte der Kategorien entnommen werden sollen. Die Namen der Felder werden um entsprechende Vergleichsoperatoren ergänzt. Eine Zeile erfüllt die Bedingung also nur dann, wenn TEMPERATURE >= T_Min und TEMPERATURE < T_Max zutreffend ist. Hinzu kommt allerdings auch noch die Funktion für anyKey, die dem Wertevergleich vorgelagert ist. Damit ergibt sich folgende Bedingung:

   ((T_Min == anyKey) || (TEMPERATURE >= T_Min)) 
&& ((T_Max == anyKey) || (TEMPERATURE < T_Max))

Damit wird eine sehr einfache Abbildung der Randbereiche möglich, ohne konkrete Endtemperaturen für die Extrema anzugeben.

Mittels der getField() Funktion wird aus der gleichen Tabelle der Name der Kategorie ausgelesen. Falls der Index _rowIdx < 0 ist, wurde zuvor keine passende Zeile gefunden und der mit notFound angegebene Variant würde an die Variable weiter gegeben. Diese Angabe fehlt, sodass hier einfach false das Ergbis wäre.

Entsprechend werden die Grenzwerte _TMin und _TMax der Kategorie, die zuvor für die Suche verwendet wurden, aus der Tabelle gelesen und es wird die Breite _width der Kategorie berechnet. Falls keine Zeile gefunden wurde, würden die Grenzwert-Temperaturen beide auf false stehen (== 0.0) und somit die Differenz auch Null ergeben. Da später durch diese Zahl geteilt werden soll, wird mit der max() Funktion dafür gesorgt, dass die Breite _width niemals Null werden kann.

Die relative Position RelPos in der Kategorie wird als Quotient der relativen Temperatur zur unteren Bereichsgrenze und der zuvor bestimmten Breite bestimmt.