General

What is Python?

Python is a programming language which enables several programming paradigms. It supports object oriented, aspect oriented, and functional programming.

Why Python?

Python has a perfectly simple syntax and can be integrated smoothly into C.

Where can I find a description of the Python functions provided by PLANTA?

The functions are described in the Python API.

What is a DTP?

DTP means Data Table Pool. Here, the PLANTA software stores all records loaded from the database (e.g. via module search or using the Python functions: search_record, get_children etc.). The data sets are then held there for display in one or more modules.

What is an MTS record?

MTS means Module Tree Structure.

  • MTS records are module records, i.e., the records that are displayed in the module.
  • Exactly one DTP record belongs to each MTS record.
  • Example: A project with all of its fields

How is the I-number for an I-text generated?

Based on the entry in the schema-specific counter value table PLANTA generates a new I-number for an I-text. Depending on the license and the I-number DI, the value of the counter value 1 DI is read out and taken for a new I-text.

  • Example for Q2B
    • Counter value table: DT 396 Counter Value Q2B
      License data item: DI 008150 License = Customer License
      DI data item: DI 008152 DI = 000985 (I-No. DI from DT434 I-No. Q2B)
      Counter value data item: DI 008164 Counter value 1

Has anything changed in I-texts compared to releases < 39?

In PLANTA project, I-texts are only stored in the schema specific I-text table. The I-number table is no longer maintained and filled.

Why is no automatic number created?

An automatic ID will only be created when all foreign key DIs of the record and, if available, all mandatory data fields are filled with valid values.

Note

  • A record with ZERO value is only a valid value if the ZERO permitted parameter is activated for the respective data table (this change can only be made by PLANTA).

Settings

How do I set up the PLANTA e-mail function (in order to directly send e-mails)?

In the Global Settings (total) module or in the Global Settings (Project) module, the correct IP address of the SMTP server and a system e-mail address must be specified. Further information.

How can I change the system title?

The system title (in the title bar) is stored in the System name field in the License, System Parameters, and DB Instances module and can be changed there. Note

  • Alternatively, it can also be set to the runtime of the system title via the following Python function:
ui_set_system_title(title: string)
CODE
See also: Python API

Tip

  • In order to distinguish different sessions, the currently logged-on user and the PID can be displayed in the system title.
    • If the MOD0099QC standard menu is used:
      • open the Python Macros module and change the CHANGE_TITLE variable in the on_load method from CHANGE_TITLE=FALSE to CHANGE_TITLE=TRUE
    • If an individual user menu is used,
      • open the Python Macros module and insert the following line in the on_load method of the user menu:
      • The following lines must, like the other lines, be indented by four spaces each in the on_load method.
PID = str(os.getpid()) ppms.ui_set_system_title('Systemtitel' + ', PID: ' + PID + " - " + ppms.uvar_get("@1"))
PY

Details

  • When you launch PLANTA project for the next time, the PID is displayed in the system title.
    • The PID is part of the log file as well, so all log files can always be ascribed to the corresponding session.

How can I change the editor used to edit macros, value ranges, etc.?

In several modules, there is a button for opening an editor. In the Modules module, this can be done by clicking on the Open Python macro editing button. Which editor is used for this is stored in the py_editor global setting in the Global Settings module. If an incorrect path is specified there, the Error executing python script: The system cannot find the specified file message will be displayed.

How can I store/use my own product logo (brand logo) throughout the system?

  • In order to store an individual product logo,
  • In order to exchange the logo in the default print areas headline (header):
    • Open the data area with Positioning = 3 (Print area: header) of the module which is specified in the Skin of the logged-on user in the Module for print areas data field .
    • substitute the ID of the OLE object with that of the newly created one.
  • The logo in individual print areas may have to be substituted the exact same way.
  • In order to use your own product logo throughout the system:
    • create a new OLE object for the product logo and assign it to the Product logos category.
    • Switch to the Product Logos module variant.
    • For the newly created OLE object, click on the Use as logo throughout the system button.

Questions on the behavior ("Why?")

Why is a DI not displayed in a module?

  • The DI is in Window 9.
  • The DI is in a mask without mask position.
  • The DI is virtual and deactivated (Activated (DT412) = ), the data table which contains the DI is deactivated (Activated (DT415) = ) or the schema which contains the DI is deactivated (Activated (DT420) = ).

Why is a newly customized context menu not displayed?

The respective data field has to be customized in one of the visible windows (windows 1-3).

In what way are the field width, indent, and window 1, 2 and 3 width constants related?

  • The values for DF width and indent are specified in tenth millimeters of the same unit.
  • The specification in Width W1 etc. is no size but only serves to calculate the window's share of the total screen width.
    • Since the widths of screens (and thus the &bdquo;width available&ldquo; for the panel) differ, this is no fixed value.

What are implicit fetch exits?

In case data from parent data tables is to be displayed, no exit must be customized. The data item itself can be included in the data area. This is called an implicit fetch exit.

See also: Exits

Why are fields not displayed in a new window?

If a field is to be displayed in window 1 (or window 2), you have to enter a value in the Width W2 (or Width W3) data field in the Other Module Parameters module.

  • When creating a new module in the Modules module, a width will be set for window 1 via the standard value in Width W1. It is therefore not necessary to specify a width explicitly.

Note

  • If the Width Wx field (Width W1, Width W2 , Width W3 ) is filled but there is no data field with Window = x in the module, window x will be displayed (empty) anyway.

Why are entered and saved values not displayed below the scale after reloading?

For modules in which you want input to be possible in a projection you have to check whether the Output parameter is deactivated in the data area which contains the projection data items. If not, the value cannot be saved (it is displayed but after restart you can see that it has not been saved).

Why can a newly created DI not be used/Why do changes made to the DI not take effect?

After a change has been made to a data item of the system databases (Q1 and Q2 schemas), the server must be reloaded. In the Data Dictionary and in the Data Items module you will find the Server restart button.

  • The only exception are changes made to
    • I-texts, e.g. of the DI name or
    • of value ranges (also VR type )
  • Meta data of the Data Dictionary is contained in the target directory. The POJO classes responsible for this are not generated anew by restarting the PLANTA service. The target directory must be deleted in order for the POJO classes to be generated anew when restarting for the next time.

I cannot select any value from the listbox. Why is that?

For the value to be copied from the listbox, the LB: value transfer parameter must be activated in the listbox module.

Tip

Why can't I click on any fields in the form editor although customizing mode is activated?

There are two possible reasons:

  • The data area in which the fields are located
    • has not yet been activated by clicking on it (the data area is still displayed in green) or
    • is no mask (Layout = 0 or 1). The data area is displayed grayed-out.
      • Tip: You can change the layout by right-clicking and selecting the respective entry.
See also: Customize Forms

Why are alternating shadings displayed in black?

In the respective data area, the Color intensity W1 DI (Color intensity W2 or Color intensity W3 ) is filled, however the Altern. color W1 DI (Altern. color W2 (Altern. color W3) is not. If this field is empty, the color black (in the specified intensity) is used for alternating shading.

Why does a filter criterion not apply in recursive structures as expected?

When customizing with recursive structures, check the Apply filter to parameter. This controls on which level in the recursive structure the filter criteria take effect.

Why does a filter criterion not take effect?

Filter criteria can be deactivated via the Filter deactivated parameter.

Why are the charts not displayed in a copied module?

  • In the chart data field in the da_id='’ parameter in the Data field configuration field you can define which data area the data for the chart stem from.

Example

"""Define Chart - Properties"""
da_id='045968'
PY
  • If a module is copied, the data area IDs change. Therefore the data area ID of the source module is replaced by that of the new one.

Tip

  • The easiest way to find out which data area ID must be used, is to look up which data area was used in the source module and which data area of the copied module equates to it.

Why can a file which was copied from the template not be opened in a hyperlink field?

The path of the template specified in the customizing is possibly not correct. This path is stored in the sub DI with the CR function.

Why is the new version of a changed variable no longer displayed in the system after the client was restarted?

  • In PLANTA project 39, variables behave just like in the previous releases (like e.g. 3.7 and 3.8).
    • This means that they are loaded to the main storage when the session is started, provided that they are not directly changed in the database, their values apply only to the current session.
    • Hence, by increasing a variable via Python macro, only the value in the main storage is changed, not the one saved in the database.
    • After closing the session and restarting, the value in the main storage expires and the value from the database is fetched again.
    • The same applies if a second session is opened simultaneously. Here, the value stored in the database is imported as well.

Why can a file which was copied from the template not be opened in a hyperlink field?

This problem occurs in combination with the File [path specification] cannot be opened. Invalid path or file does not exist. error message. It is displayed when you try to open a file copied from the template on the hyperlink field while the template path specified in the customizing is not correct. This path is stored in the sub DI with the CR function.

Customizing Tips ("How?")

What can I do in order to improve performance?

  • If most modules are slow,
    • check whether the environment meets the hardware requirements (specifically: main memory dimensioning, latency between database and application server and database performance (e.g. indeces).
  • If a specific module is too slow,
    • check the module construction. E.g.: does the module contains data areas or data fields which are not required?
      • For performance reasons, only customizing objects which are actually required should be embedded in a module in general (i.e. data areas, data fields).
      • The data in data areas with Never show = are loaded as well, i.e. it is not sufficient to set a non-required data area to Never show = .
    • Verify filter criteria (Filter from, Filter to, Regular expression)
      • Are there filter criteria on real data fields or only on virtual data fields?
        • Reason: Filter criteria on real data items are evaluated in the database and filter criteria on virtual data items are evaluated in the main storage, i.e., if filter criteria are only set to virtual data items in a module, all data is loaded into the main storage first, in order to be restricted to the filter criteria there.
        • The same applies to regular expressions.
      • Most value ranges and fetch exits can be converted to a Python value range via the computeSqlValueRange() function. The database recognizes fields with such values. Therefore filter criteria on these fields do not only take effect in the main memory but on the database.
    • check whether numerous implicit fetch exits are used in this module.
      • For performance reasons, implicit fetch exits should not be used in modules with large amount of data.
    • check whether value ranges are used in this module in which the DtpRecord.get_children() Python method is used without specifying a DI list.
  • If a panel loads slowly or the loading of the tabs stagnates for certain submodules,
  • If a particular customized function is slow,
  • Furthermore,
    • frequent or recurring database access via customizing, e.g. by setting up caches, should be avoided.
    • should only be used as dependency in value ranges if this is necessarily required for functional or technical reasons. Reason: Value ranges with dependency are recalculated upon every action in the system, i.e. also if another module is opened for instance.

How do I have to specify paths in the client_exec() Python function?

There are several options for specifying a path. ( The following path specification variants are exemplified by a model excel export.)

  • Variant 1:
ppms.client_exec("""
env = get_Env()
mod = env.ActivePanel.ModuleManager.__getitem__('%s')
doc = mod.CreateExcelExportDocument(fullExportPath = 'C:\\\\folder\\\\subfolder\\\\file name')
env.GenerateExcelFile(doc)
""" % uid)
PY
  • Variant 2:
ppms.client_exec(r"""
env = get_Env()
mod = env.ActivePanel.ModuleManager.__getitem__('%s')
doc = mod.CreateExcelExportDocument(fullExportPath = 'C:\\folder\\subfolder\\file name')
env.GenerateExcelFile(doc)
""" % uid)
PY
  • Variant 3:
ppms.client_exec("""
import os

env = get_Env()
mod = env.ActivePanel.ModuleManager.__getitem__('%s')
doc = mod.CreateExcelExportDocument(fullExportPath = os.path.normpath('C:/folder/subfolder/file name'))
env.GenerateExcelFile(doc)
""" % uid)
PY

Notes

  • The specification of the file ending is optional.
  • If the file name is specified without any path, the file is stored in the My Documents folder (=%USERPROFILE%\My Documents=).

How are the currency formats customized by default?

Currency formats with two decimal places are used throughout the standard system. If you want to adjust this format for individual modules or data fields, this can be done at data field level (Format ID field).

How is the height and width of listboxes adjusted?

  • The height (or width) of listboxes must not be adjusted manually but is calculated on the basis of the number of values (or width of the fields).
  • There is a minimum and a maximum height or width.

How can line breaks be adjusted in a data field?

Via the Multiline parameter, both manual and automatic line breaks can be inserted or displayed.

How can I customize a frame (a blue one in the standard) for a listbox?

The colors for the frame surrounding a listbox is stored in the Background symbol parameter in the Further Module Parameters module.

Note

  • The blue color in the standard has the symbol ID 001975.

How can the content of the current @L-variable (list variable) be displayed?

A user with customizing rights can consult the current @L-values by clicking on the Show current @L-values button in the Variables module.

How can the content of a specific variable be displayed?

A user with customizer rights can access the content of a variable by clicking on the Show variable content and entering the corresponding variable in the Variables module.

How can the alignment of the data field content be changed?

This can be done by setting the Alignment parameter to data field level.

How can I enhance the performance of the resource structure customizing?

By not customizing the structure with a data area from DT469 Resource structure, but customizing a respective relation in the Recursive relation field in the data area of DT467 instead.

How can I customize a newly opened submodule as a tab behind the main module?

The dock_to_module parameter in the open_module() method must be set to the value as the UID of the module to which the submodule is to be docked.

Example

mod_obj = ppms.get_target_module()
mod_obj.open_module('ID des Moduls',forced_status=2,dock_to_module=mod_obj.get_uid(),dock_style=0,foreground=0,focus=0)
PY
  • Explanation:
    • mod_obj is the main module to which the submodule is to be docked.

How can I read a record from the DTP or fetch it from the database to the pool?

For this purpose, the search_record(dt_num, key_list, di_list, dblookup) Python method is used.

Parameters:

  • dt_num: ID of the data table
  • key_list: List of the Python Ids of the 1:1 key of the data table
    • In compound keys, all DIs (same order as in the data table) must be specified.
  • di_list: List with the DI-IDs (without leading zeros) which are to be contained in the DTP
    • Here, all DIs that are accessed in the further calculation are to be specified.
  • dblookup: Specifies whether the value is to be read out from the database if the record does not exist in the pool.

Notes

  • The di_list list must contain at least one DI.
  • 1:1 keys and foreign keys are loaded into the DTP automatically, even if they are not contained in the di_list list.

Examples

  • Example 1:
pr_id = ‘4711’

rec461=ppms.search_record(461, [pr_id], [1052,1062], True)
PY
  • Explanation
    • The rec461 variable now contains a DTP record with the following DIs (in addition to the primary and foreign keys of DT461)
      • 001052 Main Project ID
      • 001062 Manager
  • Example 2:
pr_id = ‘4711’
task_id = ‘2010’
res_id = ‘R1’

rec466=ppms.search_record(466, [pr_id,task_id,res_id], [1510], True)
PY
  • Explanation
    • The rec466 variable now contains a DTP record with DI 001510 _Actual load_ (in addition to the primary and foreign keys of DT466).

How can I have two (or more) data fields displayed behind a bar?

In order to have two (or more) so called auxiliary bar fields displayed,

  • enter the Python ID of the bar data field for both data fields in the Bar link (DF Python ID) parameter,
  • Define the auxiliary bar field position in the Dock point parameter, e.g. 1 Start point is bar end.
  • X pos. of the 2nd data field = X pos. of the 1st data field + DF width of the 1st data field + 1

How can I have a data field displayed without heading?

  • If the data area has a horizontal layout (Layout parameter = 0) or a vertical layout (Layout = 1),
    • enter a protected space (Alt + 0160) in the DF heading parameter in the Data Areas module for the data field the heading of which you do not want to have displayed.
  • If the data area is a form (Layout = 2), you can hide the heading
    • by activating the customizing mode menu item in the module by clicking on the heading and pressing DEL or
    • by deleting the X/Y positions of the heading in the _Layout_ module variant in the Data Areas module.

Customizing in Two Sessions

If the DTP_CUSTOMIZING_MODE parameter in the planta_server.conf is set to =1, you will only see customizing changes in the current session and in all sessions started afterwards but not in those which are already open.. The advantage of this setting is a better performance starting from the second call. If the parameter is deactivated, you will also see changes in all already opened sessions after restarting the module. However, every following module call will take just as much time as the first one. Reason: If the parameter mentioned above is activated (=1), upon initial loading, the data from the corresponding data tables is loaded in the DTP cache and in every following access will not use the data from the database but from the DTP cache.

CTRL + F3 for opening the current data area/F9 for opening the module

Only users with customizer rights = can

  • open the customizing of the current module in the Modules module by pressing F9
  • open the focused data area in the Data Areas module by pressing CTRL + F3.

Note

  • It is no longer sufficient to only have access to customizer menu items in order to access the customizing modules mentioned above.

Automatic Creation of Incarnations

In the Data Dictionary you have the option to create incarnations automatically.

See also: Incarnations

Convert Round Value Ranges to =computeSqlValueRange()= value ranges for Performance Reasons

A round value range like, e.g., DI003394, may possibly be critical with regard to performance. We therefore recommend that you convert it to a computeSqlValueRange() value range.

Old example

(ROUND(DI001510,2) != 0.00) ||
(ROUND(DI002669,2) != 0.00) ||
(ROUND(DI002671,2) != 0.00)
PY

New example

def computeSqlValueRange(dt_name):
    val = """case  
                when nvl(DI001510,0)+nvl(DI002669,0)+nvl(DI002671,0) &gt; 0 then 1
                when nvl(DI001510,0)+nvl(DI002669,0)+nvl(DI002671,0) = 0 then 0
            end"""
    return str(val)
PY

Python: How can I add elements to a list?

  • Variant 1
value_list = [["R1"],["R2"],["R3"]]
f_list = []
i = 0
for rec in value_list:
    f_list.append(value_list[i][0])
    i = i + 1
PY
  • Variant 1 (structured)
value_list = [["R1"],["R2"],["R3"]]
f_list = []
for rec in value_list:
    f_list.append(value_list[0])
PY
  • Variant 1 (one-liner)
value_list = [["R1"],["R2"],["R3"]]
f_list = [rec[0] for rec in value_list]
PY

How can I overwrite menu items with Python functions?

from ppms import ppms
from ppms.module_subclasses.base_class import Base
from ppms.constants import MENU_FILTER, MENU_RESET, MENU_SAVE

class ModuleThatOverwritesSave(Base):
    def menu_override(self, menu_id):
        if menu_id == MENU_SAVE:
            ppms.ui_message_box('No saving allowed!')
            return self.MENU_OVERRIDE_SUCCESS

        # Don't allow resetting as that brings up a save prompt
        elif menu_id == MENU_RESET:
            return self.MENU_OVERRIDE_SUCCESS
            
        return super(ModuleThatOverwritesSave, self).menu_override(menu_id)
PY

How can I have menu items 154/151 (mark all/unmark all) mapped in Python

Objective

  • To map menu item 154 (Mark all) and 151 (Unmark all) in Python

Example Mark all

# get module object
mod_obj=ppms.get_target_module() 

#mark all records of all datareas in the module
with ppms.echo_disabled():
    [[mts_rec.mark() for mts_rec in mts_rec_list]for mts_rec_list in [da_obj.get_records() for da_obj in mod_obj.get_das()]] 
PY

Example Unmark all

# get module object
mod_obj=ppms.get_target_module() 

#unmark all marked records of all dataareas in the module
with ppms.echo_disabled():
    [[mts_rec.unmark() for mts_rec in mts_rec_list]for mts_rec_list in [da_obj.get_marked_records() for da_obj in mod_obj.get_das()]] 
PY

How can I extend the Copy Schedule function?

To do so, you have to adjust the Copy Schedule module.

Example: Additionally, the todo item notes are to be copied.

  • Create a data area from DT805 Todo item notes.
    • Tip: copy the corresponding data area from the schedule (in the standard system: 0099AN).
  • Allocate a DA Python ID (e.g. open_item_notices_area).
  • Embed the data area in the Copy schedule (0099J9) module.

Note

  • Only values from input data fields (data field behavior, e.g., i, i2 or li) are copied.

How can I have the &Sigma; sigma sign displayed?

Customize the symbol with "Font" = "Symbol", store it on the required field or heading and write S in it.

How can I embed an individual user menu?

The standard user menu module 0099QC can be copied and adjusted individually. The copy of the user menu can be stored in the Skins module in the skin of the users in the User Menu field.

How can the splash screen be exchanged?

  • Replace the splash.png file under %client_folder%/Resources/ by the provided file.

How can texts in e-mails; e.g. signatures, be changed?

For e-mails you can define texts which are automatically inserted when you create an e-mail, e.g. for signatures.

Procedure

  • Open Customizer → Module CustomizerModules module
  • Insert the module ID 009A3F
  • Open the DA041375 Stakeholder data area.
  • Unfold the tree structure of DI026625 E-mail
  • In the subject_text and body_text parameters in the Data field configuration, texts to be inserted automatically can be stored for subject and e-mail content.

Messages

What does the Attention: Your changes on a customizing table force an update of the Java POJO classes. Please inform the server development department!

This message is displayed if a new real DI is created in a data table of the Q1B and Q2B schemas. The creation, modification, and deletion of data items in data tables of the Q1B and Q2B schemas may only be carried out by PLANTA. The only exception is data table DT400, which can contain custom DIs as well.

What does the IE: (MV creation/application/saving) "[Module variant ID]" uses these unsupported DIs: DI [Data item ID]</em> message mean?

If you change a parameter for a module variant in the Option module for MV, the editing of which is not supported by the program, the above mentioned message is displayed. Further information...

Upon customizing of a Python value range, an error message is displayed. What does it mean?

Generally, there are different types of error messages.

Examples of error messages

  • IE: "deps" attribute of computeOutput() function in WB code of DI[Dataitem-ID] must be a tuple. The function won't be available.
    • Meaning: You have to specify a tupel in the dependency. I.e., if the function is to have one dependency only, you have to specify it as follows: deps = ('Di[data item ID],). Further Information on dependencies
  • IE: processInput() function must take exactly 2 arguments (!DataItem reference and old DI value), but in VR code of DI [data item ID] it takes 1 argument(s) and thus won't be available.

Note

What does the Python error in macro [macro ID]. Class 'SyntaxError': ("Non-UTF-8 code starting with...)

These error message means that forbidden characters are used in the Python code of the corresponding macro, e.g., umlauts. This does not only apply to Python code in macros but to any Python use case.

  • Forbidden characters must not be used in comments on the Python code either.

Why is the Scale assignment not possible: MOD [module ID], DA [data area ID], horizontal bar DF [data field ID] (DI [data item ID]) message displayed when opening a module?

This message is displayed if no scale area is assigned to a module, or the DA class parameter is unequal 1 (scale area).