Release 10.1A: OpenEdge Development:
Progress Dynamics Advanced Development

> ## Accessing the manager from SDOs

> When an SDO is initialized, it requests the field edit data for its enabled tables. To define the code to support this, you can create a custom override procedure for the data class. As with other custom super procedures used to subclass an object, edit the `src/adm2/custom/datacustom.i` procedure to uncomment the line that starts the super procedure `adm2/custom/datacustom.p``.` Then create a local `src/adm2/custom/datacustom.p` procedure and edit it to add a local version of`` `initializeObject`. For example:

>     Procedure initializeObject:
>     /*-------------------------------------------------------------------------
>       Purpose:     Override of initializeObject procedure.
>       Parameters:  <none>
>       Notes:       This gets the handle of the Field Edit Manager and passes it
>                    a list of enabled tables in this SDO to cache field edits for.
>     -------------------------------------------------------------------------*/
>     DEFINE VARIABLE cEnabledTables    AS CHARACTER  NO-UNDO.
>     DEFINE VARIABLE hFieldEditManager AS HANDLE     NO-UNDO.
>       RUN SUPER.
>       hFieldEditManager = DYNAMIC-FUNCTION('getManagerHandle':U IN
>     gshSessionManager,
>                                            INPUT 'FieldEditManager':U).
>       cEnabledTables = DYNAMIC-FUNCTION('getEnabledTables':U IN
>     TARGET-PROCEDURE).
>       RUN cacheFieldEdits IN hFieldEditManager (INPUT cEnabledTables).
>     END PROCEDURE.

> The procedure first gets the handle of the new manager from the Session Manager, using the Session Manager’s global handle, `gshSessionManager`, and the logical name `FieldEditManager`. Then it gets the list of enabled tables from the SDO itself and runs the `cacheFieldEdits` procedure in the manager.

> Next, the SDO needs a procedure to do validations against the rules defined in the field edits. If any errors in the detail are detected, this `fieldEditValidate` procedure creates a message string in the format expected by the standard validation support, as shown:

>     Procedure fieldEditValidate:
>     /*-------------------------------------------------------------------------
>       Purpose:     Perform validation stored in the entity field edit table.
>       Parameters:  OUTPUT pcMessageList AS CHARACTER
>       Notes:       Invoked by SDO data logic procedure RowObjectValidate, if any
>                    errors occurs, they should be passed back to RowObjectValidate.
>     -------------------------------------------------------------------------*/
>     DEFINE OUTPUT PARAMETER pcMessageList  AS CHARACTER  NO-UNDO.
>     DEFINE VARIABLE cEditValues        AS CHARACTER  NO-UNDO.
>     DEFINE VARIABLE cEnabledTAbles     AS CHARACTER  NO-UNDO.
>     DEFINE VARIABLE cTable             AS CHARACTER  NO-UNDO.
>     DEFINE VARIABLE cValueList         AS CHARACTER  NO-UNDO.
>     DEFINE VARIABLE hColumn            AS HANDLE     NO-UNDO.
>     DEFINE VARIABLE hFieldEditManager  AS HANDLE     NO-UNDO.
>     DEFINE VARIABLE hLogicBuffer       AS HANDLE     NO-UNDO.
>     DEFINE VARIABLE iCol               AS INTEGER    NO-UNDO.
>     DEFINE VARIABLE iNumTables         AS INTEGER    NO-UNDO.
>       hFieldEditManager= DYNAMIC-FUNCTION('getManagerHandle':U IN
>     gshSessionManager,
>                                            INPUT 'FieldEditManager':U).

> After retrieving the manager handle, the procedure retrieves the `LogicBuffer` handle from the SDO. The `LogicBuffer` is in fact defined in the logic procedure of the SDO, and is the buffer for the record as it is accessed by the validation entry points in the logic procedure, such as `rowObjectValidate`, as shown:

>     RUN getLogicBuffer IN TARGET-PROCEDURE (OUTPUT hLogicBuffer).

> For each column in the buffer, the code asks the Field Edit Manager whether there is a `Required` edit type or a `Case` edit type defined for that field, by running `getFieldEditData`, as shown:

>     DO iCol = 1 TO hLogicBuffer:NUM-FIELDS:
>     hColumn = hLogicBuffer:BUFFER-FIELD(iCol)
>     cTable = DYNAMIC-FUNCTION('columnTable':U IN TARGET-PROCEDURE,
>                                   INPUT hColumn:NAME).

>         IF VALID-HANDLE(hFieldEditManager) THEN
>         DO:
>           RUN getFieldEditData IN hFieldEditManager
>             (INPUT cTable,
>              INPUT hColumn:NAME,
>              INPUT 'Required,Case':U,
>              OUTPUT cEditValues).

> Note: This is not a particularly efficient way to determine which fields are required, since it involves making a separate call to the manager for every field in the SDO’s buffer, even though most of these probably do not have a record in the temp-table cache. If you are designing a new manager, you should consider the most efficient way to get the information you need and structure the data and the calls accordingly.

> If there is a `Required` type, and its value is `Yes` (which is normally the case if it is defined at all), and the `STRING-VALUE` of the field is blank, then the code uses the framework’s `aferrortxt.i` include file to format a message using the built-in message with the key `AF1`, as shown:

>      /* Check the Required edit first. */
>           IF ENTRY(1,cEditValues,CHR(3)) = 'Yes':U AND
>               hColumn:STRING-VALUE = '':U THEN
>                 ASSIGN pcMessageList = pcMessageList +
>                   (IF NUM-ENTRIES (pcMessageList,CHR(3)) > 0 THEN CHR(3) ELSE '':U) +
>                      {aferrortxt.i 'AF' '1' cTable hColumn:NAME hColumn:LABEL}.

> If you look up this message in the Administration System menu, under Message Control, you see the display shown in Figure 7–6.

> Figure 7–6: Message Control window

> The `hColumn:LABEL` argument to `aferrortxt.i` is the value used for the substitution argument `&1` in the Error Summary Description.

> Next, the code checks the other type of edit, which specifies that a character field should be uppercase or lowercase, and makes the appropriate change, as shown:

>     /* Then check the Case edit, and adjust the value of the field if there's
>              an edit defined for it. */
>           CASE ENTRY(2,cEditValues,CHR(3)):
>               WHEN 'Upper':U THEN
>                 ASSIGN hColumn:BUFFER-VALUE = CAPS(hColumn:BUFFER-VALUE).
>               WHEN 'Lower':U THEN
>                 ASSIGN hColumn:BUFFER-VALUE = LC(hColumn:BUFFER-VALUE).
>               OTHERWISE.
>           END CASE.
>        END.  /* if valid field edit manager handle */
>       END.  /* do to number of fields in logic buffer */
>     END PROCEDURE.

Copyright © 2005 Progress Software Corporation www.progress.com Voice: (781) 280-4000 Fax: (781) 280-4095