Was this helpful?
DeclareAttribute Method
The DeclareAttribute method lets you declare a named parameter and its corresponding data type. The data type is used for constructing a VARIANT to contain the named parameter when it is passed to the 4GL procedure using the RSO CallProc method:
HRESULT DeclareAttribute
    (
        [in] BSTR AttributeName,
        [in] BSTR AttributeDataType
    );
This method uses the following parameters:
AttributeName
Specifies a string that contains the name of the corresponding parameter in the 4GL procedure to be called
AttributeDataType
Specifies a string that defines the VARIANT type used when passing the data to be mapped to that 4GL parameter
The following table describes the AttributeDataType names:
AttributeDataType Name
VARIANT Type Used
"SMALLINT"
VT_I2
"INTEGER"
VT_I4
"I8"
VT_I8
"FLOAT"
VT_R8
"DECIMAL"
VT_DECIMAL
"DATE"
VT_DATE
"MONEY"
VT_CY
"STRING"
VT_BSTR
"USERCLASS"
(nested array of VARIANT)
"UCARRAY"
(nested array of VARIANT)
A structured attribute representing a user class is declared with type "USERCLASS." A structured attribute representing a user class array is declared with type "UCARRAY." Structured attributes can be nested to any number of levels. The nested attribute names are specified using OpenROAD 4GL "dot" syntax:
Set orPDO = Server.CreateObject("OpenROAD.ParameterData")
orPDO.DeclareAttribute "p_id", "INTEGER"
orPDO.DeclareAttribute "uc_emp", "USERCLASS"
orPDO.DeclareAttribute "uc_emp.empnam", "STRING"
orPDO.DeclareAttribute "uc_emp.hiredate", "DATE"
In this example, the PDO is being constructed to pass data to a 4GL procedure where uc_emp is the name of a user class parameter in the 4GL procedure, and that user class contains at least empname and hiredate attributes.
The name of a structured attribute must be declared before any of the attributes contained in it.
All desired attributes must be declared with the DeclareAttribute method before any values are set using SetAttribute. Once a value is set, no further declarations are allowed.
SetAttribute Method
The SetAttribute method sets the value of a named parameter. After the hierarchical structure of the PDO data has been declared using DeclareAttribute calls, that structure can be populated with values using the SetAttribute method:
HRESULT SetAttribute
    (
        [in] BSTR AttributeName,
        [in] VARIANT * AttributeValue
    );
This method uses the following parameters:
AttributeName
Takes a string containing the name of the scalar attribute for which a value is to be set. If the attribute is a nested attribute, its position in the hierarchical structure is expressed using OpenROAD 4GL “dot” syntax.
If the attribute is contained in a user class array, the row number is specified using OpenROAD 4GL subscripting syntax. As in the 4GL, if the next row beyond the current last row in the array is addressed, a new row is created automatically.
Set orPDO = Server.CreateObject("OpenROAD.ParameterData")
orPDO.DeclareAttribute "p_id", "INTEGER"
orPDO.DeclareAttribute "arr_uc_dept", "UCARRAY"
orPDO.DeclareAttribute "arr_uc_dept.name", "STRING"
...
orPDO.SetAttribute "p_I", 11
orPDO.SetAttribute "arr_uc_dept[1].name", "Finance"
AttributeValue
Takes the value to be stored in the VARIANT represented by that AttributeName.
Note:  This value is always coerced to the data type declared for that attribute. Depending on the actual type and value of the AttributeValue passed in, this coercion may fail and return an error. Three special cases are supported that bypass this coercion requirement: VT_EMPTY, VT_NULL, and the OpenROAD blank DATE (an empty string stored in a DATE attribute). Those special case values are stored in the associated VARIANT even though they are technically outside the range of legal values for the declared VARIANT data types.
After a value is set, it can be changed by a subsequent call to SetAttribute specifying a different value.
Note:  This method is valid for scalar attributes only. To set a structured attribute (that is, a user class or user class array) to empty or null, you must use the SetEmpty or SetNull methods.
GetAttribute Method
The GetAttribute method retrieves the value of a named parameter that was passed by reference and modified by the called 4GL procedure. When a PDO is passed through ByRef to the RSO CallProc method, the data contained in the PDO may be modified by the 4GL procedure. The PDO GetAttribute method lets you extract modified data from the PDO.
Attribute names are constructed using 4GL “dot” syntax, the same as in the SetAttribute method:
HRESULT GetAttribute
    (
        [in] BSTR AttributeName,
        [out, retval] VARIANT * AttributeValue
    );
This method uses the following parameters:
AttributeName
Takes a string containing the name of the scalar attribute from which the value is to be retrieved. If the attribute is a nested attribute, its position in the hierarchical structure is expressed using OpenROAD 4GL “dot” syntax, just as in the SetAttribute method.
AttributeValue
Specifies a retval that receives a copy of the value currently stored in the VARIANT represented by that AttributeName. Because it is a retval, scripting languages return this using syntax that represents a function return value.
Set orPDO = Server.CreateObject ("OpenROAD.ParameterData")
 orPDO.DeclareAttribute "p_id", "INTEGER"
 orPDO.DeclareAttribute "uc_emp", "USERCLASS"
 orPDO.DeclareAttribute "uc_emp.empname", "STRING"
 orPDO.DeclareAttribute "uc_emp.hiredate", "DATE"

orPDO.SetAttribute "p_id", 11
...
orRSO.CallProc "gethiredate", ,orPDO
...
vhiredate = orPDO.GetAttribute "uc_emp.hiredate"
Note:  The AttributeValue is always coerced to the data type declared for the attribute. Even though the value was already coerced to the declared data type by the SetAttribute method, the 4GL procedure may modify the data when a PDO is passed by reference to the CallProc. Because of the return mapping preferences, it may return a value that is not precisely the same type that was passed in.
For example, a FLOAT value mapped through ByRef to a DECIMAL 4GL parameter comes back as a DECIMAL VARIANT value. Coercing on the GetAttribute promotes the most predictable behavior for all scripting languages. It is possible—though highly unlikely—for this output coercion to fail because of different range limitations of similar types.
Three special cases are supported that bypass this coercion requirement: VT_EMPTY, VT_NULL, and the OpenROAD blank DATE (an empty string stored in a DATE attribute). Those special case values are retrieved from the associated VARIANT without coercion.
Depending on the scripting language in use, the assignment statement used for the GetAttribute call may not be able to process those special case values (VT_EMPTY, VT_NULL, empty string). Therefore, special methods (IsEmpty, IsNull, IsBlankDate) are provided to safely test an attribute value for special cases before attempting to get and assign the value to a program variable.
Note:  The GetAttribute method can retrieve scalar attributes only. To check whether a structured attribute (that is, a user class or user class array) is empty or null, you must use the IsEmpty or IsNull methods.
SetEmpty, SetNull, IsEmpty, IsNull Methods
Empty (VT_EMPTY) and null (VT_NULL) values have some special characteristics and require additional methods to support them, as described in the sections that follow.
Most PDO methods operate only on scalar attributes. A structured attribute usually contains a nested array of other attributes and does not have a scalar value that you can set or get directly. VT_EMPTY and VT_NULL are exceptions to the rule.
VT_EMPTY
A structured attribute can contain the value VT_EMPTY, and this is the default value of all attributes (scalar and structured) when they are first declared. All VT_EMPTY values are mapped to default instances of the corresponding parameter (or user class attribute) in the called 4GL procedure. When VT_EMPTY values are passed through ByRef, the default instances to which they were mapped are marshaled back, including any modifications the 4GL procedure may have made to those default values. The OpenROAD Server does not return any data as VT_EMPTY.
When a structured attribute has a VT_EMPTY value, all attributes nested below it are implicitly VT_EMPTY also. It is legal to set or get any scalar attribute that is nested below a VT_EMPTY structured attribute. If you set a nested attribute, the parent attribute then contains a nested array and is no longer empty.
VT_NULL
A structured attribute can contain the value VT_NULL, and this represents a null user class instance (or a null user class array instance). VT_NULL values for structured attributes can be sent to, and returned from, a 4GL procedure.
Note:  Although OpenROAD supports the concept of a null array row, a COM automation array cannot express this; therefore, null array rows are not supported by the OpenROAD Server interface. An entire array can be null, and any of the attributes within a row can be null, but a row itself cannot be null.
When a structured attribute has a VT_NULL value, all attributes nested below it are implicitly undefined. It is illegal to set or get any attribute that is nested below a VT_NULL structured attribute.
The SetEmpty, SetNull, IsEmpty, and IsNull methods are provided to allow client code to handle the special cases that arise with empty and null values. This is especially important for languages that cannot manipulate VT_EMPTY or VT_NULL values directly.
SetEmpty and SetNull can be used to set any value (scalar or structured) to empty or null:
HRESULT SetEmpty
    (
        [in] BSTR AttributeName
    );

HRESULT SetNull
    (
        [in] BSTR AttributeName
    );
SetEmpty can also be used to clear all data values in the PDO data tree by passing an empty string as the attribute name.
IsEmpty and IsNull let you safely test a scalar or structured value for those special cases before attempting other GetAttribute operations. The result is returned as an integer, with nonzero meaning TRUE and zero meaning FALSE:
HRESULT IsEmpty
    (
        [in] BSTR AttributeName,
        [out, retval] long * IsEmpty
    );

HRESULT IsNull
    (
        [in] BSTR AttributeName,
        [out, retval] long * IsNull
    );
SetBlankDate, IsBlankDate, SetDateWithoutTime, IsDateWithoutTime Methods
Another special case in strongly typed languages is the OpenROAD blank DATE value. This value (an empty string) appears in an attribute that would otherwise contain only valid COM DATE values. Assigning an empty string to a DATE program variable is illegal in many languages; therefore, the IsBlankDate method provides a safe way to test for this special case before attempting an assignment.
These methods are valid only on scalar attributes, and there is no enforced requirement to use these only on DATE attributes. Using SetBlankDate is semantically equivalent to using SetAttribute with an empty string value. Using IsBlankDate is semantically equivalent to using GetAttribute and then testing the result to see whether it is an empty string value. The result of IsBlankDate is an integer, with nonzero meaning TRUE and zero meaning FALSE:
HRESULT SetBlankDate
    (
        [in] BSTR AttributeName,
    );

HRESULT IsBlankDate
    (
        [in] BSTR AttributeName,
        [out, retval] long * IsBlankDate
    );
A new ParameterData method, SetDateWithoutTime, is provided for COM clients to put a date-without-time value into a ParameterData attribute. The input is still given as a COM DATE timestamp, but the method truncates any time portion and stores the date value internally using a special encoding that identifies it as a date-without-time value.
HRESULT SetDateWithoutTime
    (
        [in] BSTR AttributeName,
        [in] VARIANT * AttributeValue
    );
The COM DATE data type does not support the concept of a date-without-time value, so the ParameterData GetAttribute method can only return a timestamp. A new method, IsDateWithoutTime, provides the additional semantics regarding date-without-time values.
HRESULT IsDateWithoutTime
    (
        [in] BSTR AttributeName,
        [out, retval] long * IsDateWithoutTime
    );
LastRow Method
When a UCARRAY attribute is returned through ByRef from a 4GL procedure it may contain an unknown number of rows. The LastRow method lets you determine the number of rows in the array. This is typically used as a loop control count when iterating through the rows returned:
HRESULT LastRow
    (
        [in] BSTR AttributeName,
        [out, retval] long * RowNumber
    );
Last modified date: 12/20/2023