Skip to end of metadata
Go to start of metadata

Python Overview

Visual Enterprise Generator uses the IronPython implementation of Python, which is a Python interpreter that has access to the Python standard library as well as the complete set of .NET Framework APIs.

Python standard library support is only available in Visual Enterprise Generator version 8.0 SP1 or later. Prior version of Visual Enterprise Generator did not include the Python standard library out of the box.

SAP Functions

This is a set of libraries to simplify interoperability with SAP ERP systems from within Python scripts is also provided and available to Python scripts executing in callback or custom script operation contexts. For more details, please see the VDI SDK Reference describing all of the Python APIs available to your scripts.


Python Operations

The Python operations shipped with Visual Enterprise Generator fall broadly into two categories: Callback script operations, and custom scriptable operations.

Both contain Python script code that is executed as during regular Visual Enterprise Generator process execution, however callback operations are predefined operations provided by SAP, whereas custom scriptable operations can be operations created by users.

There is also another difference – The callback operation will include one or more well-known Python functions in the script code, and when the operation executes, it will call these Python functions as part of execution.

When and how it calls them, is operation-specific, and will be documented in the documentation for the operation.

For example, a callback operation may invoke a Python function zero times, or many times, during one operation execution.


Visual Enterprise Generator includes a Python interpreter that supports Python 2.7 syntax (IronPython).  From version 9.11 IronPython version was upgraded to 2.7.11

Python scripts can be executed by Visual Enterprise Generator inside the context of an operation inside a process. This provides a way to programmatically extend Visual Enterprise Generator when more advanced scenarios need to be supported; for example, special processing of complex XML documents, calling web services or calling SAP RFC functions on your ERP system.

In both cases, the operation has a parameter of the Python scriptblock type, which has a code sub-parameter that containing the Python source code as its value.

In addition to the Python standard functionality, additional SAP APIs are provided to the Python script in its scope to simplify integrating the script with the surrounding SAP 3D Visual Enterprise Generator process and the SAP 3D Visual Enterprise runtime environment. 

These SAP APIs provide functionality like passing data from the process into the script, and back from the script into the process, as well as connecting to external systems using HTTP, web services or SAP RFC calls, and performing simple scene traversals or modifications.

The Python standard library is only included in Visual Enterprise Generator 8.0 SP1 or later. Prior versions only include the functionality provided out of the box by IronPython.

Callback Script Operations

Operations with callback scripts, are operations that have a script parameter. Within this script will be a pre-defined set of functions, which will be called by the operation as it executes, at its discretion. There will usually be a default script provided by SAP, but it is possible to customize this script.

A callback operation is a pre-defined operation provided byVisual Enterprise Generator, which has a Python script parameter. This script parameter contains a Python script that defines one or more Python functions with well-known names and function arguments.

When the operation is executed, it will at its discretion call one or more of these Python functions, and pass through the arguments expected by the function.

For example, the VDI workflows have an operation that calls a Python function defined by the script, and the responsibility of this function is to provide a PDM identifier for a CAD object, given a set of function arguments.

If you want to modify what a script does, we recommend doing this in a custom copy of the process, or it may be the case that your changes are lost when you upgrade to a new version of the software, and the default system process is updated

Figure 1: An operation with a callback script


Custom Scriptable Operations

 

Scriptable operations are custom operations created inside the Process Designer, with either a new or existing process opened.

To create the definition for a new scriptable operation, select Operations -> New Scriptable Operation.

To edit the definition of an existing scriptable operation, open the toolbox where the operation was saved, right click the operation, and click Edit.

This will display the Operation Editor window for the new operation. 

You can define the Python source code for the script in the operation editor, in which case it will be the default code used by all new instances of the operation.

Alternatively, you can define it for a particular script within a particular process, in which case it applies only to the instance of the operation in that process.


A scriptable operation is a custom user-defined Visual Enterprise Generator operation with custom input and output parameters, and an associated Python script block that implements the operation’s functionality.

Within the Process Designer, the user can create a new operation of this type, and after dragging this new operation onto the process canvas, edit its Python script to do whatever is required to implement the custom operation.

See Appendix A: Creating a Scriptable Operation for more details on how to create one of these operations.

As soon as you make a change to the script source code within a particular operation, the changes you make will only apply to that single instance of the operation. If you want your changes to apply globally, you must make them in the Operation Editor.


Figure 2: The Operation Editor

 

The Operation Editor lets you modify the operation name and display name (for new operations), the description, and the input and output parameters that will be available to pass data in and out of the operation.

 

Right-clicking a parameter in the Input or Output panel to edit advanced properties of the parameter or change its default assigned name.

 

To make your script code apply globally to all new instances of this operation, you must edit the code here, in the Operation Editor.


Your first Custom Script Operation

 For the purposes of this exercise, we recommend you create an empty new VEG process to use for testing.

 Drag a filetrigger out into the process canvas:

Figure 4: The filetrigger trigger


Then create a sample scriptable operation as described in the Scriptable Operations section.

The sample operation you create will be added in the Scriptable operations toolbox, drag it out into the process canvas as well, then create a connection between this operation and the filetrigger.

You should have a process canvas that looks like this:

Figure 5: Process canvas

You edit the Python script code by double-clicking the scriptable operation, then expanding the script parameter, clicking in the code parameter, and clicking the disclosure (…) button.

Figure 6: Script operation details panel

Clicking the (…) button displays the script code editor, which is a simple text editor with Python syntax highlighting and error checking.

Figure 7: Python script code editor

Running your script

First, we will put some example code into the operation you’ve just created.

You could have put this code into the script parameter in the Operation Editor as well, but for the purposes of illustration, we've placed it in the operation instance within the process.

In the Python script code editor, type in the following code:

major = sap.settings.Version.Major
minor = sap.settings.Version.Minor
sap.log.error('SAP VE Generator v%d.%d' % (major, minor))

This script will log the message SAP VE Generator vx.y to the process log (a.k.a. task log).

The OK button will be greyed out if there are any syntax errors, and you can click the Check Syntax button to get the line numbers of the problematic lines if that occurs.

Click OK to make your script changes. Click File -> Save to save the process changes.


Testing scripts via Debug -> Run

Select Debug -> Run in the process designer, this will execute in the context of the main Visual Enterprise Generator controller process (it does not start a separate Visual Enterprise Generator task).

You will see red outlines around filetrigger and your custom script operation as it executes, the red outline indicates the currently executing unit.

When execution has completed, you can select Debug -> View Results Document to see a XML results of the process execution.

For example, in the XML beloe you can see that my custom scriptable operation (named test_script) executed, and took 0.499 seconds to run:

 

However, the log message SAP VE Generator vx.y is not displayed here, since this is not the task log.

When running the process via Debug -> Run, since a new VEG task is not created, the log message will be associated with the main Visual Enterprise Generator controller process, the logs for which can be found in C:\ProgramData\SAP\Visual Enterprise Generator\Logs\Debug\DSController_DDMMYYYY.log.

For example, debugging this process on my system produced the following log message:

[0044 12:40:03.696 Error] SAP VE Generator v8.0

If seeing the log messages via a user interface is important to you, it may be preferable to run the process Process -> Run method listed below, which means you will get a separate Visual Enterprise Generator task created, and will be able to view the log messages in Visual Enterprise Generator Administrator.


Testing Scripts via Process -> Run

 

Find the test process you created, by opening Visual Enterprise Generator Administrator, going to the Server Configuration tab, and selecting the Processes node.

 

Your process should be in the list. If it is not, click Refresh (may be required for newly created processes).

 

Right-click the process, you should get a menu like this:

 

Click Run, which will bring up the Run Process dialog.

Fill in any parameters you need (for the purposes of the sample exercise you can leave them blank), then click Run.

This will run your process as a separate Visual Enterprise Generator task.

You can then see the Visual Enterprise Generator task for your executed process in the Server Monitoring -> Tasks list:


Clicking Run & Exit will run your process as a separate Visual Enterprise Generator task and close this dialog. For development purposes, we suggest keeping this dialog open, and just clicking Run whenever you need to run the process. This way, you can keep Visual Enterprise Generator Administration open on the Server Monitoring -> Tasks lists for easy access to the task log.

Double-clicking the task in the task list for the task you just ran, gives you the log for that task, where you can see the log message without having to find it in a log file.


Below is a sample task log, produced by double-clicking the task in the Tasks list. Highlighted is the log line produced by the Python script code.


Troubleshooting

At this stage, there is no debugger that allows stepping through the script and there is no way to set breakpoints.

Instead you will have to use log statements and check the Visual Enterprise Generator task logs or log files, as described in the Running Your Script section.

Using log statements

Although there is a function sap.log.debug(message), we recommended using the info() function instead, as the debug() function will only emit messages if trace logging was enabled in the Visual Enterprise Generator Configuration application when setting up the server. 

If your server is configured to only log messages of Error or Warning priority, the same caveat will apply. You will either need to configure your server to emit Info log messages (which requires a restart), or log your messages with Warning or Error priority.

Log messages will be displayed in the task log, or in the engine log file. See the Testing scripts via Debug -> Run and Testing scripts via Process -> Run sections for more details on how to find these log messages.

Check input parameters

Scriptable Operations

If a script in a scriptable operation seems to be failing, add a log statement in the beginning of the script to see if the script is getting called and also print the input parameters.

sap.log.info("script start")
for item in sap.input_parameters:
    sap.log.info("%s" % item)
Callback Script Operations

For a callback script the input is passed as parameters to the entry point function of the script by the operation that is calling the script. The name of the entry point function is defined by the specific callback operation. E.g.

def ExportSceneMetadata(filter_path, output_path):
    sap.log.info("filter path = {}".format(filter_path))
    sap.log.info("output path = {}".format(output_path))
    # ...rest of the code...

 If the input is correct, then sap.log.info calls can be added to other parts of the script. Note that sap.log.info  expects a string parameter so it may be necessary to ensure the value passed is a string by using your choice of string formatting.

Exceptions and Runtime Errors

If any runtime errors occur in your Python scripts, it will cause the script to throw an exception, which will be turned into a .NET exception, which will bubble up to the containing process.

This may or may not be desirable.

To prevent it, you can use a Python try..catch block to protect the code that may fail, or alternatively, use the Visual Enterprise generator standarderror handler mechanism to trap the exception.

Syntax errors will also cause the scripts to fail at runtime in the same manner

Understanding Errors

In order to understand what occurs when there are runtime errors in a script, we can introduce an intentional error to the script created in the Your First Custom Script Operation section, we’ll add an intentional error and then see how it can be addressed.

Change the script to add a hello() method call, this is a name for a symbol that does not exist in the script’s scope, which will cause a Python NameError:

major = sap.settings.Version.Major
minor = sap.settings.Version.Minor
hello()
sap.log.error('SAP VE Generator v%d.%d' % (major, minor))

If you run the process now using Debug -> Run, you’ll get an error dialog:

This is what happens when you run a process under the debugger and an unhandled exception occurs in a script operation’s Python code - the dialog message is the Exception object’s message.

If you run the process using the Run Process dialog, the task log will contain the stack trace (along with script line numbers) for the error. This is more likely the type of situation which will occur when your custom script runs on a production server

This looks reasonable - you’ll also notice that line 3 is also the correct line number, as that is the line where we introduced the problematic hello() call.

You’ll also see that the process is marked as failed in the task list: 

Cookbook

Using .NET types

It is possible to use any .NET APIs from your Python script.

Check if functionality is already available in Python

We suggest first reviewing the Python standard library documentation, to check whether there is a more Pythonic way of achieving something, before resorting to using .NET APIs.

However, if the .NET API in question is more feature rich, it may make more sense to use it from the beginning.

Below is a table of some common functionality in .NET, and the Python equivalent, as an example:

.NETPython
System.LinqList/Dictionary comprehensions, the itertools package, the map(), sum() and groupby() functions
System.Xml.LinqWe recommend using .NET's System.Xml.Linq data types, they are more modern and full featured than the out of the box Python XML support.
System.IOThe open() function, the os and os.path packages.

Python tends to favour functions that operate on their arguments for these types of primitive operations, as opposed to object instance methods, or the extension method approach used by LINQ.

The Python standard library documentation applicable to the version of IronPython used by Visual Enterprise Generator can be found at https://docs.python.org/2.7/.

Native Python modules as used by CPython are not supported by IronPython. Only pure Python modules can be used in IronPython, and by consequence, in Visual Enterprise Generator.

Check if it's already available to your script

The Visual Enterprise Generator Python script environment already makes the following namespaces available for every Python script executed (types in these namespaces can be used without qualification):

System
System.IO
System.Collections.Generic
System.Xml.Linq
itertools

Using APIs from another .NET assembly

In order to use the .NET APIs from your script, the .NET assembly in which the functionality resides must be loaded into the operating system process in which your script is running.

This is done using the clr module as follows, which is IronPython specific. The clr module defines a few AddReference() methods which you will use to load the .NET assembly. In the example below, we are loading the standard .NET assembly System.Xml.Linq.

import clr
clr.AddReference('System.Xml.Linq')

This will locate the assembly having the specified name, if possible, and load it into the process, after which .NET namespaces in the assembly are made visible as Python modules.

See http://ironpython.net/documentation/dotnet/ for more information on integrating .NET APIs into your code.

Note that the documentation there is incorrect on one point, it is possible to use .NET extension methods using the standard dot syntax, see below.


Using .NET extension methods

Once you have the .NET assembly loaded, you can import extension methods so that they apply to all objects of the .NET type in the Python script as well.

It’s a matter of calling clr.ImportExtensions() on the Python module corresponding to the .NET namespace in which the extension methods are declared:

clr.ImportExtensions(System.Xml.Linq)


Passing data between the script and the process

All input parameters are provided to the script in the sap.input_parameters variable. This is a dictionary of string keys to parameter values. Parameter values correspond to their type, e.g. a integer parameter will be a Python integer value.

server_id = sap.input_parameters['serverId']
job_id = sap.input_parameters['jobId']


To return data from the custom scriptable operation to the containing process, you need to have defined some output parameters for the operation. You can do this when you’re creating or editing the operation definition from Process Designer, as seen in the Scriptable Operations section.

All parameter values that you set in the sap.output_parameters variable, which is also a dictionary of string keys to values, will be made available to the calling process after your operation completes.

sap.output_parameters['serverId'] = 'ABC'
sap.output_parameters['jobId'] = 3231


XML transformation using XSLT

Problem: Converting a source XML to a target XML. E.g. a PDM XML to a VEG input manifest.

If you prefer to use XSLT over Python code to convert an XML document to another XML document, or HTML or to plain text, then the code below may help. The Transform function expects an input XML string and an XSLT string. The input string will normally be read from the file system before being passed to the function, the XSLT could be provided in as literal in the script. The Transform function returns the result of the transformation as a string.

from System.Text import StringBuilder
from System.Xml import *
from System.Xml.Xsl import XslCompiledTransform

def Transform(input, xslt):
  inputReader = XmlReader.Create(StringReader(input))
  xslReader = XmlReader.Create(StringReader(xslt))
  sb = StringBuilder()
  settings = XmlWriterSettings()
  settings.Indent = True
  settings.IndentChars = "\t"
  settings.CloseOutput = True
  outputWriter = XmlWriter.Create(sb, settings)
  tr = XslCompiledTransform()
  tr.Load(xslReader)
  tr.Transform(inputReader, outputWriter)
  return str(sb)

transformed_xml = Transform(some_pdm_xml, pdm_to_manifest_xslt)  # example call
  • Use of XSLT is possible as far as the installed version of .NET supports it. SAP does not offer provisions or guarantees beyond what is supported by the .NET framework.
  • This function does not perform validation except for well-formedness of the XML. If an XML schema is available it may pay to do an input validation using that schema first.
  • If multiple transformations have to be performed using the same XSLT in one script, then make sure the XslCompiledTransform is re-used, as there is some overhead on the Load() call: the XSLT gets compiled at runtime into an assembly for fast execution during the tr.Transform() call.


3D scene navigation

The ability to traverse the scene hierarchy and read information like node name, metadata, and other attributes is possible using the new Python scene traversal APIs.

The sap.graphics.factory module is a factory that will construct new instances of objects that can be used to traverse the scene (read-only) and make small changes to the scene (read-write).

The ActiveSceneReader member constructs a new Scene Reader class.

The ActiveSceneManager member constructs a new Scene Manager class, which provides the ability to read the scene as well as make selected changes to the scene.

Typically, when you want to traverse the scene and read information from any of the different types of objects you may encounter, you will use a Scene Reader.

When you want activate BOMs, model views, or step views, or perform small changes like renaming nodes, you will use a Scene Manager.

Please see the sap.graphics.factory section in the VDI SDK Reference for the  module for full details on all of the APIs available.

sap.graphics.factory APIs are only available in Visual Enterprise Generator 8.0 SP1 or later.

When using any of the sap.graphics.factory factory properties or methods, you need to have an open scene for the current process, in the same process branch as your operation. You can open a scene by using the go_scene_open or go_scene_openwithplugin operations found in the 2D Vector and 3D graphics toolbox in Process Designer.


Exporting the hierarchy and metadata of a scene to XML

This example will traverse the hierarchy of the scene and produce XML having the following format:

<Scene>
  <Node Name="Assembly [默认]">
    <Metadata>
      <Metadata Category="CADMetadata" Name="AUTHOR">Test Author</Metadata>
      <Metadata Category="CADMetadata" Name="COMMENTS">Test Comments</Metadata>
      <Metadata Category="CADMetadata" Name="CREATED">Fri Jul 23 02:02:02 2004</Metadata>
    </Metadata>
    <Node Name="Subassembly [ABC-123]">
      <Node Name="Part [123-123]" />
    </Node>
  </Node>
</Scene>

The Python code:

xml_elements_by_node = {}


# Returns a sequence containing the result of calling to_xml() for the specified Node, 
# as well as all of its children, recursively.
def recursive_nodes(node, to_xml, parent_node=None):
  yield to_xml(node, parent_node)
  for child_node in node.Children:
    for recursive_child_xml in recursive_nodes(child_node, to_xml, parent_node=node):
      yield recursive_child_xml

# Returns a sequence containing the result of calling to_xml() for each of the specified
# IMetadataValue in metadata_values.

def flatten_metadata(metadata_values, to_xml):
  for value in metadata_values:
    if hasattr(value.Value, '__iter__'):
      for child_value_xml in flatten_metadata(value.Value):
        yield child_value_xml
    else:
      yield to_xml(value)


# Returns the XML for a specified node
def xml_for_node(node, parent_node=None):
  global xml_elements_by_node
  metadata_values_xml = list(flatten_metadata(node.MetadataValues, xml_for_metadata))
  if len(metadata_values_xml) > 0:
    metadata_xml = XElement('Metadata', metadata_values_xml)
  else:
    metadata_xml = None
  xml = XElement('Node', XAttribute('Name', node.Name or ''), metadata_xml)
  # ALWAYS use node.Handle for object identity, NOT the node itself!
  xml_elements_by_node[node.Handle] = xml
  if parent_node:
    parent_xml = xml_elements_by_node[parent_node.Handle]
    parent_xml.Add(xml)
  return xml

# Returns the XML for a specified metadata value.
def xml_for_metadata(metadata_value):
  return XElement('Metadata', 
    XAttribute('Category', metadata_value.CategoryName or ''),
    XAttribute('Name', metadata_value.KeyName or ''),
    XText(metadata_value.Value or ''))

# Get a reader for the current scene (go_scene_open or equivalent
# must have been invoked before this operation).
scene = sap.graphics.factory.ActiveSceneReader


# Get all of the nodes in the scene hierarchy, and
# transform them into XML
node_elements = [node_xml for bom in scene.Boms
                          for root_node in bom.RootNodes
                          for node_xml in recursive_nodes(root_node, xml_for_node, None)]
root_element = XElement('Scene', node_elements)

# Log the XML
sap.log.info('%s' % root_element)


Activating a BOM in a scene

This snippet uses a reader to find the list of BOMs in the scene, and then uses a manager to activate the second BOM in the list. To test you would need to open a CAD file having at least two BOMs in it.

reader = sap.graphics.factory.ActiveSceneReader
manager = sap.graphics.factory.ActiveSceneManager
with manager.BeginChanges():
  manager.ActivateBom(list(reader.Boms)[1])


Calling external web services

The SAP Python script environment provides some helper functionality to get web service calls up and running quickly.

It uses the .NET web service client support, and generates client proxy classes for consuming web services, given a specified WSDL file.

We’ll call the Conversion Server web service – this assumes you’ve set up your Visual Enterprise Generator server in Integrated mode. This example will log the API version of this web service, after making the web service call.

# The WSDL to generate proxies for.
wsdl_path = Path.Combine(sap.settings.InstallationPath, 'ConversionServerWS', 'ConversionServerV3.asmx.wsdl')

# Where the target web service endpoint is located. In the case of
# the Conversion Server WS, it is important that it end with a trailing /,
# for the default document handling to be triggered on IIS. Alternatively,
# you could specify the full URL to the .asmx file.
endpoint_url = 'http://localhost/ConversionServerWS/'

# Generates a proxy from the given WSDL. Generated proxy DLLs are cached.
# The cached proxy DLL can be removed with sap.webservice.Remove().
service = sap.webservice.Create(wsdl_path, endpoint_url)

# Make the web service call. Real code should protect this with try..except.
version = service.GetAPIVersion()

# Process response.
sap.log.info('API version %d.%d.%d.%d' % (version.Major, version.Minor, version.Build, version.Revision))


Making SAP RFC calls

The SAP Python script environment provides helper functionality to simplify the process of making SAP RFC calls from within Python scripts.

This requires the Visual Enterprise Generator server to be running in Integrated mode.

Set up a new SAP system connection

In order to make an RFC call, you need to have an SAP connection set up in Visual Enterprise Generator Administration.

To do so, open up the VEG Administration, and go to SAP Integration -> Connections. Click New, select SAP RFC for the type, and a RFC Connection Details section will be displayed:

Selecting the SAP System drop-down should display the list of SAP systems configured on the Visual Enterprise Generator server, using SAP GUI for the service account to create them.

If your list is empty, you will first need to log on as the user that Visual Enterprise Generator is running as, start SAP GUI, and create an entry for the system you want to connect to. You may need to restart Visual Enteprise Generator after doing this, for the newly added system to show up in this list.

Make sure that the Windows user account you are running the Visual Enterprise Generator service as, is the same user account that you are running SAP GUI as, when you add the systems in SAP GUI.

Once you have a list of systems, select the system you are interested in, and specify the Name and correct Client to use.

The Name field is what you will use in Python script to identify the system you wish to connect to, it is a unique name.

In versions of Visual Enterprise Generator before 8.0 SP2, the Name field was labeled Display Name, but it is the same field, used for the same purpose.


Authentication and obtaining a connection

In order to make RFC calls, your script will use a connected instance of an RfcDestination object, which is an object provided by the SAP .NET connector library. You will not create instances of this object yourself, instead you will use system provided functions to obtain an instance of this object.

If your script is running inside a job which is already making RFC calls, such as any of the VDI processing workflows, you can use a single call to the sap.rfc.GetDestination() method to get this object, because the job will already have associated RFC username and securely stored credentials.

However, if your script is running inside other workflows, you may need to use sap.authentication.WithUser() or sap.authentication.WithERPUser() to set the credentials before calling sap.rfc.GetDestinationForConnection(). We recommend the use of sap.authentication.WithERPUser(), as it does not require you to manage storage of the credentials securely yourself.

Please refer to the VDI SDK Reference for more information on these functions.


Making an RFC call using an RfcDestination

Once you have a connected RfcDestination object already connected to the SAP system, you can use the standard .NET Connector APIs to make RFC function calls.

Below is an example that just calls the standard RFC_PING function.

# Sets the user credentials for subsequent calls.
 
# For production  scripts, we STRONGLY recommend using sap.authentication.WithERPUser()
# to use accounts set up in VEG Administrator's User Names and Passwords,
# section instead.
 
# This is the name in VEG Administrator for the SAP connection.
sap_system_name = 'SYSTEM NAME'
 
# The credentials on the SAP system to use.
sap_user_name = 'USERNAME'
sap_user_pwd = 'PASSWORD'
 
# Prepare the credentials for subsequent calls.
sap.authentication.WithUser(sap_user_name, sap_user_pwd)
 
# Get a connected RFC destination object
destination = sap.rfc.GetDestinationForConnection(sap_system_name)
 
# Get a function object.
rfc_ping = destination.Repository.CreateFunction("RFC_PING")
 
# In a real script, you should make calls to RfcFunction.GetTable() and other
# methods to prepare the RFC function call.
 
rfc_ping.Invoke(destination)
 
sap.log.info('RFC ping completed.')

Please see http://service.sap.com/connectors for more information regarding the RfcDestination class and other .NET Connector APIs.


File format identifier detection

Problem: Detecting a file format GUID for a given file on disk.

Sometimes a python script needs to have a file format specific behaviour. This can be achieved by invoking the function detect_file_format from the saplib.cad library. Given a full file path, this function will return a result object.

The result object will have the property ScanResult set to Successful if the file format has been successfully detected, in which case its PluginGuid property will contain the guid identifier of the file format.

Another library file saplib.erpintegration.fileFormats  contains predefined common plugin identifiers.

These libraries can be found in the ~PythonLibraries\saplib folder of a Visual Enterprise Generator installation.

from saplib.cad import detect_file_format
from saplib.erpintegration import fileFormats
 
def is_solidworks_file(filename):
    file_format = detect_file_format(filename)
    if str(file_format.ScanResult) == "Successful":
        if file_format.PluginGuid == fileFormats.GUID_SOLIDWORKS_ASSEMBLY or file_format.PluginGuid == fileFormats.GUID_SOLIDWORKS_PART:
            return True
        else:
            return False
    else:
        raise Exception("Unknown file format")
 
sap.log.info(is_solidworks_file(("C:\\Data\\sw\\mast_truck\\Inner mast.SLDASM")))


CAD assembly structure extraction

Problem: Extracting the assembly structure from a CAD file into an XML file.

Visual Enterprise Generator CAD readers can be invoked to extract the assembly structure of a CAD file into an XML file. The user needs to have some knowledge about the contents and format of the CAD file in order to choose the correct method and arguments passed to the method.

from saplib.cad import extract_bom,CONFIG_OPTION
 
extract_bom("C:\\Data\\sw\\mast_truck\\Inner mast.SLDASM", # source CAD filename
            "c:\\temp",                    # folder to store temporary files
             "c:\\temp\\assembly_structure_all.xml")# target assembly xml filename
 
extract_bom("C:\\Data\\sw\\mast_truck\\Inner mast.SLDASM", # source CAD filename
            "c:\\temp", # folder to store temporary files
            "c:\\temp\\assembly_structure_last_saved.xml",# target assembly xml
            CONFIG_OPTION.LAST_SAVED) # export the last saved configuration
 
extract_bom("C:\\Data\\sw\\mast_truck\\Inner mast.SLDASM", # source CAD filename
            "c:\\temp", # folder to store temporary files
            "c:\\temp\\assembly_structure_specific.xml", # target assembly xml
            CONFIG_OPTION.SPECIFIC, # export a user specified configuration
            "IM_ASS4000") # name of the configuration to be extracted


Handling CREO data with Pro/Explorer

Problem: Working with CREO CAD files.

Pro/Explorer is a 'plugged' CAD reading solution that calls the native CREO application to export the CREO CAD assembly and part files into neutral CAD file format whilst preserving all the features present in the exported files. Library saplib.proexplorer exposes support for this 'plugged' solution. See Configuring ProENGINEER or CREO for instructions on required configuration that needs to be performed for the plugged solution to work.

Pro/ENGINEER or CREO needs to be installed and licensed for this script to work

from saplib.proexplorer import ProExplorer
 
proe = ProExplorer()
 
# return all available CREO family instances in the file as a list
proe.detect_top_level_family_instances("C:\\Data\\CREO\\export\\letter.prt.3")
 
# convert CREO drawing to viewable file and return path to it
proe.convert_drawing_to_rhz("C:\\Data\\CREO\\generic.drw")
 
# convert generic CREO family instance to neutral and return path to it
proe.convert_creo_to_neutral("C:\\Data\\CREO\\letter.prt.3")
 
# convert a specific CREO family instance to neutral and return path to it
proe.convert_creo_to_neutral("C:\\Data\\CREO\\letter.prt.3","LETTER_D")


Reusing Python code

Problem: Avoiding repetition/maintaining multiple copies of code.

Python code can be reused between different VEG processes and operations if it is saved as a .py file in the Visual Enterprise Generator share folder, in the Workspace\PythonLibraries sub-folder. This module can then be accessed from Python scripts using standard import directives.

The name of the .py file should be unique within the folders that will be searched for Python modules.

Example  script saved to VEG Share\Workspace\PythonLibrarie\user_test.py:

def add_two_numbers(a,b):
  return a + b 

Example of how this script can be used from within an operation:

from user_test import add_two_numbers
print add_two_numbers(2,3)

Custom SAP APIs

All custom SAP APIs are grouped into a Python namespace named sap which is available to all scripts running inside an Visual Enterprise Generator process context.

Within this namespace are additional sub-groupings by functionality.

sap.input_parameters

This is a Python dictionary containing all of the parameters defined in the Input pane of the Operation Editor, for a custom scriptable operation. Any values set by the containing process before the operation executes will be passed through in this dictionary. The keys in this dictionary correspond to the names of the defined input parameters.

sap.output_parameters

This is a Python dictionary in which the script can set the values for parameters defined in the Output pane of the Operation Editor, for a custom scriptable operation. Any values set by the script will be made available as output parameters of the scriptable operation in the containing process.

The keys in this dictionary should correspond to the names of the defined output parameters.

sap.settings

This object provides access to some general Visual Enterprise Generator server settings.

Properties
PropertyDescription
InstallationPathThe full path to the location where Visual Enterprise Generator is installed
SharePathThe full path to the Visual Enterprise Generator share
WorkspacePathThe full path to the Workspace folder within the Visual Enterprise Generator share
VersionA .NET Version object containing the Visual Enterprise Generator version. The returned object has Major, Minor, Revision and Build properties that contain integers for the respective components of the Visual Enterprise Generator version. It can also be converted to a string by calling the .ToString() method on this object.

sap.log

The object sap.log provides the ability to log messages to the task log for a Visual Enterprise Generator process.

Methods
MethodDescription
debug(message)

Logs a message of severity Debug to the task log. Message will only be visible if trace logging is turned on in Visual Enterprise Generator configuration.

ArgumentDescription

message­

A string containing the message to log
info(message)

Logs a message of severity Info to the task log. Message will only be visible if informational logging is turned on in Visual Enterprise Generator configuration.

ArgumentDescription
message­A string containing the message to log
warning(message)

Logs a message of severity Warning to the task log. Message will only be visible if warning logging is turned on in Visual Enterprise Generator configuration.

ArgumentDescription
message­A string containing the message to log
error(message)

Logs a message of severity Error to the task log.

ArgumentDescription
message­A string containing the message to log
Example
sap.log.debug('trace message')
sap.log.info('informational message')
sap.log.warning('warning message')
sap.log.error('error message')


sap.jobreport

The object sap.jobreport provides the ability to add entries to the job report for the currently executing job, to allow customizations using Python to surface information to end-users. This is the job report seen in Visual Enterprise Generator Administrator or when using the VEG_JOBMONITOR transaction.

Methods

Each of these messages creates an entry in the job report. The type of the entry dictates which icon is used in the job report for the entry.

The method also returns an object that can be used to create child items for that object. For example, calling the Info() method on the object returned by the Assembly() method, will result in an Assembly object in the job report with an Info message as a child item.

MethodDescription
Part(name)

Adds an object of type Part to the job report.

ArgumentDescription
nameA string containing the name of the part
Return Value
A builder object that can be used to add child items to the part
Assembly(name)

Adds an object of type Assembly to the job report.

ArgumentDescription
nameA string containing the name of the assembly
Return Value
A builder object that can be used to add child items to the assembly
Asset(name)

Adds an object of type Asset to the job report.

ArgumentDescription
nameA string containing the name of the asset
Return Value
A builder object that can be used to add child items to the asset
File(name)

Adds an object of type File to the job report.

ArgumentDescription
nameA string containing the name of the file
Return Value
A builder object that can be used to add child items to the file
Folder(name)

Adds an object of type Folder to the job report.

ArgumentDescription
nameA string containing the name of the folder
Return Value
A builder object that can be used to add child items to the folder
Info(messageText)

Adds a message of type Info to the job report.

Argument
messageTextA string containing the message text
Return Value
A builder object that can be used to add child items to the message
Warning(messageText)

Adds a message of type Warning to the job report.

ArgumentDescription
messageTextA string containing the message text
Return Value
A builder object that can be used to add child items to the message
Error(messageText)

Adds a message of type Error to the job report.

ArgumentDescription
messageTextA string containing the message text
Return Value
A builder object that can be used to add child items to the message
Example
assembly = sap.jobreport.Assembly('TopLevelAssembly')
part1 = assembly.Part('Part1')
part2 = assembly.Part('Part2')
folder = sap.jobreport.Folder('Folder 1')
folder.File('File 1')
folder.Info('Informational Message')


sap.jobresult

The object sap.jobresult provides the ability to add entries to the job results for the currently executing job. Job results are categorized name-value pairs with well-known names, that can be retrieved by external systems to determine additional information about job. An example of a result could be the DIR of a document created in the SAP DMS.

Job results differ from the job report in that they are intended for consumption by automated systems and not intended for human consumption directly.

Results added in this way can be retrieved by calling the JobGetResult() method of the VDI web service API.

The job result category named SAP is reserved for use by SAP, and should not be used to avoid the potential for naming collisions.

Methods
MethodDescription
Add(name, value)

Adds a job result. No check for existing results is performed.

ArgumentDescription
nameThe name of the result.
valueThe value of the result
Add(category, name, value)

Adds a job result. No check for existing results is performed.

ArgumentDescription
categoryThe category of the result, can be used as a grouping field.
nameThe name of the result.
valueThe value of the result.
Add(category, path, name, value)

Adds a job result. No check for existing results is performed.

ArgumentDescription
categoryThe category of the result, can be used as a grouping field.
pathThe path of the result, can be used as a sub-grouping field within a category
nameThe name of the result
valueThe value of the result
Update(name, value)

Updates a job result. If a result already exists with the specified name, its value will be overwritten.

ArgumentDescription
nameThe name of the result
valueThe value of the result
Update(category, name, value)

Updates a job result. If a result already exists with the specified name, its value will be overwritten.

ArgumentDescription
categoryThe category of the result
nameThe name of the result
valueThe value of the result


Update(category, path, name, value)

Updates a job result. If a result already exists with the specified name, its value will be overwritten.

ArgumentDescription
categoryThe category of the result, can be used as a grouping field.
pathThe path of the result, can be used as a sub-grouping field within a category
nameThe name of the result
valueThe value of the result



Example
sap.jobresult.Add('Key1', 'Value1')
sap.jobresult.Update('SAP', 'Document/10002123/VED/000/00', 'MaterialID', '123')



sap.authentication

The object sap.authentication provides the ability to configure the authentication method that will be used by all subsequent HTTP, RFC or web-service calls. This authentication method will be in place until another sap.authentication call is made, or the script terminates.

It supports the following authentication methods:

  • Basic username/password authentication
  • X.509 client certificate authentication
Methods
MethodDescription
WithUser(userName, password, [domain])

Configures the script to use basic username/password authentication for subsequent external calls.

ArgumentDescription
userNameA string containing the user name to use
passwordA string containing the password to use
domainAn optional string containing the domain for authentication

This method should not be used in production environments, as the password would not be stored securely, but would be present in the script source code itself. Instead, it is recommended that the WithERPUser() method be used instead, as it stores credentials using strong encryption in a secure location.

WithERPUser(projectName)

Configures the script to use basic username/password authentication using the credentials associated with a Visual Enterprise Generator project. This is the recommended way to set up basic username/password authentication as the credentials are stored, encrypted, in a secure location and not in the script source code.

ArgumentDescription
projectNameA string containing the name of the Visual Enterprise Generator project that has an associated user. The user association can be created in the Visual Enterprise Generator Administration tool, in the User Names and Passwords section of the SAP Integration tab.
WithCertificateFromFile(filename, [password])

Configures the script to use X.509 client certificate authentication, using a certificate loaded from a disk file.

ArgumentDescription
filenameThe path to the X.509 certificate file, in a format supported by the .NET X509Certificate2 class.
passwordAn optional string containing the password for the certificate, if the certificate file is password protected. It is recommended to use file system permissions to secure the certificate file as well.

It is not recommended to use this method in production environments. Instead, WithCertificatesFromStore() should be used, as it will use the Windows certificate store, which is protected by the operating system.

WithCertificatesFromStore()Configures the script to use X.509 client certificates stored in the certificate store of the Visual Enterprise Generator service user account. For example, if Visual Enterprise Generator is running as the DOMAIN\VEGUser user, the certificate should be stored in that user’s Windows certificate store. This is the recommended way to set up X.509 client certificate authentication, as the certificate is stored in a secure area protected by the operating system.
UserName(jobId)

Returns the user name used for authentication, for a specific Visual Enterprise Generator job.

ArgumentDescription
jobIdThe job ID to look up the credentials for.
ConnectionName(jobId)

Returns the ERP connection name used for authentication, for a specific Visual Enterprise Generator job.

ArgumentDescription
jobIdThe job ID to look up the connection name for.
Example
sap.authentication.WithUser('username', 'secret')
sap.authentication.WithERPUser('CustomProjectName')
sap.authentication.WithCertificateFromFile('c:\test.cer')
sap.authentication.WithCertificatesFromStore()
sap.authentication.UserName(sap.jobid)
sap.authentication.ConnectionName(sap.jobid)


sap.connection

The object sap.connection provides the ability to configure the proxy server that will be used for subsequent HTTP calls (raw HTTP as well as web services), to allow for performing these types of calls in environments where proxy servers are required for security reasons.

Methods
MethodDescription
ProxyServer(url)

Specifies the proxy server that should be used.

ArgumentDescription
urlThe URL to the proxy server, including port if required; for example, http://proxy:8080/
ProxyUser(userName, password, [domain])

Sets the credentials to use if the proxy server requires authentication.

ArgumentDescription
userNameThe user name with which to authenticate.
passwordThe password with which to authenticate.
domainAn optional string containing the name in which the user exists.


Example
sap.connection.ProxyServer('http://proxy:8080/')
sap.connection.ProxyUser('username', 'secret')


sap.http

The object sap.http provides the ability to make HTTP requests, like GET or POST requests, with helpers to simplify downloading and uploading files. Prior to version 9.10 (9.0 FP10) the default timeout was 100 seconds and not customisable. From version 9.10 (9.0 FP10) the default timeout is 30 minutes and can be changed.

Properties
PropertyDescription
ResponseHeadersContains all of the response headers from the most recent HTTP GET or POST request.
Methods
MethodDescription
Get(uri, [timeout])

Performs an HTTP GET request.

ArgumentDescription
uri

The URL to perform an HTTP GET request for

[timeout]An optional number setting custom timeout period in seconds. Available in version 9.10 onward.
Return Value
Returns a string containing the HTTP response body
GetBuffer(uri, [timeout])

Performs an HTTP GET request.

ArgumentDescription
uriThe URL to perform an HTTP GET request for
[timeout]An optional number setting custom timeout period in seconds. Available in version 9.10 onward.
Return Value
Returns a .NET byte array containing the response body. Useful if the raw binary data is needed.


GetFile(uri, targetFileName, [timeout])

Performs an HTTP GET, writing the response to a local disk file.

ArgumentDescription
uriThe URL to perform an HTTP GET request for
targetFileNameThe path to the file on disk where the data should be written
[timeout]An optional number setting custom timeout period in seconds. Available in version 9.10 onward.
Post(uri, data, [timeout])

Performs an HTTP POST request.

ArgumentDescription
uriThe URL to perform an HTTP POST request to
dataA string containing the data to use as the body of the POST request
[timeout]An optional number setting custom timeout period in seconds. Available in version 9.10 onward.
PostBuffer(uri, data, [timeout])

Performs an HTTP POST request.

ArgumentDescription
uriThe URL to perform an HTTP POST request to
dataA .NET byte array containing the data to use as the body of the POST request.
[timeout]An optional number setting custom timeout period in seconds. Available in version 9.10 onward.


PostFile(uri, filePath, [timeout])

Performs an HTTP POST request.

ArgumentDescription
uriThe URL to perform an HTTP POST request to
filePathThe name of the file containing the data that will be used as the body of the POST request
[timeout]An optional number setting custom timeout period in seconds. Available in version 9.10 onward.
Example
html = sap.http.Get('http://www.google.com')
buffer = sap.http.GetBuffer('http://server.com/data')
sap.http.GetFile('http://server/file.zip', 'c:\\temp\\file.zip', 500)
sap.http.Post('http://server/api/Login', '<login username="xx" password="yy" />')
sap.http.PostBuffer('http://server/api/Login', buffer)
sap.http.PostFile('http://server/api/FileUpload', 'c:\\file.zip')

The version of IronPython distributed with Visual Enterprise Generator includes support for parsing JSON, since this was added to Python 2.6.

Use the json module and the json.dumps and json.loads functions for this purpose.


sap.webservice

The object sap.webservice provides the ability to connect to any external SOAP web services for which the WSDL is available. It is implemented by using the standard .NET support for consuming web services (it uses the same mechanism to generate web service proxy classes as the wsdl.exe tool provided by Microsoft) .

Methods
MethodDescription
Create(wsdlPathOrUrl, [endpointUri])

Creates a proxy object that can be used to invoke all of the methods defined in the WSDL. If proxy objects have already been generated for the WSDL (determined by using the wsdlPathOrUrl argument as a key), they will be re-used.

ArgumentDescription
wsdlPathOrUrlThe path to the local file containing WSDL, or the URL of a location from where the WSDL can be downloaded. Should the WSDL require authentication or proxy server configuration to download, use the appropriate methods on sap.authentication or sap.connection before you call Create().
endpointUriAn optional string containing the URL that should be used to connect to the web service (instead of the URL specified in the WSDL, if any).
Return Value

Returns a proxy object containing invokable methods for all of the operations described by the WSDL.

All data types defined by the WSDL will also be automatically imported into the script scope by the Create() call, this is important to note if you have naming collisions in your script.

Remove(wsdlPathOrUrl)

Removes any proxy objects that may have been generated for a specific WSDL file or URL.

This should only to be used if the WSDL at a particular URL has changed, or the performance benefits of generated proxy caching will not be realized.


Examples
wsdl_path = Path.Combine(sap.settings.InstallationPath, '~WSDL', 'DOC_3I_DOCFILELINKINFORMATION_OUT.wsdl')

# this creates a proxy object for the web service
docinfo_service = sap.webservice.Create(wsdl_path)

# this calls the web service
response = docinfo_service.ECC_GetDocUrlByFileId(request)


sap.rfc

The object sap.rfc provides the ability to make calls to SAP systems using the RFC protocol, which allows for the majority of remotely accessible SAP function modules to be executed from  Visual Enterprise Generator.

It does this by providing access to the native RFC interface provided by the SAP .NET Connector v3.0, but taking responsibility for authentication and any other pre-configuration of the .NET connector objects on your behalf.

Methods
MethodDescription
GetDestination()

Creates an RfcDestination object for communicating with the SAP system associated with the current job, using the authentication and connection information associated with the current job. If the current job does not have these two pieces of information associated with it, the GetDestinationForConnection() method should be used instead.

Return Value
Returns a connected .NET Connector RfcDestination object that can be used to communicate with the remote SAP system.
GetDestinationForConnection(name)

Creates an RfcDestination object for communicating with the specified SAP system.

ArgumentDescription
nameThe name of the SAP system connection, as configured by the Visual Enterprise Generator Administration application in the Connections section of the SAP Integration tab. If the remote system requires authentication, and there is no authentication context associated with the current job, the sap.authentication methods should be used to configure the SAP system user to use before calling GetDestinationForConnection().
Return Value
Returns a connected .NET Connector RfcDestination object that can be used to communicate with the remote SAP system.


Example
dest = sap.rfc.GetDestination()

# Example of specifying custom credentials, if the current job has no associated authentication
# context:
#
# sap.authentication.WithERPUser('LOOKUPKEY')
# dest = sap.rfc.GetDestinationForConnection('CONNECTION')

server_id = str(sap.input_parameters['vegInstanceId'])
job_id = str(sap.input_parameters['vegJobIdentifier'])

repo = dest.Repository
func = repo.CreateFunction("VEG_SRV_RESET_LOCK")
rowStructure = repo.GetStructureMetadata("DMS_VEG_S_CAD_DATA").CreateStructure()
rowStructure.SetValue("PROSERVER", server_id)
rowStructure.SetValue("PROCONTEXT", job_id)
input = func.GetTable("IT_DMS_VEG_CAD_DATA")
input.Append(rowStructure)
func.Invoke(dest)
output = func.GetTable("ET_MESSAGE")
for message in output:
  number = message.GetString("NUMBER")
  text = message.GetString("MESSAGE")
  type = message.GetString("TYPE")
  if type == "S" or type == "I":
    sap.log.info("ERP locks released successfully: %s" % text)
  elif type == "W":
    sap.log.warning("ERP locks released, with warning: %s" % text)
  else:
    sap.log.error("ERP lock release encountered errors: %s" % text)


sap.graphics.events

The object sap.graphics.events provides access to information about 3D processing events, which are events that occur when loading or saving 3D data, or when performing other types of scene manipulations.

Methods
MethodDescription
GetChronologicalEvents()

Gets a list of processing events that have occurred, in chronological order, since the process began executing or the last time ClearEvents() was called.

Return Value
A sequence of GraphicsProcessingEvent objects for each event that has occurred
GetEventsWithIds(ids)

Gets a list of processing events that have occurred, filtered by a set of well-known event IDs

ArgumentDescription
idsA sequence of one or more integer event IDs used to filter the returned events
Return Value
A sequence of GraphicsProcessingEvent objects for each event that has occurred, and has an ID that exists within the list of IDs specified as an argument.
ClearEvents()Clears the list of processing events. All subsequent calls to GetChronologicalEvents() or GetEventsWithIds() will only return events that have occurred after this call.
ContainsEventWithId(id)

Checks whether an event with an event ID has occurred.

ArgumentDescription
idThe ID of the event to check
Return Value
A Boolean value of true if the event has occurred, false otherwise.


sap.graphics.factory

This object provides read and write access to elements in an open graphics scene. The scene can be opened with the go_scene_open operation. Any Python script that uses the graphics factory has to be in the subtree of this operation in the Visual Enterprise Generator process, and not after it.

Example

vme_ExtractMetadata is a script that uses the sap.graphics.factory object.

In the documentation below, the return values are often specified as .NET interface names. The name can be looked up in subsequent sections, where all the properties of the respective interface are listed.

Although the Return Value can be documented as "Sequence of ..." it is not strictly a sequence in terms of Python. It is in fact an IEnumerable<T> from the underlying .NET implementation and therefore cannot be indexed like [i] or sliced like [a:b]. It first has to be turned into a proper Python sequence using the list() or tuple() functions before indexing or slicing can be applied.

first_bom = scene.Boms[0]        # NOT correct 
first_bom = list(scene.Boms)[0]  # correct
last_bom = list(scene.Boms)[-1]  # correct
Properties
PropertyDescription
ActiveSceneReaderGets an object that is the entry point to the 3D scene for the purpose of reading only
ActiveSceneManagerGets an object that is the entry point to the 3D scene for the purpose of reading and modifying certain types of elements in the scene
Examples
readonly_scene = sap.graphics.factory.ActiveSceneReader
writable_scene = sap.graphics.factory.ActiveSceneManager

ActiveSceneReader

This object provides read access to elements in the 3D scene.

Properties
PropertyDescription
Boms

Retrieves all the BOMs in the scene.

CurrentBom

Retrieves the currently active BOM.

HasAssemblyHierarchy Indicates whether the current scene has assembly (instance-reference) hierarchy.
NumberOfFaces

Gets the number of faces the current scene has.

NumberOfVertices

Gets the number of vertices the current scene has.

Procedures

Retrieves the procedures in the scene. A procedure has multiple steps.

Portfolios

Retrieves the sequence of portfolios.

RootNodes

Sequence of public root nodes of the current BOM. Equivalent to: scene.CurrentBom.RootNodes.

RootNodesIncludingInternal

Sequence of all root nodes of the current BOM.

Equivalent to: scene.CurrentBom.RootNodesIncludingInternal

SourceFilePathReturns a string containing the path of the source file (the loaded file).
Example
scene = sap.graphics.factory.ActiveSceneReader
for bom in scene.Boms:
  sap.log.info(bom.Name)
  first_portfolio = list(scene.Portfolios)[0]
  sap.log.info("file={}".format(scene.SourceFilePath))


IMetadataReader

The objects returned from the scene properties above all implement the IMetadataReader interface. This means that two properties can be accessed for all these objects: MetadataValues and ReservedInternalMetadataValues. The exception is the SourceFilePath property which returns a string.

An IMetadataReader provides access to a sequence metadata values, which implements the IMetadataValue interface.I

Include the following line at the top of the script to make the metadata objects accessible:

from SAP.VE.Generator.Graphics.Wrappers.Metadata import IMetadataValue

Properties
PropertyDescription
MetadataValuesSequence of public metadata values
ReservedInternalMetadataValues

Sequence of internal metadata values.

SAP reserves the right to add or remove internal metadata values at its discretion, it is not recommended that you write any business logic that depends on internal metadata values.

Example

The example below defines a generator that takes into account that a metadata value can be a collection of metadata values, and returns them recursively.

def expand(metadata_values):
  for mdv in metadata_values:
    if isinstance(mdv.Value, IEnumerable[IMetadataValue]): 
      for submdv in expand(mdv.Value):
        yield submdv
    else:
      yield mdv
  for mdv in expand(scene.CurrentBom.Metadata.MetadataValues):
    sap.log.info("{} {} {}".format(mdv.CategoryName, mdv.KeyName, mdv.Value))

IMetadataValue

The classes that implement this interface all have a CategoryName, KeyName, and Private property. In addition, there is a Value property; the data type of this property depends on the type of the metadata value.

PropertyDescription
CategoryNameA string containing the name of the category to which the metadata belongs
KeyNameA string containing the name of the metadata value
PrivateA boolean specifying whether or not this is a private metadata field
Value

The metadata value, its type can be one of the following:

  • string
  • double precision floating point
  • 64 bit signed integer
  • boolean
  • .NET DateTime structure
  • A sequence of IMetadataValue
Example

The following example returns the type of the metadata as string, but does not account for collection types. To test for a metadata value that is collection check for instance of IEnumerable[IMetadataValue].

def value_type(value):
  t = type(value)
  if t == str: return 'String'
  if t == int or t == System.Int64: return 'Integer'
  if t == float: return 'Real'
  if t == bool: return 'Boolean'
  if t == DateTime: return 'DateTime'
  if isinstance(value, IMatrixReader): return 'Matrix'
    raise Exception("Unsupported metadata type {} for value={}".format(t, value))


ISceneMemberReader

This interface is inherited by: ISceneReader, IBomReader, INodeReader, IObjectReader, IProcedureReader, IStepReader, IPortfolioReader, and IModelViewReader. It defines three properties that are common to all of these interfaces.

Properties
PropertyDescription
Handle

A 64-bit integer containing the internal identifier of the graphics element, unique with in the scene. Two objects with the same handle value are effectively the same object.

NameA string containing the name of the scene member
Metadata

If the scene has any metadata, an IMetadataReader is returned by this property. If no metadata, None is returned.

Example
metadata = scene.CurrentBom.Metadata.MetadataValues


IBomReader

This interface defines read access to a BOM object.

Properties
PropertyDescription
NumberOfFaces

Gets the number of faces the current bom has.

NumberOfVertices

Gets the number of vertices the current bom has.

RootNodes

Sequence of public root nodes of this BOM

RootNodesIncludingInternal

Sequence of all root nodes of this BOM, including internal nodes (e.g. camera objects)


Example
nodes = scene.CurrentBom.RootNodes
for node in nodes:
  sap.log.info("node: {}".format(node.Name))


IProcedureReader

This interface defines read access to procedure metadata and procedure steps.

Properties
PropertyDescription
StepsA sequence containing the steps of the procedure, as IStepReader instances.
Example
for step in procedure.Steps:
  sap.log.info("{}: {}".format(step.Name, step.Description))


IStepReader

This interface defines read access to procedure step description and metadata.

Properties
PropertyDescription
AssignmentsA sequence containing all of the assignments in the step, as IAssignmentReader instances
DescriptionA string containing the step text
TargetBom

An IBomReader instance representing the BOM that contains the assignment's nodes

VisibleNodesThe visible nodes in the TargetBom that are selected as part of the assignment, as INodeReader instances
Example
scene = sap.graphics.factory.ActiveSceneReader
for proc in scene.Procedures:
  sap.log.info(proc.Name)
  for s in proc.Steps:
    sap.log.info(" '{}'; '{}': '{}'".format(s.TargetBom.Name, s.Name, s.Description))
    for vn in s.VisibleNodes:
      sap.log.info(" Node={}".format(vn.Name))


IAssignmentReader

This interface defines  read access to an assignment object.

Unlike most other interfaces listed here the IAssignmentReader does not inherit the properties from ISceneMemberReader, so no Node, Handle and Metadata can be addressed through this interface.

Properties
PropertyDescription
AssignedNodesA sequence of INodeReader objects representing the nodes assigned to the step
AssignmentTypeA string indicating the type of assignment
Example

Prints the hierarchy of procedures, steps, assignments and nodes.

scene = sap.graphics.factory.ActiveSceneReader
for proc in scene.Procedures:
  sap.log.info(proc.Name)
  for step in proc.Steps:
    sap.log.info(" step={}".format(step.Name))
    for asn in step.Assignments:
      if asn.AssignedNodes:
        sap.log.info("    type={}".format(asn.AssignmentType))
        for node in asn.AssignedNodes:
          sap.log.info("      node={}".format(node.Name))


INodeReader

This interface defines read access a scene node object.

Properties
PropertyDescription
BoundingBoxA IBoundingBox representing two vectors that define the bounding box of the node.
ChildrenA sequence of INodeReader containing the child nodes of this node, if any.
ClosedA boolean value specifying whether or not this node is a closed node (child hierarchy hidden).
Identifiers

A sequence of IIdentifier containing VE identifiers associated with node.

MarkedA boolean value specifying whether or not this node has been marked.
NumberOfFaces

Gets the number of faces the current node has.

NumberOfVertices

Gets the number of vertices the current node has.

ObjectAn IObjectReader representing the the underlying object associated with this node. For example, a polygonal mesh object.
ObjectMatrixAn IMatrixReader defining the position of an object instance. For example, two nodes can refer to the same mesh object, but each position is an instance of that object at a different position in the scene.
ParentRelativeMatrix

An IMatrixReader defining the node's position relative to its parent node.

PMIA boolean specifying whether or not the object contains any attached Product Manufacturing Information.
Private

A boolean specifying whether or not this node is a private node.

Private nodes are used for internal purposes. Modifying or building business logic depending on them is not supported, and SAP reserves the right to remove them in future, or change their semantics, at any time, without notice.

Selected

A boolean indicating whether or not the node is currently part of the active selection, if any.

Visible

A boolean indicating whether or not the node is currently visible.

WorldMatrixAn IMatrixReader containing the position of the node relative to the world.


Example

The function below logs some node information. It checks whether the node.Object exists, and logs the handle of the object. Multiple nodes can point to the same underlying scene object.

def node_info(node):
  sap.log.info ("'{}' obj={} cls={} mark={} pmi={} pr={} sel={} vis={}".format(
    node.Name,
 (node.Object.Handle if node.Object else "N/A"),
    node.Closed,
    node.Marked,
    node.PMI,
    node.Private,
    node.Selected,
    node.Visible))


IIdentifier

Represents VE identifier

Properties
PropertyDescription
Fields

A sequence of IIdentifierField containing the fields associated with the identifier.

SourceString value representing source of the identifier.

Type

String value representing the type of the identifier.

IIdentifierField

Represents VE identifier field

Properties
PropertyDescription
NameString value representing name of the identifier field.

Value

String value representing the value of the identifier field.

IObjectReader

This interface defines read access to a graphics object.

Properties
PropertyDescription
IsRenderable A boolean indicating whether or not the object is renderable.
Type

An enumeration of type ObjectType. The following values are possible:

  • Mesh
  • Sprite
  • Procedural
  • Camera
  • Internal
Example
if node.Object and node.Object.Type == ObjectType.Mesh:
  sap.log.info("this object is a mesh")


IPortfolioReader

This interface defines provides read access to the portfolio object in a scene. A portfolio has modelviews.

Properties
PropertyDescription
ModelviewsA sequence of IModelViewReader containing the modelviews in a portfolio


Example
portfolios = sap.graphics.factory.ActiveSceneReader.Portfolios
modelviews = list(portfolios)[0].Modelviews


IModelViewReader

This object provides read access to a model view.

Properties
PropertyDescription
TargetBom

An IBomReader representing the BOM that contains the nodes that belong to the model view

VisibleNodesA sequence of INodeReader instances representing the nodes that belong to the model view.
Example

Prints all nodes of all modelviews of all portfolios in a scene.

scene = sap.graphics.factory.ActiveSceneReader
for pf in scene.Portfolios:
  sap.log.info(pf.Name)
  for mv in pf.Modelviews:
    sap.log.info("  " + mv.Name)
    for vn in mv.VisibleNodes:
      sap.log.info("    " + vn.Name)


IMatrixReader

This interface defines read access to a transformation matrix (object, parent-relative or world).

Properties
PropertyDescription
AxisXAn IVector3DReader representing the X axis vector of the matrix
AxisYAn IVector3DReaderrepresenting the Y axis vector of the matrix
AxisZAn IVector3DReaderrepresenting the Z axis vector of the matrix
Data

A two-dimensional 4x4 floating point array containing the transformation matrix data for the axes (x,y.z), location (t) and a scale factor.

The data is laid out as follows:

x1 x2 x3 0

y1 y2 y3 0

z1 z2 z3 0

t1 t2 t3 scale

IsIdentityA boolean value indicating if this matrix is mathematically an Identity matrix.
LocationAn I3dVectorReader representing the location component of the matrix
ScaleA floating point value representing the scale of the object
String12The transformation matrix represented in String12 format: string composed of 12 numbers in flat array.
String16The transformation matrix represented in String16 format: string composed of 16 numbers in flat array.
Example

This function converts a matrix to a string containing its space separated values.

def matrix_to_string(m):
  values = []
  for axis in (m.AxisX, m.AxisY, m.AxisZ, m.Location):
    values.extend(axis.Data)
    values.append(m.Scale)
  return " ".join(str(v) for v in values)


IVector3DReader

This interface provides read access to the vector components.

Properties
PropertyDescription
DataAn array of 3 floating point numbers, in the order x, y, z
XA floating point value for the x component of the vector
YA floating point value for the y component of the vector
ZA floating point value for the z component of the vector
Example

The following returns a matrix as a string of the format "[[xx,xy,xz], [yx,yy,yz], [zx,zy,zz], [lx,ly,lz]]"

def vector(ax):
  return "[{}, {}, {}]".format(ax.X, ax.Y, ax.Z)


def matrix_string(m):
  s = ", ".join(vector(ax) for ax in (m.AxisX, m.AxisY, m.AxisZ, m.Location))
  return  "[" + s + "]"

print matrix_string(some_node.ObjectMatrix)



IBoundingBox

This interface provides read access to the bounding box components.

Properties
PropertyDescription
MinimumAn IVector3DReaderrepresenting the first vector defining the bounding box
MaximumAn IVector3DReaderrepresenting the second vector defining the bounding box
Example

The following returns Minimum and Maximum vectors components of Bounding Box.

def iteratenodes(node):
    box = node.BoundingBox
    vector = box.Minimum
    sap.log.debug("MSG: node:'%s' Minimum X:'%s', Y:'%s', Z:'%s', " % (node.Name, vector.X, vector.Y, vector.Z))
    vector = box.Maximum
    sap.log.debug("MSG: node:'%s' Maximum X:'%s', Y:'%s', Z:'%s', " % (node.Name, vector.X, vector.Y, vector.Z))
    for child in node.Children:
        iteratenodes(child)

import sap

scene = sap.graphics.factory.ActiveSceneReader

for node in scene.RootNodes:
    iteratenodes(node)


ActiveSceneManager

The Collapse method is included only from VEG 8.0 SP4 or later.

This object is used to modify elements in the scene. Modifications do not persist automatically. The go_scene_save operation has to be called to persist changes to a disk file.

All scene changes are transactional in nature, and must be performed by calling the BeginChanges() method of this interface, followed by the changes to perform, followed by a Commit() call on the object returned by BeginChanges().

Attempting to perform a scene change outside of a BeginChanges()…Commit() scope will cause an exception to be raised.

The scene manager implements the ISceneReader interface as well as the ISceneReaderWriter interface, however, properties that return modifiable scene elements return *ReaderWriter objects that correspond to their Reader equivalents, for example, INodeReaderWriter has all of the properties of INodeReader, but also adds read-write access to select properties.

Properties
PropertyDescription
BomsA sequence of IBomReaderWriter for all BOMs in the scene
CurrentBomAn IBomReaderWriter representing the currently active BOM
HasAssemblyHierarchy Indicates whether the current scene has assembly (instance-reference) hierarchy.
NumberOfFaces

Gets the number of faces the current scene has.

NumberOfVertices

Gets the number of vertices the current scene has.

ProceduresA sequence of IProcedureReader for all procedures in the scene. A procedure has multiple steps.
PortfoliosA sequence of IPortfolioReader for all portfolios in the scene.
RootNodes

A sequence of INodeReaderWriter representing the public root nodes of the current BOM. Equivalent to: scene.CurrentBom.RootNodes.

RootNodesIncludingInternalA sequence of INodeReaderWriter representing all root nodes of the current BOM. Equivalent to: scene.CurrentBom.RootNodesIncludingInternal.
SourceFilePathA string containing the path to the source file this scene was opened from.
Methods
MethodDescription
ActivateBom(bom)

Activates a BOM. The scene's CurrentBom property will be set to this BOM once the modification scope is committed.

ArgumentDescription
bomAn IBomReader or IBomReaderWriter representing the BOM to activate
ActivateModelview(modelview)

Activates a model view.

ArgumentDescription
modelviewAn IModelviewReader representing the model view to activate.
ActivateStepview(step)

Activate the given step of a procedure.

ArgumentDescription
stepAn IStepReader representing the step view to activate.
ApplyMetadataFromManifest(filepath)

In some cases parts' metadata is lost in assemblies vds files. This happens if virtual entities or Assembly Level Features are being involved. This function is being used as part of scriptable operation in process jmp_BuildViewables_Build3D. Available in version 9.10 (9.0 FP10) onward.

ArgumentDescription
filepathA path to the file that has MultiBOM structure matching the current assembly and containing needed metadata
BeginChanges()

Starts a new change scope. Nested change scopes are not permitted. All scene changes made after this call will be added to this scope, to be applied when the scope is committed.

Return Value
An ISceneChangeScope object that can be used to commit the changes.
 Collapse()

 Accepts an arbitrary collection of nodes, collapses them and adds the collpased node as a child of the youngest common ancestor of the input set nodes.

ArgumentTypeMandatoryDescription
targetNodesIEnumerable<INodeReader>YesNodes to be collapsed
CreateNode(name)

Creates a top-level node in the scene with the specified.

Return Value
An INodeReaderWriter object.
DeleteAllPortfolios()Deletes all portfolios and their ModelViews from the scene. This operation will modify the scene permanently and is not undoable.
DeleteViewport(viewport)Deletes supplied viewport. Portfolios and ModelViews are Viewports. This method accepts both. If a porftolio is being deleted, all its child ModelViews will be automatically deleted too. This operation will modify the scene permanently and is not undoable.
ExecuteQuery()

Executes an RHQ query on this scene.

ArgumentType and Description
queryString - the query text
Return Value 
True if query succeeded, false otherwise.
ExecuteQueryFromFile()

Executes an RHQ query on this scene.

ArgumentType and Description
queryFilePathString - Fully qualified path to the RHQ file containing the query to execute.
Return Value
True if query succeeded, false otherwise.
ReGenerateHiddenCADMetadata()Creates hidden metadata values as they were in VEG 8.0 for RH format. This function was added for backward compatibility for clients who still use RH format and their processing depends on that hidden metadata. After the metadata is created, the file has to be saved to RH format because VDS format will not support it.
RemoveAssemblyHierarchy()

Removes assembly (instance-reference) hierarchy from the scene. This operation will modify the scene permanently and is not undoable. It is a prerequisute for scene hierarchy modification operations.

RenameViewport(viewport)Changes the name of supplied viewport. Portfolios and ModelViews are Viewports. This method accepts both. This operation will modify the scene permanently and is not undoable.
Example 1
scene = sap.graphics.factory.ActiveSceneManager
nodesToBeCollapsed = []
 
for node in scene.RootNodes:
    if node.Name == '_moto_x_asm' or node.Name == 'Skateboard':
        nodesToBeCollapsed.append(node)
        for rootChild in node.Children:
            if rootChild.Name == 'BODY_PANELS_ASM':
                nodesToBeCollapsed.append(rootChild)
 
with scene.BeginChanges():
  scene.ActivateBom(list(scene.Boms)[1])
  scene.Collapse(nodesToBeCollapsed)
Example 2 

This example renames a portfolio named "Portfolio 1" to "My fancy portfolio".

scene = sap.graphics.factory.ActiveSceneManager
  
with scene.BeginChanges():
  for portfolio in scene.Portfolios:
    if portfolio.Name == 'Portfolio 1':
      scene.RenameViewport(portfolio, 'My fancy portfolio')
Example 3 

This example deletes portfolio's "Portfolio 1" ModelViews

scene = sap.graphics.factory.ActiveSceneManager
  
with scene.BeginChanges():
  for portfolio in scene.Portfolios:
    if portfolio.Name == 'Portfolio 1':
      for modelview in portfolio.Modelviews:
        scene.DeleteViewport(modelview)
Example 4 

This deletes all portfolios

scene = sap.graphics.factory.ActiveSceneManager
  
with scene.BeginChanges():
  scene.DeleteAllPortfolios()
Example 5 

This creates hidden metadata for backward compatibility with custom processes

scene = sap.graphics.factory.ActiveSceneManager

with scene.BeginChanges():
     scene.ReGenerateHiddenCADMetadata()
Example 6 

This applies metadata from manifest. Available in version 9.10 (9.0 FP10) onward.

import sap

scene = sap.graphics.factory.ActiveSceneManager
with scene.BeginChanges():
   scene.ApplyMetadataFromManifest(sap.input_parameters['Schema1FilePath'])



ISceneChangeScope

This is the interface for the object returned by ISceneManager.BeginChanges(). Only one of these can exist at a time within a Visual Enterprise Generator process, nesting is not permitted, and will cause an exception to be raised.

Methods
MethodDescription
Commit()Commits all changes in the current scope and modifies the correspend elements in the scene. No elements in the scene will be modified until this method is called.
Discard()Discards all changes in the current scope. No objects will be modified.

Because changes are only made to scene objects when the scope is committed, if you read a modified property before its change is committed, you will still see the old value.


IBomReaderWriter

This is a superset of IBomReader, which exposes INodeReaderWriter versions of its child nodes. Everything else about the interface is the same.


INodeReaderWriter

The methods Collapse, ChangeMetadata, RemoveMetadata are included only in VEG 8.0 SP 04 or later.

This is a superset of INodeReader, and includes all of the properties of INodeReader, but it also makes some properties writable, and adds some methods.

Writable Properties
PropertyDescription
ClosedWhether or not the node is closed, can be set to true or false
NameThe name of the object, can be set to a new name.
SelectedGets or sets the node selection status. Setting the node selection status will only take effect when the containing change scope is committed.
Additional Methods
MethodDescription
AssignMaterial()

Assigns specified material to the selected node. The material MUST exist on the scene before calling this method. If the material wasn't previously present, it can be added to the scene by using operation “go_material_import” with parameter “filename” value as path to material file e.g. “Gem Emerald.rhm”

ArgumentTypeMandatoryDescription
materialstringYesThe name of the material that has to be assigned to the node
Delete()Deletes this node. If this node is part of an instanced parent object, it will be deleted from all instances.
Collapse()
Collapses the scene hierarchy below this node.
ChangeMetadata() 

Allows setting of new metadata and changing of existing metadata on this node. Metadata can also be changed on all instances of this node.

ArgumentTypeMandatoryDescription
categorystringYesThe category of the new metadata to be set or existing metadata to be changed.

keyname

stringYesThe key of the new metadata to be set or existing metadata to be changed.
valueobjectYesThe metadata value to be set
setOnAllInstances bool No Indicates whether the metadata change should be reflected on all instances of the node. Treated as set to false, if not explicitly set to true.
MovePivotPointObjCenter()
Moves the pivot point of the object represented by this node to the object's center.
MovePivotPointSceneCenter()
Moves the pivot point of the object represented by this node to the whole scene's center.
RemoveMetadata()

Allows removal of metadata under the specified category and keyname on this node. If no keyname is specified, all metadata under the category is removed. Metadata can also be removed from all instances of the node.

ArgumentTypeMandatoryDescription
category                          stringYes             The category of the metadata to be removed.

keyname

stringNoThe keyname category of the metadata to be removed.
removeOnAllInstancesboolNoIndicates if the metadata removal is to affected on all instances of the node. Treated as set to false, if not explicitly set to true.
SetParent()

Changes the node parent. This will only take effect when the containing change scope is committed, if the parent node is not null and if the scene does not contain any assembly (instance-reference) hierarchy.

ArgumentTypeMandatoryDescription
parentINodeReaderYesThe new parent node
Example
scene = sap.graphics.factory.ActiveSceneManager
metadataToBeSet = ["KNA1","VBKA", "VBAK", True, 7642, 16.25]
with scene.BeginChanges():
  for node in scene.RootNodes:
    if node.Name == 'DeleteMe':
		node.Delete()
    else:
        node.Name = 'PREFIX' + node.Name
    if node.Name == 'System Wheel':
        node.ChangeMetadata('SAP', 'MATERIAL', '100000045786', True)
        node.ChangeMetadata('SAP', 'SALES', metadataToBeSet)
        node.RemoveMetadata('SAP', 'QUANTITY')
        node.RemoveMetadata('CADMetadata')
        wheelChild.RemoveMetadata('VE', removeOnAllInstances=True)
        node.MovePivotPointObjCenter()
        node.AssignMaterial("Gem Emerald")
        	


sap.workflow.settings

This object provides access to the workflow settings for the current job. 

Properties
PropertyDescription
WorkflowNameGets a string name of the current workflow. This feature is available from VEG version 9.0 FP11 (9.11)
Example

This example retrieves the workflow name and produces warning message in the log.

sap.log.warning("----Workflow Name is " + sap.workflow.settings.WorkflowName)


Methods
MethodDescription
GetValueByName(name)

Gets the workflow setting by setting name. Uses case sensitive comparison.

ArgumentDescription
name

A string containing the name of the setting. The name of a setting is different from the display name, and is unaffected by system locale settings.

The setting name can be found in Visual Enterprise Generator 8.0 SP2 or later, when editing the settings for a particular workflow in the Visual Enterprise Generator Administration tool, above the description of the setting in italics:

GetValueByDisplayName(displayName)

Gets a workflow setting by setting display name. Uses case insensitive comparison.

ArgumentDescription
displayNameThe display name of the setting.

The setting display name is not locale independent, therefore, if the system locale changes (for example, from English to German), this lookup may fail because the display name used will change based on the system locale. If this is a problem, use the setting name instead.


Example

This example retrieves a workflow setting by name and display name.

workflowSettings = sap.workflow.settings
 
# Retrieve setting by name
setting = workflowSettings.GetValueByName("StorageCategory")
sap.log.info("Setting 'StorageCategory' value is '%s'" % setting)
 
# Retrieve setting by display name (a collection of matches is returned)
settingCollection = workflowSettings.GetValueByDisplayName("storage category")
sap.log.info("Found %s values for setting 'storage category'" % settingCollection.Count())
for setting in settingCollection:
  sap.log.info(" - Setting 'storage category' value is '%s'" % setting)


# Retrieve setting by name using indexer
setting = workflowSettings["StorageCategory"]
sap.log.info("Setting 'StorageCategory' value is '%s'" % setting)


sap.job.startup_arguments

This object provides access to the start-up arguments for the current job.

This object is only included in Visual Enterprise Generator 8.0 SP4 or later.


Methods
MethodDescription
GetValueByName(name)

Gets the start-up argument by start-up argument name. Uses case sensitive comparison.

ArgumentDescription
name

A string containing the name of the start-up argument.

The start-up argument name can be found in Visual Enterprise Generator 8.0 or later, when viewing the job report for a particular job in the Visual Enterprise Generator Administration tool:


Example

This example retrieves a job start-up argument by name.

jobStartupArgs = sap.job.startup_arguments
 
# Retrieve start-up argument by name
startupArg = jobStartupArgs.GetValueByName("ExtractAllConfigsIfNoneSpecified")
sap.log.info("Start-up argument 'ExtractAllConfigsIfNoneSpecified' value is '%s'" % startupArg)
 
# Retrieve start-up argument by name using indexer
startupArg = jobStartupArgs["ExtractAllConfigsIfNoneSpecified"]
sap.log.info("Start-up argument 'ExtractAllConfigsIfNoneSpecified' value is '%s'" % startupArg)


sap.process.settings

This object provides access to process settings.

Properties
PropertyDescription
StartTimeGets the timestamp for the time that the process started executing, as a .NET DateTime structure
TimeOutGets the timeout of the process in seconds, as an integer value
TimeOutTimeGets the the time when this process will timeout, as a .NET DateTime structure
Example

Logs the process settings.

processSettings = sap.process.settings
sap.log.info("Process started at '%s' with a timeout of %s seconds and will be killed at '%s' if it does not complete by then." % (processSettings.StartTime, processSettings.TimeOut, processSettings.TimeOutTime))


sap.jobid

Returns the job ID of the current job, as a 64-bit integer.

sap.parentjobid

Returns the job ID of the parent job, if any, otherwise, returns 0, as a 64-bit integer.


MataiDirect API

This section has been moved to a separate page: MataiDirect API

Appendix A: Creating a Scriptable Operation

Scriptable operations are created inside the Process Designer, with either a new or existing process opened.

To create the definition for a new scriptable operation, choose Operations -> New Scriptable Operation.

To edit the definition of an existing scriptable operation, open the toolbox where the operation was saved, right-click the operation, and choose Edit.

This will display the Operation Editor window for the new operation:

The Operation Editor lets you modify the operation name and display name (for new operations), the description, and the input and output parameters that will be available to pass data in and out of the operation.

Right-click a parameter in the Input or Output panel to edit advanced properties of the parameter or change its default assigned name.

If you set the value of the code sub-parameter of the script parameter to some Python script code, this will be the default code for new instances of this operation. You can use this feature to implement operations solely using Python. Note: This requires Visual Enterprise Generator 8.0 SP2 or later.



  • No labels