Example 6 - Table for value ranges
Task:
A descriptive text of a category is to be found for a measured variable. For example, the measured variable 'TEMPERATURE' is compared with a table of limit values and a corresponding text is read out. In addition, the position of the measured value relative to the limits of the category is to be determined.
Solution:
1. Create the table
As in example 5, a table with the categories is set up in the resource area of the math module. The following table is created under the resource tag "Categories":
Name | T_Min | T_Max
===========================================
extremely cold | * | -10.0
very cold | -10.0 | 2.0
cold | 2.0 | 8.0
cool | 8.0 | 15.0
normal | 15.0 | 21.0
warm | 21.0 | 28.0
hot | 28.0 | 34.0
very hot | 34.0 | 46.0
extremely hot | 46.0 | *
2. Implementation in the formula text
_rowIdx = selectRow(TEMPERATURE, TEMPERATURE, {
table: 'Categories' // mandatory
, keys: ['>= T_Min', '< T_max'] // mandatory
});
CatName = getField(_rowidx, {table: 'Categories', field: 'Name'});
_TMin = getField(_rowidx, {table: 'Categories', field: 'T_Min'});
_TMax = getField(_rowidx, {table: 'Categories', field: 'T_Max'});
_width = max(0.01, _TMax - _TMin);
RelPos = (TEMPERATURE - _TMin) / _width;
Functions used
Explanation:
The table is read line by line. Empty lines or those that begin with 3 identical "line" characters (here e.g. '===') are skipped. The lines are cut apart at the default separators (these also contain a |
character), freed from superfluous spaces at the front and back and interpreted as a variant. The first line provides the names for the columns (= fields). All further lines provide the data elements for comparison or reading.
With selectRow()
, a suitable row is now searched for in the table and its index is returned as the result value. To do this, the key value, here e.g. TEMPERATURE
as <dbl>
, is passed to the function twice, as it has to be compared against two columns. The fields T_Min and T_Max, from which the limit values of the categories are to be taken, are defined using keys. The names of the fields are supplemented by corresponding comparison operators. A line therefore only fulfills the condition if TEMPERATURE >= T_Min
and TEMPERATURE < T_Max
is applicable. However, there is also the function for anyKey, which is upstream of the value comparison. This results in the following condition:
((T_Min == anyKey) || (TEMPERATURE >= T_Min))
&& ((T_Max == anyKey) || (TEMPERATURE < T_Max))
This enables a very simple mapping of the boundary areas without specifying concrete end temperatures for the extremes.
The name of the category is read from the same table using the getField()
function. If the index _rowIdx < 0, no suitable row was found beforehand and the variable specified with notFound would be passed on to the variable. This specification is missing, so that false would simply be the ergbis here.
Accordingly, the limit values _TMin
and _TMax
of the category that were previously used for the search are read from the table and the width _width
of the category is calculated. If no row was found, the limit temperatures would both be false (== 0.0) and therefore the difference would also be zero. As this number is to be divided later, the max()
function is used to ensure that the width _width
can never become zero.
The relative position 'RelPos' in the category is determined as the quotient of the relative temperature to the lower range limit and the previously determined width.