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.