ObjProperty
You can use this function for Optiva Workflows, Copy Methods, and Equations.
Purpose
The function ObjProperty retrieves a field from the database and places it in a local variable. This function can also be used to retrieve an array of data.
Syntax for header data
object ObjProperty(string propertyName, string objSymbol, string objectKey, string rowkey, string keycol)
Return Value
If the code is successful, the scrit displays the value as an object. Data type of the result depends on the type of field, but when programming in C#, automatic conversions are not allowed, and immediate conversion to string or numeric data type can result in an error if the attribute is blank, or the result can be a single value or array of values.
ObjProperty retrieves property values from workflow objects. If multiple rows match the criteria, it returns an array of values; if only one row matches, it returns a single string. When the RowKey uses a wildcard (*), it always returns an array.
Usage: ObjProperty can be used in 3 types based on the type of fields
- Simple field - Header fields such as Description, Status, or an extension field.
- Column of data in a table where all the rows can be returned to the variable, Eg - All Item Codes in the Item Lines table.
- Specific cell of a table - Eg, PValue for the DENSITY parameter in Parameters table/grid or the qty of a specific item in the Item Lines table.
Arguments
| Part | Description | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
propertyName |
The propertyName represents the name of the field that needs to be retrieved and is a combination of Field name and possibly Detail code and other identifiers. References for Field name and Detail code include the Data Dump from a representative object, the Field Label form, Validation form (or FsValidationField database table), Extension table definition form, Lookup Set form, and Symbol form (Extensions tab) depending on the attribute type. Different ways to frame propertyName argument are demonstrated below -
Type 1 attributes (simple Field name only):
Examples: DESCRIPTION, CLASS, COMPONENTIND, C_FACILITY
Type 2 attributes (Simple field + Detail code, no RowKey/KeyCol):
Type 3 attributes (single-table data): A property name requires at least a Detail code. However, certain tables—such as Extension tables, References, and Views—need additional processing beyond the Detail code. This extended processing is referred to as Type 4 logic. Follow these steps to correctly construct the propertyName argument when a Detail code is required for most table attributes - Step 1 : Find the Detail code (DTLCODE) of the desired attribute using the 'objectdtlinfo' table in the Data Dump from any object of the desired type. The codes are generally logically named, such as DOC, TPALL, INGR, ALTINGR, BYPROD, etc. Step 2 : To find the Field name for the identified DTLCODE, start by obtaining the corresponding 'VALIDCODE' from the same table in the data dump (e.g. G.FORMINGRED, G.SPECPARAM). Step 3 : Open the Field Label form, selecting the VALIDCODE as Validation Code. Step 4 : Find the desired field name in the Field Label’s Data Name column. The Validation form can alternately be used instead of Field Label but is not included in the UI label for reference to the user interface, and requires a profile attribute that allows access to columns beyond ATTRIBUTEx. Examples: VALUE.TPALL, TARGET.TP, QUANTITY.INGR, LABCODE.USERROLE
Note: Ensure the field name is exactly as it appears in the Data Name column in the Field Label form, or FIELD_NAME column of the Validation form. If preferred, DB_Name can also be used.
Refer to the examples for better understanding. Type 4 (multi-table data):
|
||||||||||
objSymbol |
The object type or current object type of the data.
Note: Use empty quotation marks to indicate the current symbol of the workflow.
|
||||||||||
rowKey |
Required when accessing table data Case 1 : Access all rows of the column, such as all Item Codes in the formula item lines table: Use the asterisk (*) symbol only, in double quotes. Example: ObjProperty("ITEMCODE.INGR", "", "", "*");
Case 2 : Retrieves data from a specific cell in a table. The row can be identified by:
When using a line ID or other numeric value, do convert the number or numeric variable to string. For example, to specify the Line ID where a loop counter variable “x” is referenced, the rowkey is x.ToString(). |
||||||||||
keycol |
Required when a rowkey has been specified to return table data Case 1 : Accessing all rows of the column, using (*) for rowkey: The column key can be skipped completely, although most users prefer a placeholder such as "" or 1. Example : Case 2 : Accessing a specific cell of the table
|
Description
ObjProperty retrieves the value of an object and places it in a local variable. Use this function to gather values for other statements.
You can also use it in conjunction with IsBlank to check if a field value is null before retrieving it.
To use Option Strict On and Option Strict Off with ObjProperty, see Data type returns with Strict On and Strict Off.
Workflow examples that follow also apply to copy methods and equations.
Examples
Example 1: (Header Data Examples) Retrieving the value of STATUS for formula PIZZA/0001
-
• As per our requirement, objSymbol is formula and objectKey is PIZZA/0001.
- Let's frame the propertyName by following the below process.
-
Consider these tables for reference - STATUS is the detail code for Status field as per objectdtlinfo(FORMULA) table.
Table 3. objectdtlinfo (FORMULA) Symbol DTLCODE VALID_CODE FORMULA STATUS G.OBJSTATUS FORMULA DOC G.DOCUMENT
Let us consider the table under VALID_CODE for DTLCODE STATUS: G.OBJSTATUS
| Data Name | Label |
|---|---|
| ROLLUPID | Rollup ID |
| STATUSIND | Status |
| UOMCODE | UOM |
propertyName: STATUSIND.STATUS (FIELD_NAME - STATUSIND, DTLCODE - STATUS)
objSymbol: FORMULA
objectKey: PIZZA\0001
rowkey: Not a table value, so not needed
keycol: Not a table value, so not needed
Function Call: ObjProperty("STATUSIND.STATUS", "FORMULA", "PIZZA\0001");
object oStatus = ObjProperty("STATUSIND.STATUS", "FORMULA", "PIZZA\0001");
Example 2: (Header Data Examples) Retrieving the value of CLASS for any Item
- As per our requirement, objSymbol is formula and objectKey is PIZZA/0001.
- Let us frame the propertyName by following the below process.
- Class is a standard Header field and is not part of the Status or Security fields. Therefore, no detail code is needed.
- Next, open the Field Label form, and select the symbol (ITEM) as Validation Code.
Note the Data Names possibly including a custom label
| Data Name | Label | Custom Label |
|---|---|---|
| CALCIND | Calculation Type | |
| CLASS | CLASS | Item Type |
| COMMCODE | Common Name | Label Name |
Let's consider the table under VALID_CODE for DTLCODE STATUS : G.OBJSTATUS
| Data Name | Label |
|---|---|
| ROLLUPID | Rollup ID |
| STATUSIND | Status |
| UOMCODE | UOM |
In this case, CLASS is the propertyName but users see a custom label. They have written the request as a requirement to get the “Item Type”. The Field Label table tells us the standard name and field name for the attribute.
As this is a basic field, no rowKey or keyCol entries are needed.
propertyName:CLASS
objSymbol: ITEM
objectKey: Empty quotations to resemble current object.
rowkey: Not a table value, so not needed
keycol: Not a table value, so not needed
Function Call: ObjProperty("CLASS", "ITEM", "");
object sItemClass = ObjProperty("CLASS", "ITEM", "");
MessageList("The item type is: ", sItemClass.ToString());
Example 3 : Retrieving the value of DESCRIPTION for any ITEM
- As per our requirement, objSymbol is ITEM and objectKey is the current object on which the workflow is launched. Empty quotations can be used.
- Let's frame the propertyName by following the below process.
- Description is a standard Header field. Therefore, no detail code is needed.
propertyName: DESCRIPTION
objSymbol: ITEM
objectKey: Empty quotations to resemble current object.
rowkey: Not required
keycol: Not required
Function Call: ObjProperty("DESCRIPTION", "ITEM", "");
Code: string itemDescr = ObjProperty("DESCRIPTION", "ITEM", "").ToString();
MessageList("Header description Curr obj: " + itemDescr);
Example 4: Retrieving the value of DENSITY parameter for any ITEM/FORMULA
- • As per our requirement, objSymbol is ITEM/FORMULA (Can be any symbol based on requirement) and objectKey is the current object on which the workflow is launched. Empty quotations can be used.
- The fields where parameter values are typically stored include:
- VALUE – Represents the actual value of the parameter.
- MINVAL – Indicates the minimum permissible value.
- MAXVAL – Indicates the maximum permissible value.
Other columns are also required such as the ATTRIBUTE# columns, CALCIND, etc.
- Let's frame the propertyName by following the below process.
- Let's frame the propertyName by following the below process.
- Consider these tables for reference - TPALL is the detail code for Parameters on Items, Formulas and Projects (Note that for Label Content and Specification, the detail code is “TP”)
| SYMBOL | DTCODE | TABLENAME | VALID_CODE |
|---|---|---|---|
ITEM |
DESCR |
FSDESCRIPTION |
G.DESCR |
ITEM |
ST |
FSITEMST |
G.SETITEM |
ITEM |
LABEL |
FSITEMLABEL |
G.ITEMLABEL |
ITEM |
STATUS |
FSITEMSTATUS |
G.OBJSTATUS |
ITEM |
TPALL |
FSITEMPALL |
G.TECHPVAL |
| SYMBOL | DTCODE | TABLENAME | VALID_CODE |
|---|---|---|---|
FORMULA |
DESCR |
FSDESCRIPTION |
G.DESCR |
FORMULA |
ST |
FSFORMULAST |
G.SETFORMULA |
FORMULA |
INGR |
FSFORMULAINGR |
G.FORMINGRED |
FORMULA |
BYPROD |
FSFORMULABYPROD |
G.FORMBYPROD |
FORMULA |
STATUS |
FSFORMULAINGR |
G.OBJSTATUS |
FORMULA |
TPALL |
FSFORMULATPALL |
G.TECHPAL |
FORMULA |
REF |
FSFORMULAREF |
V\REFERENCE |
Let's consider the table under VALID_CODE for DTLCODE TPALL : G.TECHPVAL
| VALIDATION_CODE | VALIDATION_SUBCODE | FIELD_NAME | FIELD_NO |
|---|---|---|---|
G.TECHPVAL |
DENSITY |
MAXVAL |
200 |
G.TECHPVAL |
DENSITY |
MINVAL |
200 |
G.TECHPVAL |
DENSITY |
VALUE |
|
G.TECHPVAL |
FATS_SATS |
MAXVAL |
200 |
G.TECHPVAL |
FATS_SATS |
MINVAL |
200 |
G.TECHPVAL |
FATS_SATS |
VALUE |
200 |
When reviewing the table, note that the VALIDATION_SUBCODE acts as a unique identifier for differentiating fields that share the same name.
This is important because certain field names, such as VALUE, can appear multiple times for different parameters.
For our specific parameter, the VALIDATION_SUBCODE is DENSITY.
The corresponding Field Name is VALUE. As per the objectdtlinfo table, the DTLCODE is TPALL.
propertyName: VALUE.TPALL (FIELD_NAME - VALUE, DTLCODE - TPALL)
objSymbol: Empty quotations to resemble current symbol.
objectKey: Empty quotations to resemble current object.
rowke: It Indicates the key (Parameter code) - DENSITY
keycol: Preferred method - What is the DB_FIELD_NAME of the column where the code "DENSITY" is found? PARAM_CODE.
Less preferred, historically used method: Take the value of DB_FIELD_NO for the desired field, Divide it by 100 -> DB_FIELD_NO/100 => 200/100 = 2.
ObjProperty("VALUE.TPALL", "", "", "DENSITY", "PARAM_CODE");ObjProperty("VALUE.TPALL", "", "", "DENSITY", "2");
Code Snippet:
object oDens = ObjProperty("VALUE.TPALL", "", "", "DENSITY", "PARAM_CODE");
If (IsBlank(oDens) == 0)
MessageList("Density value is : " + oDens.ToString());
- As per the requirement, objSymbol is SPECIFICATION (Can be any symbol based on requirement) and objectKey is SPEC/0001.
- Let's frame the propertyName by following the below process.
- DTLCODE can be found in the object specifc objectdtlinfo table.The DTLCODES related guide is also attached for reference.
- Consider these tables for reference - CONTEXT is the detail code for Context Attributes
| SYMBOL | DTLCODE | TABLENAME | VALID_CODE |
|---|---|---|---|
SPECIFICATION |
PER |
FSSPECIFICATIONPER |
G.OBJSECURITY |
SPECIFICATION |
DESCR |
FSDESCRIPTION |
G.DESCR |
SPECIFICATION |
MATRIX |
MATRIX |
V\DATAMATRIX |
SPECIFICATION |
INGR |
FSSPECIFICATIONINGR |
G.SPECINGRED |
SPECIFICATION |
CONTEXT |
FSSPECIFICATIONCONTEXT |
G.OBJECTCONTEXT |
SPECIFICATION |
STATUS |
|
G.OBJSTATUS |
SPECIFICATION |
CUSTOM |
FSSPECIFICATION_CUSTOMATTRIB |
G.CUSTOM |
Let's consider the table under VALID_CODE for DTLCODE TPALL : G.OBJECTCONTEXT (The Validation details for Context are global to all object types)
| VALIDATION_CODE | VALIDATION_SUBCODE | FIELD_NAME | DB_FIELD_NAME |
|---|---|---|---|
G.OBJECTCONTEXT |
ATTRIBCODE |
ATTRIB_CODE |
|
G.OBJECTCONTEXT |
DESCRIPTION |
DESCRIPTION |
|
G.OBJECTCONTEXT |
ATTRIBVAL |
ATTRIB_VAL |
|
G.OBJECTCONTEXT |
C_BRAND |
ATTRIBVAL |
ATTRIB_VAL |
G.OBJECTCONTEXT |
C_ENDUSE |
ATTRIBVAL |
ATTRIB_VAL |
G.OBJECTCONTEXT |
C_ENDUSER |
ATTRIBVAL |
ATTRIB_VAL |
G.OBJECTCONTEXT |
C_PRODTYPE |
ATTRIBVAL |
ATTRIB_VAL |
G.OBJECTCONTEXT |
MFGLOC |
ATTRIBVAL |
ATTRIB_VAL |
G.OBJECTCONTEXT |
SELLOC |
ATTRIBVAL |
ATTRIB_VAL |
As per our requirement we can choose the field name related to the specific Attribute code, in this case C_BRAND. The Field name available for the attribute types is ATTRIBVAL
propertyName: ATTRIBCODE.CONTEXT (FIELD_NAME - ATTRIBCODE, DTLCODE - CONTEXT)
objSymbol: SPECIFICATION
objectKey: SPEC/0001
rowkey: It Indicates the key (ATTRIB_CODE) - C_BRAND
keycol: Brand, Selling Location, etc. are attribute codes, so the keycol is the DB_FIELD_NAME ATTRIB_CODE.
Function Calls: ObjProperty("ATTRIBVAL.CONTEXT", "SPECIFICATION", "SPEC/0001", "C_BRAND", "ATTRIB_CODE");
var oAttribVal = ObjProperty("ATTRIBVAL.CONTEXT", "SPECIFICATION", "SPEC/0001", "C_BRAND", "ATTRIB_CODE");
MessageList("context val: " + oAttribVal.ToString());
The data resulting from this ObjProperty call is nothing/null if there are no Brands, a string if there is only one Brand, and an array if there are multiple.
Therefore, the use of the oAttribVal variable needs to be tested before passing to an alert message or other code, and often the simplest approach is to always create an array from the result such as this example that converts the ObjProperty result into an array of either 1 or multiple values.
var RawValue = ObjProperty("ATTRIBVAL.CONTEXT", "", "", "MFGLOC", "ATTRIB_CODE");
if (RawValue is not null && RawValue is Array)
{
string[] ContextValues;
if (RawValue is Array)
{
ContextValues = (string[])RawValue;
}
else
{
ContextValues = new string[1];
ContextValues[0] = RawValue.ToString();
}
}
Example 4.1: Retrieving the Context attributes of all codes for SPECIFICATION SPEC/0001
In order to retrieve all the context attributes (of all codes) for any specific object, use below code -
//Retrives all the attribute codes as an array of type Object.
object[] attribCodes = (object[])ObjProperty("ATTRIBCODE.CONTEXT", "SPECIFICATION", "SPEC/0001", "*", 1L);
//Retrives all the attribute values as an array of type Object.
object[] attribValues = (object[])ObjProperty("ATTRIBVAL.CONTEXT", "SPECIFICATION", "SPEC/0001", "*", 1L);
if(attribCodes!=null)
{
for (int i = 0; i<attribCodes.Length;i++)
{
MessageList("ATTRIBCODE: " + attribCodes[i] + "ATTRIBVAL: " + attribValues[i]);
}
}
Example 5: The following example demonstrates how to call functions to retrieve all Ingredients (Items) and their corresponding quantities for any formula:
Detail Code: INGR – Represents the Item Lines tab.
Field Names: ITEMCODE – Used to retrieve the Item Code (ingredient name), QUANTITY – Used to retrieve the Item Quantity. These are the names for the rows where the value exists.
By using these field names in the function calls, you can extract both the ingredient details and their quantities efficiently.
object[] lines = (object[])ObjProperty("ITEMCODE.INGR", "FORMULA", "", "*", 1L);
object[] qty = (object[])ObjProperty("QUANTITY.INGR", "FORMULA", "", "*", 1L);
Example 6: Retrieve all References and types from any object
- In this case, the rowKey = *will retrieve all rows of the table in the chosen column(s).
- The data result is an array unless there are no rows of the table, in case the result is null in C#.
- REF is the detail code for References referenced in any object.
propertyName: OBJECTCODE.REF (FIELD_NAME - OBJECTCODE, DTLCODE - REF)
objSymbol: Empty quotations to resemble current symbol.
objectKey: Empty quotations to resemble current object key.
rowkey: *
keycol: Not Required//Retrives all the reference codes as an array of type Object.
string[] oRef = (string[])ObjProperty("OBJECTCODE.REF", "", "", "*");
//Retrives all the reference types as an array of type Object.
string[] oRefType = (string[])ObjProperty("OBJECTTYPE.REF", "", "", "*");
for (int y = 0; y < oRef.Length; y++)
{
MessageList($"Referenced {oRefType[y]} is {oRef[y]}");
}
Example 6.1: Retrieve Reference(s) of any specific type for any object
propertyName: OBJECTCODE.REF (FIELD_NAME - OBJECTCODE, DTLCODE - REF)
objSymbol: Empty quotations to resemble current symbol.
objectKey: Empty quotations to resemble object key.
rowkey: VENDOR
keycol: R_OBJECT_TYPE
var objCodes = ObjProperty("OBJECTCODE.REF", "", "", "VENDOR", "R_OBJECT_TYPE");
if (objCodes is Array refCodeArray && refCodeArray.Length > 0)
{
for (int i = 0; i < refCodeArray.Length; i++){
string firstRefCode = refCodeArray.GetValue(i).ToString();
// Use firstRefCode as needed here
MessageList($"RefCode: {firstRefCode}");
}
}
else
{
MessageList($"The Referenced Object is {objCodes}");
}
Example 7: Retrieving values from Extension Table (Matrix)
ObjProperty -> ObjProperty(string propertyName, string objSymbol, string objectKey, string rowkey, string keycol)
- As per our requirement, objSymbol can be any symbol based on requirement and objectKey is the current object on which the workflow is launched. Empty quotations can be used.
- Let's frame the propertyName by following the below process.
- MATRIX is the detail code for Extension Table/Custom Table/Matrix in any object.
propertyName: Field<#>.MATRIX.V\DM<Symbol#>
The first argument is made up of three parts. Each part tells the system which data to retrieve and from where.
FIELD<#> – FIELDrefers to a column name in a data grid (matrix).- The details associated to this data grid can be found in the object specific MATRIX tables in the database.
- Example:
FS_FORMULAMATRIX_0resembles first matrix table associated with the formula. - The <#> is a number that tells the system which column to use.
- Columns are numbered internally, starting from 1.
- Example: FIELD1 → first column, FIELD2 → second column etc.
- MATRIX is the name of detail code for Extension Table
V\DM<Symbol#>- This tells the system exactly which Data Matrix table to use.- Data Matrix tables are given internal numbers by the system.
- To reference a specific table, use the prefix "V\DM", followed by the symbol name, and then a table number.
- The table numbers start at 0.
- Example: First table → V\DMProject0, Second table → V\DMProject1 etc.
- Points to remember:
- To find the correct Data Matrix table number, check the FsDataMatrix table.
- This table shows how many Data Matrix tables exist for each symbol.
- Example: Let's consider for the Project symbol, the below table indicates that there are two Data Matrix tables.
Use the value in the VIEW_ID column as the table number. First table → V\DMProject0 resembles SAMPLE SHIPMENTS table.
Example 7.1: Retrieving all the Values of a column in an Extension Table
ObjProperty(@"FIELD2.MATRIX.V\DMPROJECT0", "", "", "*");
- property Name : "FIELD2.MATRIX.V\DMPROJECT0" (FIELD2 → Specifies the second column to retrieve, MATRIX → Indicates the data comes from a Data Matrix, V\DMPROJECT0 → Identifies the Project Data Matrix table, table number 0)
- objSymbol : Empty quotations to resemble current symbol.
- objectKey: Empty quotations to resemble object key.
- rowkey : * To retrive all the rows for that column.
class ActionScript : FcProcFuncSetEventWF
{
public long wf_start()
{
var extensionTableData = ObjProperty(@"FIELD2.MATRIX.V\DMPROJECT0", "", "", "*");
if (extensionTableData is Array dataArray && dataArray.Length > 0)
{
MessageList("Values of Column FIELD2 :");
for (int i = 0; i < dataArray.Length; i++){
string fieldVal = dataArray.GetValue(i).ToString();
// Use Values as needed here
MessageList($"Value {i} : {fieldVal}");
}
}
else
{
MessageList($"The Data is {extensionTableData}");
}
return 111L;
}
}
Example 7.2: Retrieving a Value from an Extension Table
This example demonstrates to retrieve the brand value of Lauren Vendor.
Let's Consider below example of Extension table in project form| Line ID | Brands | Vendor |
|---|---|---|
| 1 | EXTENDEDLONGBRAND1Z_AG |
ABBOUND |
| 2 | BRAND2_AG |
LAUREN |
| 3 | EXTENDEDLONGBRAND4Z_AG |
LEVIS |
Here, the column names of Line ID, Brands, Vendor are FIELD1, FIELD2, FIELD3 respectively as per FS_PROJECTMATRIX_0 table.
This example retrieves the value from the second column (FIELD2) of the row where the FIELD3 value is LAUREN.
Function Call: ObjProperty(@"FIELD2.MATRIX.V\DMPROJECT0", "", "", "LAUREN", "FIELD3");
- property Name : "FIELD2.MATRIX.V\DMPROJECT0" (FIELD2 → Specifies the second column to retrieve, MATRIX → Indicates the data comes from a Data Matrix, V\DMPROJECT0 → Identifies the Project Data Matrix table, table number 0)
- objSymbol : Empty quotations to resemble current symbol.
- objectKey: Empty quotations to resemble object key.
- rowkey - LAUREN
- colKey - FIELD3
Process:
- Look in Project Data Matrix table 0 (V\DMPROJECT0).
- Find the row where FIELD3 equals "LAUREN".
- From that row, return the value in FIELD2 (the second column).
class ActionScript : FcProcFuncSetEventWF
{
public long wf_start()
{
var tbl = ObjProperty(@"FIELD2.MATRIX.V\DMPROJECT0", "", "", "LAUREN", "FIELD3");
MessageList(tbl.ToString());
return 111L;
}
}