Python Value Ranges
Information
- The following Python methods can be defined in the Value range attribute of all data items.
- They are used to calculate or process the value of a data item.
- You can use the full range of methods available in the Python API.
List of Functions
Method | Parameter | Return value | Comment |
---|---|---|---|
computeSqlValueRange(dt_name) | dt_name: String (SQL Alias which PLANTA uses for selecting the current record) | The return value of this function is used as a subselect in the original select for this table. So whenever PLANTA selects the current record, it embeds the return value of this function to it's initial select as a subquery. Since PLANTA uses aliases as table names, the function receives the currently used table alias as input parameter | User defined method is called before the selection process for the current table takes place. |
computeOutput(di) | di: Dataitem | Processed new value of the same type as the DI's type | User defined method is called for output value computation. If the DI is of the string type and the length of the computed value exceeds the DB length of the respective DI, the computed value will be trimmed to fit in. |
checkInput(di, oldValue) | di: Dataitem (current DI) oldValue:same type as the DI's type (old value of DI) | Boolean value that indicates whether the check was successful | User-defined method checks the validity of the entered value. |
processInput(di, oldValue) | di: Dataitem (current DI) oldValue:same type as the DI's type (old value of DI) | Processed new value of the same type as the DI's type | User defined method is called when setting the new value and allows to perform other actions in addition to the simple assignment of the value. Note: When an incarnation DI has a |
Note:
- PLANTA Server tries to convert the return values of the
computeOutput()
andprocessInput()functions
to the underlying DI's type. - When that fails, it issues a message box containing a Python error similar to the following one:
Python error in value range of DI041035 "di_customizing_name": computeOutput
<class 'TypeError'>:
argument must be string, not None
Note:
- Setting data field or data item values using the Python API will never trigger the
checkInput()
function of a Python value range, whileprocessInput()
will be evaluated.
Information
- The
checkInput()
function is evaluated beforeprocessInput()
is called. - Thus
checkInput()
will inhibit callingprocessInput()
when it does not accept the input. computeOutput()
is evaluated whenever the DI's value is read. There may be no evaluation when PLANTA Server is in echo off mode (usingppms.echo_off()
orppms.echo_disabled()
), as PLANTA Server refreshes the DI values during the serialization step (which is skipped in echo off mode).
Dependency Tracking
Information
- Since it is impossible to "auto-detect" all the possible source data references of the respective function, it is necessary to specify them.
- Every function has an dependency attribute,
deps
which contains a tuple of DI source data references. PLANTA then can assure that all references are available when ever this DI is calculated.
- Every function has an dependency attribute,
- Special feature of the
computeOutput()
function:- The function is called whenever a source reference changes, this means that the result of the
computeOutput()
function is always up to date according to its source references.
- The function is called whenever a source reference changes, this means that the result of the
Details
- Following functions must have dependencies:
computeOutput()
processInput()
checkInput()
- The tuple of dependencies can contain
- DI references (DIs from the same record): 'DI000123'
- Variable references (@G, @D, @L, @M): '@G15','@L1'
- '*' meaning that the value has to be recalculated in any case. This will have bad influence on the performance. You should therefore use this feature with caution.
- It is not necessary to add the DI containing the value range to the dependencies.
- Example: when the
computeOutput()
is customized on DI123456, it is not necessary to add DI123456 to the dependencies.
- Example: when the
- If the DI only interacts with itself, simply add
deps = ('',)
- If there is only one DI in the dependency, add
deps = ('DI012345',)
- It is also possible to use a DI's property name (python ID/customizing name) as a dependency.
- When referring to a sibling data item in the same data table, use the plain property name, such as
deps = ('name',)
. - When referring to a data item from a foreign data table, use that data table's entity name in entity.property notation, such as
deps = ('Module.name',)
.
- When referring to a sibling data item in the same data table, use the plain property name, such as
- Although it is possible to use both DI IDs and Python IDs in the dependencies, PLANTA recommends that, for uniformity purposes, you only use only one of them.
- "DI" has to be capitalized, e.g. it has to be
DI000000
instead ofdi000000
.
The tuple is specified in the source code of the python value range like this:
import random
def computeOutput(di):
list = ppms.uvar_get('@M6')
return random.choice(list)
computeOutput.deps = ('@M6',)
- In this case,
computeOutput()
depends on @M6 variable.
Examples
checkInput
def checkInput(di, oldvalue):
rec = di.get_dtp_record()
compl_in_perc=rec.compl_in.get_value() #DI040154
compl_on=rec.compl_on.get_value() #DI040155
compl_by=rec.compl_by.get_value() #DI040156
if oldvalue == 0:
if compl_in_perc > 99 and compl_on > 0 and compl_by != "":
return True
else:
return False
else:
return True
# either:
#checkInput.deps = ('DI040154', 'DI040156', 'DI040155', )
# or:
checkInput.deps = ('compl_in', 'compl_on', 'compl_by', )
computeOutput
def computeOutput(di):
rec = di.get_dtp_record()
panel_title = rec.get_di_by_id(57816).get_value()
mod_title = rec.get_di_by_id(1588).get_value()
if panel_title == None or panel_title == '':
return str(mod_title)
else:
return str(panel_title)
computeOutput.deps = ('DI057816', 'DI001588', )
processInput
def processInput(di, oldvalue):
dtpRec = di.get_dtp_record()
diVal = di.get_value()
name = dtpRec.name.get_value() #DI001589
dt_id = dtpRec.dt_title.get_value() #DI003389
if name == "":
dtpRec.name.set_string_value(str(dt_id))
else:
dtpRec.name.set_string_value(str(name))
return str(diVal)
# either:
#processInput.deps = ('DI001589', 'DI003389', )
# or:
processInput.deps = ('name', 'dt_title', )
computeSqlValueRange
def computeSqlValueRange(dt_name):
"""Calculate the number of data area assignments"""
val = """
select count(*)
from DT406
where di000969={0}.di000198
""".format(dt_name)
return str(val)