Site hosted by Angelfire.com: Build your free website today!


PLEX WORLD

PLEX WORLD. METATASKS: Working with OBSYDIAN , Cool: Plex, Advantage Plex, AllFusion Plex, and CA Plex META CODE




 



Click here to add PLEX WORLD. METATASKS: WORKING WITH OBSYDIAN (Cool:Plex, Advantage Plex) META CODE to your list of favorites

 


This section is intended for intermediate/advanced Plex users. If you are new to metacode you would benefit from reading the following Meta Code Tutorial written by Adrian Slade (let me know if you cannot find the tutorial at this location. File is also posted at Yury Lesiuk's site).

If you have questions, don't hesitate to drop me an email. I provide on-demand remote (100% via the internet) hourly consulting for the entire Development and Project Lifecycles at the best cost in the market.

Developed by: Lucio Gayosso, MIS/M, BS, PLEX Expert (1999-2010)

 

Other resources:

  1. Set all fields on a region to the default or blank value.
  2. +For Each Field Region statement looks at all field within a given region. Metacode:

    +For Each Field Region
    _+Case
    __+When FLD null VAL
    ___++Set Value FLD null VAL
    __+When FLD empty VAL
    ___++Set Value FLD empty VAL
    __+Otherwise
    ___++Set Empty


  3. How can I obtain and output the implementation name of a Function A to a calling Function B and display within a message in a Function A?
  4. Solution: Enter the following meta-code to retrieve the implementation name in the function being called. Metacode:

    +For Each Property Target FNC impl name NME
    _+++Define Field: Impl_Name_Field
    _+++Set Value To Current Field: Impl_Name_Field
    _++Name Defined Field: Impl_Name_Field, Output < Impl_Name_Field >

    Where:
    Impl_Name_Field IS A Fields/Identifier (suggested)
    The output field Impl_Name_Field can then be retrieved in the calling function and displayed in a message.

    2b. How can I get the Impl Name for a given Function B withing a Function A:

    Set Work<Function Impl Name> = <Function Impl Name.*Blank>

    +++Define Function: MyFunctionFullyQualifiedName

    +++Define Field: FIELDS/+Name

    +For Defined Value Function: MyFunctionFullyQualifiedName

    > +For Each Property Target FNC impl name NME

    >> +++Set Value To Current Field: FIELDS/+Name

    >> ++Name Defined Field: FIELDS/+Name, Environment<*Object>

    >> Cast Work<Function Impl Name>, Environment<*Object>

    Work<Function Impl Name> contains the implementation name of "MyFunctionFullyQualifiedName"

    In addition, to develop pattern-based functionality to retrieve Impl Names of many functions follow the guidelines in the following CA's PLEX Forum thread:

    http://caforums.ca.com/ca/board/message?board.id=caplexgeneraldiscussion&message.id=896&query.id=43624#M896

  5. How can I define abstract functions that will allow functions inheriting from them to bypass some of the logic? I must be able to bypass the inherited logic to allow customized code
  6. Solution: Wrap all the logic in a meta-defined subroutine. Add Edit Points that will allow the inheriting function to bypass this code by "Undefining" the meta-variable. Metacode:

    Sub TestSubroutine
        +++Define Field: FIELDS/+Subroutine
        Edit Point Begin TestSubroutine
        +If Field: FIELDS/+Subroutine
            Add your logic here
        Edit Point End TestSubroutine
        +++Undefine Field: FIELDS/+Subroutine

    Use the "Begin TestSubroutine" Edit Point in any inheriting function to Undefine and this way, bypass this logic.

  7. How can I remove all trailing spaces for all fields in a given variable?
  8. Solution: Create the following subroutine and call it in your Action Diagram whenever you want to remove the spaces for all the fields in the requested variable:

    Sub Remove Trailing Blanks from LOCALVAR Fields
        Removes the trailing blanks from all of the character fields in the LOCALVAR local variable
        +For Each Field LOCALVAR
            +++Define Field: OBASE/Field
            +++Set Value To Current Field: OBASE/Field
            ++If Not Empty
                +For Defined Value Field: OBASE/Field
                    +If FLD type SYS, System: Character
                        ++Cast To String<Character string>
                        API Call Source code: STDRBASE/Remove trailing blanks
                        +++Define Field: OBASE/Field name
                        ++Name Defined Field: OBASE/Field name, String<Field name>
                        ++Cast From String<Returned string>
        +++Undefine Field: OBASE/Field name
        +++Undefine Field: OBASE/Field

    "STDRBASE/Remove trailing blanks" Source Code object:
    // Removes trailing (right) blanks from a character string with TrimRight function inherited from CString.
    {
    &(1:) = &(2:);
    &(1:).TrimRight();
    }

    Where:
    &(1:) = Returned string
    &(2:) = Character string

    The parameters are strings (long enough to handle fields with trailing spaces) for both input/output.

    Alternatively, a universal trim function (that trims on both sides of the strings) could be used:

    {
    &(1:).TrimLeft();
    &(1:).TrimRight();
    }


  9. How can I retrieve the Implementation Name of a Message object?
  10. Solution: The following MetaCode retieves the name of MyMessage Message object.
    +++Define Field: OBJECTS/*Message ID
    +++Define Field: OBJECTS/*Message
    +++Define Message: MyMessage
    +++Set Value Field: OBJECTS/*Message, Message: MyMessage
    +For Defined Value Field: OBJECTS/*Message
        +For Each Property MSG impl name NME
            +++Set Value To Current Field: OBJECTS/*Message ID, .Target
            ++Name Defined Field: OBJECTS/*Message ID, Environment<*Message ID>

  11. How can I meta-call one of many functions based on an input parameter on a calling function A without having to define a case statement to add "real" call statements for all possible calls. (CooL Plex 4.5- Win/ODBC Generator)
  12. Solution: Define all the functons that can possibly be called by Function A by adding "Function A Calls FNC" triples.

    On the Action Digram add the following Meta Code:

    Seq Meta Code
        +++Define Field: FIELDS/Function
        +For Each Property FNC calls FNC
            +++Set Value To Current Field: FIELDS/Function, .Target
            ++Name Defined Field: FIELDS/Function, Local<USR Web Calling Function>
            If Local<USR Web Calling Function> == WebInput<USR Web Calling Function>
                ++Call Field: FIELDS/Function, MetaParameters
                Terminate

    The field WebInput(FIELDS/Function) defines an input parameter (this example considers the variable WebInput for a Cool:Plex/Websydian implementation) that will state what function will be finally called.

  13. How can I get the Implementation Name of an Attribute arising from a ENT refers to ENT ...for QLF? (Cool: Plex 4.5) (For example:
    CUSTOMER refers to ADDRESS
    ...for BILLING. Need the Imp Name for attribute: 'BILLING | ADDRESS ID')
  14. Solution: Use the following meta-code. Name retrieved will be stored in Work.
    +For Each View
        +For Each Entity Relation
            +For Each Attribute
                +++Set Value To Current Field: FIELDS/+Field
                +For Defined Value Field: FIELDS/+Field
                    +If ATR impl name NME
                        ++Set Value Field: FIELDS/+Name, FLD impl name NME
                        ++Name Defined Field: FIELDS/+Name, Work<AttributeName>

  15. How can I get the Variant (language) of a function?
  16. +++Define Field: FIELDS/+Function
    +++Set Value To Current Field: FIELDS/+Function
    +For Defined Value Field: FIELDS/+Function
        +If FNC language SYS, System: RPG400
            Call Function1
        +If FNC language SYS, System: WinNTC
            Call Function2

    Note: It is a good idea to encapsulate all metacode in a SEQ contruct. For example:

      Seq FunctionOptions
        +++Define Field: FIELDS/+Function
        +++Set Value To Current Field: FIELDS/+Function
        +For Defined Value Field: FIELDS/+Function
            +If FNC language SYS, System: RPG400
                +++Define Field: FIELDS/+RPG400
            +If FNC language SYS, System: WinC
                +++Define Field: FIELDS/+WinC
            +If FNC language SYS, System: WinNTC
                +++Define Field: OBASE/+WinNTC
            +If FNC language SYS, System: Java
                +++Define Field: FIELDS/+JAVA
            +If FNC language SYS, System: Oracle
                +++Define Field: FIELDS/+Oracle
            +If FNC language SYS, System: OracleWinNT
                +++Define Field: FIELDS/+Oracle

  17. How can I generate a list of the local entities in a Model (excluding referenced -library-, scoped, and implicit entities?)
  18. +++Define Field: Current entity

    +For Each Object Entity //Loops around all the entities in the model

    +If Query Object Library
    // Exclude library objects
    +Else

    +If Query Object Scope
    // Exclude scoped entities
    +Else

    +If Query Object Real // Only include real entities
    +++Set Value To Current Field: Current Entity
    ++Name Defined Field: Current Entity, Report<Object Name>
    Print Report
    ++Undefine Field: Current Entity

  19. How can I determine the Objects that are not scoped in the model?
  20. +++Define Field: FIELDS/+Name
    +++Define Name: OBJECTS/+Meta
    +For Each Object Name
    // Check every NAME Object in the Model

    +If Query Object Library
    // Do nothing if the NAME Object Belongs to a library
    +Else

    +++Set Value To Current Field: FIELDS/+Name
    +++Define Field: +Include
    +For Each Object Function

    +If Query Object Library
    // Do nothing if the Function Object Belongs to a library
    +Else

    +For Each Property Target FNC impl name NME

    +++Set Value To Current Name: OBJECTS/+Meta
    +If EQ Name: OBJECTS/+Meta, Field: FIELDS/+Name

    +++Undefine Field: +Include
    // Don't include if NAME is target of a FNC impl name NME triple

    +For Each Property Target FNC file name NME

    +++Set Value To Current Name: OBJECTS/+Meta
    +If EQ Name: OBJECTS/+Meta, Field: FIELDS/+Name

    +++Undefine Field: +Include
    // Don't include if NAME is target of a FNC file name NME triple

    +For Each Property Target FNC name NME

    +++Set Value To Current Name: OBJECTS/+Meta
    +If EQ Name: OBJECTS/+Meta, Field: FIELDS/+Name

    +++Undefine Field: +Include
    // Don't include if NAME is target of a FNC name NME triple

    +If Field: +Include

    +For Each Object Field

    +If Query Object Library
    // Do nothing if the Field Object Belongs to a library
    +Else

    +For Each Property Target FLD impl name NME

    +++Set Value To Current Name: OBJECTS/+Meta
    +If EQ Name: OBJECTS/+Meta, Field: FIELDS/+Name

    +++Undefine Field: +Include
    // Don't include if NAME is target of a FLD impl name NME triple

    +For Each Property Target FLD special type NME

    +++Set Value To Current Name: OBJECTS/+Meta
    +If EQ Name: OBJECTS/+Meta, Field: FIELDS/+Name

    +++Undefine Field: +Include
    // Don't include if NAME is target of a FLD special type NME

     

    +If Field: +Include
    ++Name Defined Field: FIELDS/+Name, Environment<*Object>
    Print Report
    // The Name has not been found as the target of any triple, issue a report

    Notes:

  21. How can I get the Implementation Name for an entity's Table?
  22. +++Define Field: FIELDS/+Name
    +++Define Field: FIELDS/+Entity
    +++Define View: YourEntity.Update
    +For Defined Value View: YourEntity.Update
        +++Set Value Field: FIELDS/+Entity, Query Object Scope
        +For Defined Value Field: FIELDS/+Entity
            +For Each Property Target ENT table TBL
                +For Each Property Target TBL impl name NME
                    +++Set Value To Current Field: FIELDS/+Name
                    ++Name Defined Field: FIELDS/+Name, Work<TableName>

     

  23. How can I set all fields in a variable, that do not contain a value (are blank), to a given value (in this case ALL BLANKS)?
  24. Set Work<AllBlanksField> = <AllBlanksField.BLANKS>

    // This field contains a string with the maximum length of the longest field in the variable and is defaulted to all blanks

    +For Each Field VariableName
        +++Define Field: OBASE/Field
        +++Set Value To Current Field: OBASE/Field
        ++If Empty
            +If FLD type SYS, System: Character
                ++Cast From Work<AllBlanksField>

    Additionally, for this task it was required to fill will trailing blanks all fields that did have a value to meet a fixed-length field format. The code was enhanced to fill with trailing BLANKS in the following manner:

    +For Each Field VariableName
        +++Define Field: OBASE/Field
        +++Set Value To Current Field: OBASE/Field
        ++If Empty
            +If FLD type SYS, System: Character
                ++Cast From Work<AllBlanksField>
        ++Else
            Fill out with trailing blanks all fields that were assigned a value
            ++Cast To Work<Character string>
            Set Work<2nd string | Character string> = <Character string.BLANKS>
            Format Message Message: Concatenate 2 strings, Work<Character string>
            ++Cast From Work<Character string>

    A vital component of the previous metacode is the ++Cast From statement that generates a Cast statement from a specified field, or the field returned by a meta-query, to the current field. Full syntax:

    The current field is assigned the value of the specified field.
  1. How can I convert all fields in a variable to uppercase? (Plex 4.5, WinC client)

Solution: Create a subroutine in your Action Diagram that contains the following metacode:

Sub Capitalize all FieldsInVariableName

+For Each Field VariableName
    +++Define Field: OBASE/Field
    +++Set Value To Current Field: OBASE/Field
    ++If Not Empty
        +If FLD type SYS, System: Character
            ++Cast To Work<VaryCharacter>
            API Call Source code: WINAPI/MakeAllUpper
            ++Cast From Work<VaryCharacter>

The metacode looks for all character field in variable VariableName to then cast them to a work VaryCharacter field that is then used by the MakeAllUpper Souce Code to be capitalized. After capitalization values cast back to their original field.

  1. How can I assign all the fields in a variable (that containing multiple field types) to a given value only for the fields inheriting from a common ancestor?
  2. Solution: In the following example all fields within variable FirstParty that inherit from a common ancestor (Amount) are initialized to empty value (zero, as the ancestor is numeric)

    +++Define Field: CTABLES/(Amount)
    +++Define Field: FIELDS/Current
    +For Each Field FirstParty
        ++If Not Empty
            +For Each Property Target FLD is a FLD
                +++Set Value To Current Field: FIELDS/Current
                +If EQ Field: FIELDS/Current, Field: CTABLES/(Amount)
                    ++Set Empty
    +++Undefine Field: CTABLES/(Amount)
    +++Undefine Field: FIELDS/Current

    The meta-loop checks each current field's FLD is a FLD triple and gets the name of the target field. If such value is (Amount) -Current field IS A FLD (Amount)- then the field is set to empty value.

  1. How can I assign all fields to their default BLANK or EMPTY value to avoid NULLS? This is necessary to avoid inserting fiels with value <NULL> in a SQL Server DB which causes processing errors.
  2. Solution: The following Remove Nulls sequence loops through all fields in the VariableName variable and assigned the default valid EMPTY or NULL value or seeting to EMPTY to avoid the <NULL>


    +For Each Field VariableName
         ++If Empty
               +Case
                     +When FLD null VAL
                            ++Set Value FLD null VAL
                     +When FLD empty VAL
                           ++Set Value FLD empty VAL
                     +Otherwise
                           ++Set Empty

  1. How can I validate all date fields in a variable are proper ISO values and set them to valid BLANK value if they are not?

    Solution: Create the following subroutine:

    Sub Validate Dates are ISO

     +For Each Field FetchedData

        +++Define Field: OBASE/Field

        +++Set Value To Current Field: OBASE/Field

        +For Defined Value Field: OBASE/Field

          +If FLD type SYS, System: Date

          ++Cast To Work<Ref ISO Date>

          // Input<DateISO> Work<Ref ISO Date>

          Call DATE/ValidateDateISO

          If Environment<*Returned status> != <*Returned status.*Successful>

            Comment Invalid ISO Date. Set to BLANK

            Set Work<Ref ISO Date> = <Ref ISO Date.*Blank>

          Else

            Comment Valid date. Continue processing it

          +++Define Field: OBASE/Field name

          ++Name Defined Field: OBASE/Field name, Work<Field name>

          ++Cast From Work<Ref ISO Date>

        +++Undefine Field: OBASE/Field name

        +++Undefine Field: OBASE/Field

  1. How can I define an abstract event that will automatically capture the field name of a control that is updated to then trigger an event with its contents, such as calling a validation function or a fetch function to get associated virtuals?
  2. You can create explicit logic to get the field's value on the panel (i.e. Get DetailP<Field>) and when the Updated event occurs (i.e. user has entered the value then left the edit box) then trigger the associated process. The problem with this approach is that you have to specify this logic for each field on the pane that would trigger logic in this way.

    Another 'abstract' approach is through the use of metalogic associated to the Gained Focus event, to determine what field is currently being updated, and the Updated Event, to trigger the processing with the value just entered after the user leaves the Edit Box.

    On the Panel Edit, associate both the Gained Focus and Updated Events to the Edit Box of each control that will process similar logic then define the following events (logic obtained from Plex's FOUNDATION Pattern Library Help|Abstract Event Handling and the common processing defined in the Updated Event is for retrieving Virtual fields associated to the ID/Key entered by the user)

    Edit Point Additional events
     Event Event: Gained Focus
      +For Each Field Details

       ++If Focus
       +++Define Field: focus field // focus field is a varying length char field
       +++Set Value To Current Field: focus field
       ++Name Defined Field: focus field, Local.focus field>, .Scoped //Current field getting focus is assigned to work field
     Event Event: Updated
      +For Each View Details
       +For Each Entity Relation
        +++Undefine Field: Virtuals Exist
        +For Each Attribute
         +If Query View Virtual
          +++Define Field: Virtuals Exist // At least one virtual is on the panel

        +If Field: Virtuals Exist
         Set Local.Full key specified> = .Full key specified.*True>
         +For Each Attribute
          +If Query View Foreign Key
           ++If Empty
            Set Local.Full key specified> = .Full key specified.*False>
         If Local.Full key specified> == .Full key specified.*True>
          ++Call ENT checked by FNC, .Target
          If Environment.*Returned status> == .*Returned status.*Error>
           // Blank out virtuals if no record found
           +For Each Attribute
            +If Query View Virtual
             ++Set Empty
          Put Details

  1. How can I extract a fields' Value (the Label of the value) and Literal to use in a function? I need to be able to get the get the Label, i.e. *Sucessfull if the field is the *Returned Status instead of the literal ' ', to then process it.
  2. 1) Create a field 'ValueLabelConversion' which will scope a new function 'ConvertValueToLabel'

    2) Scoped function can be either internal/external, client/server.

    3) Add the scoping field as an Input parameter, and another field like *Object or appropriate as a Dual Parameter. This field will hold the returned string (the Value Label)

    4) Add the scoping field as a Local field to the function, and also, if you did not use *Object, the field you used as a Dual.

    5) Define the following Metalogic. Also create the fields +Label and +Value or use another appropriate field as these are used to hold the meta-variables

    +++Define Field:+Label

    +++Define Field:+Value

    +++Define Field:ValueLabelConversion

    +For Defined Value Field:ValueLabelConversion

    +For Each Property Target FLD value Val

    +++Set Value To Current Field: +Value

    ++Text Defined Field: +Value, Environment<*Object> // The field may not be character so use *object and then cast

    Cast Local<ValueLabelConversion>, Environment<*Object>

    If Input<ValueLabelConversion> == Local<ValueLabelConversion>

    +If Val label LBL

    +For Each Property Target VAL label LBL

    +++Set Value To Current Field: +Label

    ++Text Defined Field: +Label, Input<*Object>,.Text

    +Else

    ++Name Defined Field +Value, Input<*Object>, .Language

    Go Sub Terminate

    Whenever this functionality for a field is required make MyField IS A ValueLabelConversion with continuation triple ... LIMIT SYS ALL and call the function for the field to convert its value to its label, or the name of the value. More details at:

    http://caforums.ca.com/ca/board/message?board.id=caplexgeneraldiscussion&thread.id=1210

Do you have any problem/solution you would like to share? Send me an e-mail and I'll get it posted.
If you found any information interesting or useful please mention it on the Guestbook on the main page of Plex world.
If you could contribute to keep this site free, personal checks or paypal payment are gladly accepted (no matter how small the contribution)

Developed by: Lucio Gayosso, MIS/M (1999-2010)



 
 


You are visitor

Email: l_gayosso@hotmail.com



Home



Background music: Tangerine Dream's "Sun Gate" (same album's name)

Use the controls to Stop, Start, Play the music

 
Listen to: R@DIO DIMENSION and let your mind fly...
Escucha: R@DIO DIMENSION y deja a tu mente volar...