A standard computed archive, which is structured, operates on a specific column of one or more structured archive objects.
Example of a calculation: Let's have a structured variable SV.Struct, which has columns Current and Voltage and is archived by the primary structured historical value H.Struct. Let's have a computed historical value object with the expression
H.Struct^Current * H.Struct^Voltage
and with the Archive size specified as H.Struct[0]^Current or H.Struct[0]^Voltage or SV.Struct[0]^Current). Such a computed archive will have the same number of rows as the structured variable or primary structured archive. For each row, the product of the items in the Current and Voltage columns will be calculated. For example, for the 3rd row, the expression will be H.Struct[3]^Current * H.Struct[3]^Voltage.
This functionality is usually sufficient, but what if we want to calculate, for example, the sum or maximum of all values in the Current column? Given that non-constant indexes are not supported for archive expressions (due to calculation optimization, we cannot use the local variable _i and write H.Struct[_i]^Voltage), we have 2 options:
- Write an expression containing all necessary rows: e.g. H.Struct[1]^Voltage + H.Struct[2]^Voltage + H.Struct[3]^Voltage
- Use LOOP_TEMPLATE syntax
The first option is simple but laborious (especially if the structured variable has a larger number of rows). Moreover, when changing the size of the structured variable, it is necessary to manually edit the expressions. Therefore, the second option was implemented, which essentially means writing a macro within the calculated historical value. This macro will be expanded and compiled by D2000 Archiv at startup, but also automatically when changing the size of the source archives (due to changing the size of the structured variable), so no modifications to the calculated archive are necessary.
Note: When writing, it is necessary to use the Extended syntax for the expressions (containing INIT and FINALLY as well as supporting local variables).
LOOP_TEMPLATE syntax
LOOP_TEMPLATE_START #LOOP_TEMPLATE_PAR#, low_range, high_range ;any code that can contain #LOOP_TEMPLATE_PAR# as an index of a structured archive, e.g. for implementing a sum ; _sum := _sum + H.Struct[#LOOP_TEMPLATE_PAR#]^Current LOOP_TEMPLATE_END
where
low_range is a constant
high_range is a constant or the name of a structured archive object (in which case it is replaced by the number of its rows).
All code between LOOP_TEMPLATE_START and LOOP_TEMPLATE_END is "expanded" for #LOOP_TEMPLATE_PAR# iterations from low_range to high_range
Note: Nesting (LOOP_TEMPLATE_START inside LOOP_TEMPLATE_START) is not supported, but a single computed archive can contain multiple LOOP_TEMPLATE constructs.
Examples:
Sum of values from column H.Struct^Current (only valid values are processed - see use of the \VLD attribute)
INIT REAL _sum LOOP_TEMPLATE_START #LOOP_TEMPLATE_PAR#, 1, H.Struct IF H.Struct[#LOOP_TEMPLATE_PAR#]^Current\VLD THEN _sum := _sum + H.Struct[#LOOP_TEMPLATE_PAR#]^Current ENDIF LOOP_TEMPLATE_END FINALLY _sum
Finding the maximum in the column H.Struct^Voltage
INIT REAL _max _max := H.Struct[1]^Voltage ; initialization (we assume that the structure has at least 1 row) LOOP_TEMPLATE_START #LOOP_TEMPLATE_PAR#, 1, H.Struct IF H.Struct[#LOOP_TEMPLATE_PAR#]^Voltage\VLD & H.Struct[#LOOP_TEMPLATE_PAR#]^Voltage > _max THEN _max := H.Struct[#LOOP_TEMPLATE_PAR#]^Voltage ENDIF LOOP_TEMPLATE_END FINALLY _max
Finding the maximum in the column H.Struct^Voltage (rows 5 - 30 only)
INIT REAL _max _max := H.Struct[5]^Voltage LOOP_TEMPLATE_START #LOOP_TEMPLATE_PAR# 5, 30 IF H.Struct[#LOOP_TEMPLATE_PAR#]^Voltage\VLD & H.Struct[#LOOP_TEMPLATE_PAR#]^Voltage > _max THEN _max := H.Struct[#LOOP_TEMPLATE_PAR#]^Voltage ENDIF LOOP_TEMPLATE_END FINALLY _max