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


PLEX WORLD

OBSYFAQ: OBSYDIAN, Cool: Plex, Advantage Plex, AllFusion Plex, CA Plex, and related tecnologies FAQ, tips and techniques.




 


Click here to add PLEX WORLD. OBSYFAQ (OBSYDIAN-PLEX FREQUENTLY ASKED QUESTIONS) to your list of favorites

 

The intended audience for this document is OBSYDIAN (Cool:Plex) developers which have covered the introductory documentation on the tool at least (OBSYDIAN Getting Started/tutorial). Items, terms, and words in italics are concepts that can be found in Windows/OBSYDIAN (Cool:Plex) documentation

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)

  1. Working with a Local Model (saving or updating a Group Model) takes a considerable amount of time (more than working locally).
I had the same problem when I used to update a Group Model from a Local in the network. Any remote action will take a considerable amount of time (compared to work in the local hard drive) just because all the checking involved and the number of calls that go back and forth in the network. I recommend saving to the local hard drive and then move the MDL file to the network.
  1. Using an unscoped Source Code Object that accesses a database table doesn’t work.
To execute SQL statements for a specific table you need to scope the Source Code object to a view. I did this with OBSYDIAN 3.0 and the simple fact of scoping enabled the access to the database. An alternative is the use of the uses VIEW triple to specify what view will provide the DB access.
  1. Setting the DEFAULT VAL and the …APPLY SYS continuation triple to EARLY for an entity’s field doesn’t initialize the default value on the panel entry.

This was encountered with OBSYDIAN 3.1. Apart from the steps above mentioned it is also necessary to add a “TBL defaults SYS Procedural” triple to the table as this property defaults to “Database”

Additional notes from Plex' help

FLD default VAL ...apply SYS

Nominates one of a field's values as its default. The default value is used for fields which are displayed on panels and reports or updated to the database.

The TBL defaults SYS verb controls how the default value processing is implemented.

You can use the ...apply SYS continuation verb to specify more information about when the default value should be applied. The precise effect of this continuation verb depends on your class library. The allowed system values are:

Early

The field is initialized with its default value when it is first displayed on the screen (unless a value already exists).

Late

When a row is created in a table and no value has been specified for the field, the default value is applied at the time the row is created.

  1. Changing the order of Menu Groups on the panels does not get saved. The Panel Editor displays the changes correctly but after closing (and saving), if the object is generated (or opened with the editor) the changes are lost
Known bug until V3.1 (I do not know if this is fixed in subsequent versions). Move ALL Menu items and buttons around (on the panel) so that they all turn blue (way OBSYDIAN indicates their position has been modified), then place them in the desired position. This time when the Panel is saved the changes will remain. Update. Similar problem in Cool: Plex 4.5. The problem was seen again in this version of Plex. A work around I found would be to move each Menu Group to the Menu Bar Region, one at the time and in the order they should be appear from left to right on the Menu Bar.
  1. Menu Items disappear if moved to new Menu Groups in application's new version.
This problem occurs up to OBSYDIAN 3.1 and Sterling's Support Team does not know yet if it is solved in subsequent versions. This conflict is due to having some elements Version/Level dependent and some not. The Menu Groups (the items containers) are Version/Level dependent and they obey the regular inheritance rules, that is, if we define Menu A and Menu B in the application's BASE level these two Groups will show up in all versions above. If now we create Menu C in application's V1, this Group will display for all versions above but not below (in this case BASE)

Menu Items ARE NOT Version/Level dependent though. If an item (Item 1) is created in BASE and then moved to Menu C in V1 the item "disappears" in all versions, including the ones below (BASE in this case) and just shows up in the Group (and Version/Level) where it was placed .

Note:    We had to create new Menu Groups in new Versions of the application to create custom Panels for different users where the same Menu Items would show up in different locations (Menu Groups) according to the logic of how the information was presented for different users. With the limitation of not having Menu Items Version/Level dependent we had to take the following work-around to preserve all Menu Groups/Menu Items configuration for previous Versions/Levels and include the new features:

If we had to present "Menu Item 1" in Menu A for Version 1 (V1) and then on Menu C for V2 we would place "Menu Item 1" on Menu A in V1 then set the Exist and Visible properties to NO for it on V2 where a "Menu Item 2" was created and attached to the same Event on the Panel Designer. "Menu Item 2" was basically a replica of "Menu Item 1".

  1. Functions scoped to Views that sort on Dates in Descending Order do not retrieve all records.
It is necessary to set the highest value to the Date fields to start fetching records from that point. This is accomplished by adding the "high VAL" and "value VAL" triples to the Date fields and setting the Literal Value to the highest date used in the system (i.e. 2100-12-31). In addition, this values must also be set in the Action Diagram as in the following example:

If  Positioner<Date Field> == <Date Field.Null>
    Set  Positioner<Date Field> = <Date Field.highest date>

Note: If a Wrapper function is used (to allow multple sort options), each of the individual get sequential functions called will also need this code.

Update on this issue (10/31/03): In the new versions of Plex's patterns (Plex 4.5 and above) a BLANK/NULL value for the Positioner values for Dates is correctly mapped to the HIGH value on the dates fields as long as the "high VAL" and "value VAL" triples are added to such fields (for AS400 Implementations no aditional triple/setting is required). For SQL Implementations the appropriate high values to use might have to be specified on the INI file (for further details check this EDGE thread: "ProcessGroup with Restrictor and Position")

  1. How can a panel that invoques another one (where a process has ben executed) be updated automatically, without closing the second panel and refreshing the first one to reload?
Use the "NAME" Action Diagram Command to retrieve the name of the function to update:
Name  Function: ENTITY.FUNCTION_TO_UPDATE, Work<Function>, .Scoped

Then make an API Call to the the "OBWIN/Trigger Event" Source Code Object to perform the desired task. In this case you will have to pass the value of the operation to perform (Update Grid):
API Call  Source code: OBWIN/Trigger event

where the mapping would be :
 

<Function>
Work<Function>
<Logical Event>
<Event Name.Update Grid>
<Event Status>
Work<Event Status>



Notes:

  1. How can I Move (or Copy) a block of Action Diagram's statements and Construct from one Function to another one in a different Version/Level without manually reentering all the code?
You can Copy  (or Cut) all the block of code to any Text Editor like Wordpad. The statements and constructs will be inserted with control characters together with the specification for the mapping of all calls as in the following example:

ª+1 Comment  Lucio Gayosso. 09/29/99. Example of how to Cpoy blocks of Code from a Function to another one in a different Version/Level
 |1 Input
 |2 15 51002c55 Field: CSBASE/RPS Company Code
 |3 Grade Master.All attributes.Get one instance/Output
 |4 15 51002c55 Field: CSBASE/RPS Company Code
 |5 10 57000744 Function: Company Setup.All attributes.Get one instance
 // Input<RPS Company Code> Grade Master.All attributes.Get one instance/Output<RPS Company Code>
ª+1 Call  Company Setup.All attributes.Get one instance
ª+1 Substring  GL Account Nbr Setup<GL Acct Nbr Prefix Co>, GL Account Nbr Setup<RPS S2K Company Number>, GL Account Nbr Setup<GL Acct Nbr Prefix Lenght>, GL Account Nbr Setup<GL Acct Nbr Prefix Position>
ª+1 Substring  GL Account Nbr Setup<GL Acct Nbr Prefix Cost Center>, GL Account Nbr Setup<RPS S2K Company Number>, GL Account Nbr Setup<GL Acct Nbr Prefix Lenght>, GL Account Nbr Setup<GL Acct Nbr Prefix Position>
 |1 <none>
 |2 15 ffffffed Field: GL Acct Nbr Prefix Co
 |3 GL Account Nbr Setup
 |4 15 ffffffed Field: GL Acct Nbr Prefix Co
 |5 0 0 <none>
 // <GL Acct Nbr Prefix Co> GL Account Nbr Setup<GL Acct Nbr Prefix Co>
 |1 <none>
 |2 15 ffffffea Field: GL Acct Nbr Prefix Cost Center
 |3 GL Account Nbr Setup
 |4 15 ffffffea Field: GL Acct Nbr Prefix Cost Center
 |5 0 0 <none>
 // <GL Acct Nbr Prefix Cost Center> GL Account Nbr Setup<GL Acct Nbr Prefix Cost Center>
ª+1 Format Message  Message: Grades Received.List attributes.Process Some Instances - Payment.Format GL Acct Nbr Prefix, GL Account Nbr Setup<GL Acct Nbr Prefix>
ª+1 Comment  set "GLA S2KGL Account Number" with Prefix and GLA S2KGL Account Number from Purchase Materials to create Items Received
ª+1 Set  Work<GLA S2KGL Account Number> = GL Account Nbr Setup<GL Acct Nbr Prefix> CONCAT Purchase Materials.All attributes.Get one instance/Output<GLA S2KGL Account Number>
@@

Now you can change your  Local Model to the target Configuration (Version/Level). Open the Function where you want to insert the code and Copy all of it from the Text Editor (insert it directly on the AD code not in the Entry Line). OBSYDIAN will format the text to create the corresponding statements/constructs and will validate them.

  1. Cascade deletion for a child does not work even after specifying the destructor function and dependency on the entity (destructor FNC and dependency SYS Delete triples)
Some databases do not handle the "ON CASCADE DELETE" process as it is not part of the ODBC 2.0 standard (i.e. IBM DB2 Universal Database V5.0) so that if the entity's table dependencies is set to DATABASE no deletion is accomplished. It is then needed  a Procedural  value for the dependencies SYS triple to force the generator to call the destructor function.
Note: If this is done after the entity has been generated then it will be necessary to recreate the table (make sure you backup the existing data if any! You will need this to import later), views that reference it and the parent(s) function(s) that perform the cascade deletion.
  1. How can I trigger an alternate prompt on a referenced field and, depending on the results from this prompting process, I execute or not the regular one?
Including a reference to an entity creates the "Prompt processing" metafunction for all Foreign Keys (Key fields  in the referenced entity) that provides the ability to prompt their values, that is, if at run-time F4 is pressed in the field (or double clicked) the list of values on the referenced table is displayed. You can condition the process to create an alternate prompt and decide (based on the results of the new prompt) whether you still want the regular prompt or not. This is accomplished by creating a new event on the Panel Editor (i.e. ALTERNATE PROMPT) and mapping the field's EDIT double click physical event to the new event. On the Action Diagram add:

Event  Event: ALTERNATE PROMPT
Get  Details<Prompted Field>
    ***
    Process for alternate prompt
    Set Details<Prompted Field> = Result from Process for alternate prompt
    Put Details<Prompted Field>
    ***
    If Details<Prompted Field> =! Valid result (i.e. equals "blank" or "zero")
       Go Sub  Prompt event (subroutine that includes metacode for executing regular prompt)

  1. Error "class/struct/union type"
This type of error usually ocurrs while working with objects from non-local objects, that is, with objects pertaining to referenced class libraries.For example, the following error ocurred while assigning the output from an inherited call to OBASE/Set current date and time date value to an input field in a function being called in a local AD.

Creating command line "link.exe @C:\TEMP\RSPE5.tmp"
Compiling...
RP2msF.CPP
C:\recpaper_v30\GEN\ODSOURCE\RP2msF.CPP(1240) : error C2039: 'ObOut_OB00001F' : is not a member of ObDat_RP2msF'
C:\recpaper_v30\GEN\ODSOURCE\RP2msF.CPP(1240) : error C2228: left of '.Set_current_date_and12' must have class/struct/union type
C:\recpaper_v30\GEN\ODSOURCE\RP2msF.CPP(1240) : error C2228: left of '.Panel_date17' must have class/struct/union type
Error executing cl.exe.

Function RP2msf retrieves the panel date from the output of inherited call to OBASE/OB00001F.

There are two possible solutions:
1) Make a local call to this object (OBASE/Set current date and time) and then the output filelds are available
2)Assign the otput from the inherited obkject to a local work field and then use this for the mapping.

Note: Error "class/struct/union type" also found during compilation of a WinNT Server function (Plex 4.5) that wrapped a single statement to execute a SQL Statement.

(C:\old_F_drive\obbuild\patbuild46\patdevlg\JEcidF.CPP(97) : error C2228: left of '.GetWrapper' must have class/struct/union type)

In this case problem was resolved by adding a USES VIEW (with any view as the target) to the server function.

  1. After Generation/Build, only the user's ID used in Compile process has access to the application.
Problem found in an NT 4.0 server with IBM's DB2 V5.0. Problem due to not having a Database Objects Owner. Solution: In the Gen and Build options, System Definitions, WinNT System Properties, ODBC Build, enter a valid User ID in the Database Objects Owner field. Re-generate all objects.
  1. Function is generated and compiled (Select Instance User Interface) with no warnings or errors. When called, received message "Duplicate MDI frames detected" and function does not execute.
Solution: A function's panel in the inheritance path had the windows property = MDI. Set this to MDI Child.
  1. Size of panel (for Select Instance User Interface function) does not display correctly, eventhough panel editor looks fine and all functions in inheritance path seem to be fine.
Recent inheritance change had modified the window type on one of the ancestors. Even after all editors reflected the correct inheritance the application ini file entry for this particular panel had to be modified.
Solution: Locate and delete the following entry on the application ini file (it will be recreated next time the function is called)
[FunctionImplementationName::Grid Settings]
Column Map=0,2; 1,57; 2,55; 3,58; 4,161; 5,69; 6,73; 7,56; 8,84; 9,96; 10,92; 11,104; 12,84; 13,120;
  1. How can I disable the inherited log message that pops up after field validation fails on panels (relation failed validation)?
Solution: As this code is inherited it is not modifiable (no Edit Points for 'Validate Instance' subroutine). It is necessary to use another Edit Point right after the call to OBASE/Field Validation function ('Edit Point 0 Post field validation' can be used). You can use the WINAPI/ShowMessageLog Source Code object to manipulate the log message window. It inputs a 'PanelState' field that specifies the action to take (show, hide, minimize, restore, etc).
  1. How can I use crystal reports' OCX control (crystl32.ocx) to allow my OBSYDIAN applications to launch (and pass parameters to the reports)?
1) Register the OCX control in you system (command: regsvr32 crystl32.ocx)
2) Add the OCX control to the panel of the function that will be launching your report (on the Panel Designer, right mouse click on it, select 'Create Active X Control' and choose 'Crystal Report Control')
3) On the Properties Palette double click on 'Custom Properties' and enter all necessary information on all seven tabs (information is required on 'General' (Report File Name) and 'Database' (Connect: UID=DatabaseUser;PWD=DatabasePassword;DSN=;) tabs. The report can operate with most of the default in the other tabs.
4) Hide the OCX control by setting the 'Visible' property = No
5) In the Action Diagram: Use the API Call Source code: 'OBWIN/Set ActiveX character property' and 'Set ActiveX character property' to set the properties required to launch the report/pass any required parameters to filter by (i.e. Report Title, Selection Formula,Destination, Action).
  1. On the Panel Editor, how can I organize Menu Items by creating new ones and putting the existing ones in to create sub-menus? (dragging the existing items simply re-sorts them -they are positioned before or after- but are not put 'inside' the new Menu Items)
Solution: The Panel Designer interprets the drag and drop action as a resequencing operation if this occurs within the same elements of the same Menu Item. To accomplish inserting Menu Items to Menu Items in the same group the elements must be moved out of the Menu Item where they are contained and then back into the one that will contain them.
  1. When working with the Panel Designer, if Menu Items are moved and located in a different position, the results are not always reflected correctly after generation/execution.
Solution: At times changes in the Menu entries structure are saved but not reflected in the generated code. In these cases you can move the Menu Items to an intermediate position, save the changes, re-open the Panel Editor and change the order once more to obtain the desired results.
  1. Menu Item does not get executed although Panel Editor displays correct Menu structure and aLogical Event is correctly associated.
Solution: After checking what Physical Event was associated with the Logical event (Panel Editor, Events) found out inheritance defined an additional Physical Event under this association that, despite of belonging to a hidden Menu Item not implemented on the current Panel, was previous to the Physical Event that was expected to trigger action. Deleted Menu Item not used on Parent Menu. Re-generated function.
  1. I have a Panel A that has an 'ancestor' Panel B ('implicitly' inherited, no use of a IS A PNL triple) with Menu Items I do not plan to use. If I define a new Panel C with the desired Menu Groups and Menu Items and define Panel A IS A Panel C, why does it still show the Menu Items from Panel B?
Solution: If a panel is subject to both 'explicit' and 'implicit' inheritance, the explicitly inherited properties take precedence (in this example the ones coming from Panel A IS A Panel C); but if the inherited elements from different inheritances can be stored separately, the properties are merged. In this case the Menu Item Panel Elements from C DO NOT OVERRIDE the ones from Panel B thus, both Menu Items are displayed on Panel A. A solution would be to set the VISIBLE Property for the unwanted Menu Items = NO.
  1. How can I selectively choose the implicit inheritance for a panel? An "Edit Grid User Interface" function inherits from two different layers (implicit inheritance) A and B where layer B inherits/specializes A . The scoped panel at the new level C thus inherits the properties of both layers but only the properties for A are required (but the Menu Items and Events from B are inherited), The approach to hide/disable inherited level B's elements was not considered because several entities have been defined this way (and the rest of the Grid User Intefaces at level C DO require the properties from both A and B levels).
Solution: Implicit inheritance can not be chosen selectively. An additional "Edit Grid User Interface 2" had to be created at level B, inheriting from previous level A (Level B entity.Grid maintenance Suite.Edit Grid Interface 2 IS A Level A entity.Grid maintenance suite.Edit grid user interface) and replacing all views and server functions from level A by the ones from level B. As all new Grid UIs from level C will inherit this additional function, the triple IMP SYS = No (and changed to YES on entities where elements fom level A only are required).
  1. How can I handle Client Internal functions so that I keep control of all of them and allow their generation to be used by all developers? This is specially required for massive generation/build of a new application's release or OBSYDIAN update.
Solution: Create a PKG object (or SBJ -Subject Area-) that references all of the internal functions in the model. Then, when a full new release of the application (or Plex itself) is required, rebuild all of those functions to get a new LIB file. This LIB file can be renamed (i.e. INTERNAL.LIB) and then put in the network so that all developers can reference it (set it up in the in the Build | Generate and Build Options | System Definitions | Pre-Built C++ Libraries).
  1. I have a function that has a lot of calls FNC triples for functions that are never called. This function also contains many valid calls to other functions. What is the fastest way to identify the triples for non-existing calls to delete them? (to avoid receiving all the "Call statement not found.." warning messages).
Solution: Open the Model Editor for the function and delete all the calls FNC triples. Open/close the Action Diagram for the function (this will re-create the triples for all the valid calls).
  1. We use several pre-built C++ libraries and only some of them seem to be used (we checked that file name and path are correct in Generate and Build Options).
Solution: There is a limit to the number of characters the Libraries entry can store (more entries can be made but they will be discarded during compilation). One viable soluton is to install the lib files in a directory right under your system unit (i.e. c:\lib or C:\Plex\lib). This will save several characters in the libraries entry as the path will be shorter for each individual lib file or map a network drive so that the length of the entire path is reduced. You can also map a network drive so that the length of the entire path is reduced or map a network drive so that the length of the entire path is reduced
  1. A table with several dependencies had to be re-defined (table changed). Now to re-create it, all its dependencies (all views that are based or refer to this table) have to be deleted first (Cool:Plex returnes message "CPF3219 Cannot delete file or member of file FILENAME in LIBRARYNAME"). What is the fastest way to get a list of all dependencies to delete them? (Cool Plex 4.5 - Windows/AS 400 generator).

Solution: It is posible to do a "usage" with the model editor 'scoped' to the entity (View|Usage) and then, for all dependencies (all targets of 'referenced by' or 'owns' triples), locate the views that have to be manually deleted in the AS/400. This approach is rather slow but is based completely on Model Analysis. Another approach (faster) is to use the 'Display Data Base Relations' command in the AS/400: At the command line enter: DSPDBR FILE(LibraryName/TableImplName. This will provide a list of all the dependencies that need to be deleted to allow table's compilation.

Note: To delete go to the command line in the AS/400 and enter: STRPDM, select option 2 (Work with Objects), select the dependencies and use option 4 (delete).

If all dependent views for a table are identified in the Local Model and all objects are selected (table and dependencies), compilation from the Local Model can take place (Plex attemps successfully to delete all dependencies, then the table, then submits the table and finally the dependencies)

  1. Compilation fails for a server function (Delete valid instance). No additional information can be retrieved from Cool:Plex generation messages (no errors or warnings) and the 'Real Attributes' view to which the function is scoped to, generates fine (Cool:plex 4.5 - Windows/AS400 generator).
Solution: After checking spooled file found messages (severity 30) "External name specified for Rename option is not valid.Option ignored". Some of the views for references this entity makes were modified/generated in a different library (they were initially created in the correct library). Set up correct Build Directory, regenerated/recompiled related views, recreated 'Delete valid instance' and its view. Compilation completed successfully.
Note: To check for compilation messages on the server run in the AS/400 command line: wrksplf, locate the file for your submited job, select option 5 (Display), control: B (Bottom) will show show a list of the compilation messages and their severity.
  1. Entitiy A is a 'Referenced Entity' which includes several dependencies. ...Dependency SYS ERROR triples have been added to all dependencies. Generation of 'Entity A.Real attributes.Delete valid instance" goes well but compilation fails. No messages are provided by Cool:Plex (Plex 4.5. Windows/AS/400 generator)
Solution: One of the dependencies view for a destructor function had failed compilation. To get details on what is missing for successful 'Delete valid instance' compilation checked 'spooled file' for this function on the AS/400 (command:wrksplf, at the bottom of the source code error messages are displayed. Errors related to missing views are described as 'External description not found for file specified as externally described').
Tip: In the AS/400 'Displayed Spooled File' screen the error code can be used in conjunction with the Find_____ control to look for the lines where the error occured. Enter the last 4 digits of the error code and press the F16 key (SHFT + F4 in a 12-function key keyboard).
  1. A dependency is not enforced in the server even after adding a ...dependency SYS Error triple.
    Entity A refers to B
    ...optionality mandatory
    ...dependency SYS Error
Solution: The destructor function had not been specified (by using the continuation triple: ... destructor FNC).
  1. How can I modify database columns (implementation names,lenght of fields, type) and preserve the data? (Windows-AS/400 generator)
Solution: Five steps are required:

Example:

The following SQL Script that does the following

1) Creates a BACKUP version of the current files that will be modified (PJ_jeTicketEntry and PJ_jeTicketEntryHistory)

2) Copies all data from current files to BACKUP files

3) Deletes current files and their views

4) Creates new files and their views. The new files include 7 additional fields at the end of the files.

5) Restores data from the BACKUP files to the new files mapping fields. For the new 7 fields, initialization to BLANK or 0 takes places

6) Deletes the BACKUP files

(due to space limitations file is not hosted. Send me an email to request the file: SampleSQLScriptToModifyDBFileWithDataPreservation.SQL)

  1. How can I disable the "Save password" option for a Win-As/400 application?. This is required to have a more strict control over passwords (users are required to type their password every time they launch the application). Windows-AS/400 generator.
Solution: Rename or remove the Ob450jr.dll (in the Plex\BIN directory).
  1. How can I set a generic AS400 logon with a password that never expires?. If I try to distribute the applications' ini file with the user and password set the login process fails. Windows-AS/400 generator.
Solution: The password encryption adds some machine-specific information. It is necesary to use the windows API: ObConversationAPI::SetAS400Password. The implementation steps are:
  1. Compilation fails with message "unable to connect on socket". AS/400 connection is TCP/IP and this one is up and running (verified with other applications).
Solution: Port specified for TCP/IP connection in Generate and Build Options|System Definitions|AS400 COnfiguration did not have status of 'listen' (verified this with command WRKTCPSTS *CNN on AS/400 system). Started TCP/IP Dispatcher for the port number needed.
  1. How can I obtain the implementation name of a function and display within a message in a calling function?
Solution: Enter the following meta-code to retrieve the implementation name in the function being called:

+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.

  1. While testing some validation code, to produce a *View Status of error renamed a table (did not delete it) expecting that its Real Attributes would not find it. After calling the Create Instance scoped to Real Attributes I still got a returned status == successful. Why? (WinNT-AS/400 implementation)
Solution: The link (reference) from a table and its Real Attributes view is not based on the table's implementation name; there is an internal reference maintained by the AS/400. That is why even after renaming the table the view could still find and access it.
  1. How can I 'duplicate' a function without inheriting from it? (no use of IS A triple).
A simple approach is selecting (higlighting) all the contents of the Action Diagram and with CTRL + C send it to the clipboard and then on a new Action Diagram CTRL + V. This will work but you may have some mapping errors for the fields/variables not defined in your new function. To fully duplicate the original, before pasting into the new Action Diagram, open your Model Editor scoped to the original function and select every single triple and in the source object, type the new function's name to enter the new triple (this will have to be done a triple at a time). Once you've created the first triple for your new function you can open your browser and find the function there for dragging (that way you avoid potential typing errors that would create new functions).Duplicating a function this way will obviously eliminate all inheritance.
  1. How can I insert spaces, linee feeds, and cariage returns into a concatenated value formed with different fields if CONCAT command strips out these control characters? This occurs even by concatenating values containing literal values with these control characters (tested with Plex 4.5).

Solution: Create a Source Code object that inputs the parameters you want to concatenate and insert the control characters withing the message (space = " ", line feed = "\n", carriage return= "\r"). Finally make an API Call to this object.

Another alternative to formatting is by use of Trigraphs on Format Messages.

When specifying special fields format (Dates, times and timestamps, Numbers with decimal places, Literal values longer than 32 characters, special control characters like carriage return and tabs, etc) TRIGRAPHS can be used. A Trigraph is a special sequence of escape characters that are converted to the required character by the compiler.

Following is a chart with some of the most common Trigraphs to use:

To insert
Use
\
??/
[
??(
]
??)
^
??'
{
??<
}
??>
|
??!
~
??-
#
??=
TAB stroke
??/t
CARRIAGE RETURN
??/n

For additional details look for TRIGRAPHS under Plex's help

Note: Trigraphs cannot be used to print fields and labels on multiple lines (as in the TEXT prpertie for statics on panel). In such cases it is required to set the vertical size of the data or static control so that there is room for multiple lines. At run-time, the text will automatically wrap to a new line as required. Including a caret (^) character in the text of a label forces the text that follows to a new line (to display a carent in the text prefix the caret with a backslash: \^)

A common requirement is for a field value to represent a tab (\t). To insert a tab into a field value type: ??/t. Field's length may have to be increased to allow for the trigraph; for example, the value \t requires a field length of at least 2 but with the trigraph this increases to 4. Occasionally, it is necessary to insert a string that corresponds to one of the trigraphs (thus translation of the string is not desired); so, as an example, to include ??! in a field value precede the trigraph with ??/, in this case: ??/??! at run-time would display as: ??!7

Also for AS400 Implementation, if you are concatenating by using a Format Message (i.e. using &(1:) &(2:) to concatenate and include a space in between two parameters), make sure you generate and compilate the AS400 Message file.

36 a. MESSAGE used in a Format Message statement modified on AS400 variant for a server RPG function is not reflecting changes. No errors/warnings during function recreation.

Solution: Re-generated/rebuilt AS400 Message file

  1. Why can't I change Permission on objects I select on the Browser even if the checkbox for this operation can be selected? (work with Change Owner/Permission)
Solution: Even if the checkbox to Change Permissions is enabled and you can check the User, Group, and World boxes, if you don't own the object the operation won'tbe completed. Only the owner of an object and the administrator can change its permissions. Change the object ownership to you or your group (For Each Selected Object, Owned by CurrentOwner - Change Owner to:YourUser). If you don't have access to make this change you will have to log into the Group Model and extract with the corresponding authority (as Admin, for example).
  1. Do all Users working with Local Models of the same Group Model have to update the Group Model at the same time?
Solution: No. You can skip updating and just update when you have changes you want to reflect in the Group Model. Just make sure you won't be missing any update made by other User that may modify (either directly or by inheritance) the objects you are still working with as this would lead to conflicts next time you try your Group Model update. Also consider objects other Users are working on that inherit/interface with what you are manipulating.
  1. How can I make a Grid contained in an MDI Child Panel resize (at run-time) as the MDI Child is resized?. Right now if the MDI size is changed or maximized the Grid's size remains the same. The Properties for the Grid = Default and for the MDI Child panel = Maximize Box, Minimize Box = Yes, Modal Frame = No. This occurs for a panel that inherits from FOUNDATION/EditDialog.EditSuite.Grid.Panel and not for the panels that inherit from OBASE panels (Plex 4.50)
Solution: The Fix Bottom, Fix Left, Fix Right, and Fix Top properties should all be = Yes (Fix Left and FIx Top were No -wrong defaults provided in the Pattern Objects?-).
Note: The combination of these properties which determines how the element responds. Most common combinations are:

Top

Bottom

Left

Right

Description

Yes

Yes

Yes

Yes

Element resizes horizontally and vertically. Typically used for grids.

Yes

No

Yes

No

Size is fixed. Position is fixed relative to the top-left corner of the window. Typically used for push buttons.

Yes

Yes

Yes

No

Stretches vertically but horizontal size and position are fixed relative to top-left corner.

Yes

No

Yes

Yes

Stretches horizontally but vertical size and position are fixed relative to top-left corner (like a toolbar).

No

Yes

Yes

Yes

Stretches horizontally but vertical size and position are fixed relative to bottom-left corner (like a status bar).

  1. How can I check if an MDI Child window is already open and if it is, bring it on top of other MDI Children? THis is required to avoid multiple instances of the same panel to open.
Solution: Check the Word document ACTIVATE MDI CHILD where I provide detailed instructions on how to accomplish this.
  1. An enumerated entity is defined with Commit/Rollback functionality. The rollback does not occur for the enumerator key. If the process fails the entitie's records don't get created -rollback takes place- but the numerator values don't rollback and keep on incrementing (Cool Plex 4.5 - Win/AS400 generator)
Solution: Define the ""Entity.get next numerator" as COMMIT Child. The rule here is to define server update functions as COMMIT Child. With this the Commit control for an AS/400 implementation can be summarized as:
  1. MDI Parent calls a server external function that is defined as COMMIT Parent (this will make the server job to execute a STRCMTCTL command on the AS/400).
  2. Define all server update functions as COMMIT Child, including Internal Functions.
  3. Define client update functions (like the Edit Detail) as COMMIT Child. You can meta code to control commit/rollback operations after call to server update functions.
  1. Why is the Transfer|Register Target PC option disabled?. A new PC has just been installed with Plex and I want to transfer a Permanent licence from another workstation.
Solution: The Register Target PC option is only enabled when an active license is not found. By default, Plex installation grants a 30 day trial license. To allow the target PC registration, set the Windows Date/Time properties to a date where this trial license expires; then you can register the target and use the floppy to transfer the license. Finally you set the Date settings back to the original value.
  1. Error during compilation (C1853) states file obwafx.pch is not a precompiled header file
    (Plex 4.5 - Win/AS400)
    Error text:

    Compiling... AD8caF.CPP C:\LUCIO\GEN\AD8caF.CPP(19) : fatal error C1853: 'C:\LUCIO\GEN\WIN32\Release/obj/obwafx.pch' is not a precompiled header file created with this compiler Error executing cl.exe.

Solution: Delete obwafx.pch file. New compilation will create new one. Another possible solution: Copy _OBCORE.obj, obwafx.pch, and vc60.idb from another developer's PC to ...\release\obj folder

Note: Another common error that refers to a precompiled header is: Error during compilation (Build : warning : failed to (or don't know how to) build 'C:\BuildDir\obj\obrt.pch', C:\BuildDir\FunctionName.CPP(19) : fatal error C1083: Cannot open precompiled header file: 'C:\BuildDir\Release/obj/obrt.pch': No such file or directory)

Solution for this case: Install Visual Studio SP5 patch.

  1. In some particular processing all maintenance operations in a User Maintained entity.MS.MUI (change, add, delete, copy) have to be disabled, althought they will be reactivated under certain circumstances. If they are disabled users should still be able to scroll through the Grid and see the records. A subroutine sets all maintenance events state to protected but it also locks the Grid (at run time, scrolling on the Grid is not enabled). (Plex 4.5 - Windows/As400 generator).
Solution: For some reason setting the events state to Protected locked the Grid too (bug in Plex 4.5?). Change the state to Inactive, this will also set the Menu Items to a protected state and toolbar buttons will be hidden.
  1. How can I take a function out of a commit/rollback process without modifying the logic in the calling COMMIT SYS Parent function? (Cool:Plex 4.5 / AS400 Client/Server generator)
Solution: Simply delete the COMMIT SYS = Child triple for the function and recreate the functions involved (this approach will not work for ODBC implementations).
  1. How can I produce an *Instance locked condition? This is required to test validation depending on this *returned status (Plex 4.5 - Win/AS400 generator)
Solution: This is something that is done entirely in the AS400. Use the ALCOBJ (Allocate Object) command in the AS/400 to 'lock' a table (use the Lock State = *EXCLRD), this will produce the *Instace locked result desired. Make sure you release the lock by 'dealllocate' by using the DLCOBJ command (with the exact same parameters).
PC FILES MANIPULATION
  1. How can I delete a PC file? This is needed after a process writes a temporary file that has to be deleted when the process ends.

Solution: A very simple approach is the creation of a Source Code object with the following C++ code:

{ remove(&(1:)); }

Where &(1:) represents the file name to delete. Additional validation will be required to check that the file was actually deleted.

Another simple way is with the following WinC Source Code:

{
DeleteFile( &(1:) );
}

Where

&(1:) = FIELDS/FullPath represents the FullPath+FullFileName

Alternatively you can make use of the following VBScript Source Code that makes use of the File System Object:

Dim fso
Set fso = CreateObject("Scripting.FileSystemObject")
fso.DeleteFile(&(1:))

Where:

&(1:) = File Name (OBMAPI/File names)

47B. How can I create a text file?

Solution: A very quick and easy solution is to make use of FileSystemObject on a VBScript Source code:

Dim fso, f1
Set fso = CreateObject("Scripting.FileSystemObject")
Set f1 = fso.CreateTextFile("&(1:)", True)

Where:

&(1:) = File Name (OBMAPI/File names)

For more details on how to create and wite information on text files read the following notes:

CREATING TEXT FILES

There are three ways to create an empty text file (sometimes referred to as a "text stream").

ADDING DATA TO TEXT FILES

Once the text file is created, add data to the file using the following three steps:

To open an existing file, use either the OpenTextFile method of the FileSystemObject object or the OpenAsTextStream method of the File object.

To write data to the open text file, use the Write, WriteLine, or WriteBlankLines methods of the TextStream object, according to the tasks outlined in the following table.

Task Method
Write data to an open text file without a trailing newline character. Write
Write data to an open text file with a trailing newline character WriteLine
Write one or more blank lines to an open text file. WriteBlankLines

To close an open file, use the Close method of the TextStream object.

View this sample code to see how the Close method is used in FileSystemObject.

In Plex, with a Source Code (Write Text Line with Trailing NewLine) that operates with an existing file:

Dim fso
Dim file
' Format object.OpenTextFile (filename [, iomode[, create[, format]]])
' This method is used to open a text file and returns a TextStreamObject that can then be used to write to, append to, and read from the file.
' The optional iomode argument can have one of the following Constants as its value: ForReading 1 Opens a file for reading only, ForWriting 2 Opens a file for writing. If the file already exists, the contents are overwritten. ForAppending 8 Opens a file and starts writing at the end (appends). Contents are not overwritten.
' The optional create argument can be either True, which will create the specified file if it does not exist, or False, which won't.
' The optional format argument uses one of the following Tristate values to specify in which format the file is opened. If not set, this defaults to TristateFalse, and the file will be opened in ASCII format. CONSTANT VALUE DESCRIPTION TristateTrue -1 Opens the file as Unicode . TristateFalse 0 Opens the file as ASCII. TristateUseDefault -2 Use default system setting.

Set fso = CreateObject("Scripting.FileSystemObject")
Set file = fso.OpenTextFile("TransmittalFile.txt", 8, False)
file.WriteLine(&(1:))
file.Close

Where:

&(1:) = Record to write (i.e. Ref Character, 250)
--------------------------------------------------------------------------------
Note: The newline character contains a character or characters (depending on the operating system) to advance the cursor to the beginning of the next line (carriage return/line feed). Be aware that the end of some strings may already have such nonprinting characters.

--------------------------------------------------------------------------------

The following VBScript example demonstrates how to open a file, use all three write methods to add data to the file, and then close the file:

Sub CreateFile()
Dim fso, tf
Set fso = CreateObject("Scripting.FileSystemObject")
Set tf = fso.CreateTextFile("c:\testfile.txt", True)
' Write a line with a newline character.
tf.WriteLine("Testing 1, 2, 3.")
' Write three newline characters to the file.
tf.WriteBlankLines(3)
' Write a line.
tf.Write ("This is a test.")
tf.Close
End Sub

UNDERSTANDING MORE ON THE FILESYSTEMOBJECT OBJECT MODEL

This model allows you to add, move, change, create, or delete folders (directories) and files.

The FileSystemObject (FSO) object model contains the following objects and collections:

Object
Collection Description
FileSystemObject Main object Contains methods and properties that allow you to create, delete, gain information about, and generally manipulate drives, folders, and files. Many of the methods associated with this object duplicate those in other FSO objects; they are provided for convenience.
Drive Object Contains methods and properties that allow you to gather information about a drive attached to the system, such as its share name and how much room is available. Note that a "drive" isn't necessarily a hard disk, but can be a CD-ROM drive, a RAM disk, and so forth. A drive doesn't need to be physically attached to the system; it can be also be logically connected through a network
Files Collection Provides a list of all files contained within a folder.
Folder Object Contains methods and properties that allow you to create, delete, or move folders. Also allows you to query the system for folder names, paths, and various other properties
TextStream Object Allows you to read and write text files
Folders Collection Provides a list of all the folders within a Folder
Drives Collection Provides a list of the drives attached to the system, either physically or logically. The Drives collection includes all drives, regardless of type. Removable-media drives need not have media inserted for them to appear in this collection.
File Object. Contains methods and properties that allow you to create, delete, or move a file. Also allows you to query the system for a file name, path, and various other properties

To program with the FileSystemObject (FSO) object model:

  1. Use the CreateObject method to create a FileSystemObject object.
  2. Use the appropriate method on the newly created object.
  3. Access the object's properties.

Dim fso
Set fso = CreateObject("Scripting.FileSystemObject")

Dim fso
Dim f1
Set fso = CreateObject("Scripting.FileSystemObject")
Set f1 = fso.CreateTextFile("C:\Plexdev\JES\GEN46\Win32\Release\UploadDMV.txt", True)
f1.WriteLine("Hello World!")
f1.close

Where:

&(1:) = File Name (OBMAPI/File names)

Set fldr = fso.GetFolder("c:\")

For more information check Plex's Help|Reference|Microsoft Scripting Documentation

Important note on running VBScript Source Codes: Plex functions executing VBScripts need to have a panel scoped.

47C How can I copy a file from one destination folder to a target location?

Solution: Create the following "CopyFile" WinC Source Code

{
BOOL RetValue;
RetValue = CopyFile( &(1:), &(2:), FALSE );
if (RetValue == 0)
{
&(3:) = " ";
}
else
{
&(3:) = "ERR";
}
}

Where:

&(1:) = FIELDS/FullPath ...QLF SourceFile (which is a fully qualified path that includes the file name to be copied)

&(2:) = FIELDS/FullPath ...QLF DestinationFile (which is a fully qualified destination path that includes the new file name -can be the original name)

&(3:) = *Returned status

Make an API call to the Source Code which will return ' ' if file was successfully copied or 'ERR' with any other condition

47D. How can I replace some text string on the 1st line of a text file?

Solution: This task was discussed in the following EDGE Thread:

TEXT FILE UPDATE

A suggested solution by Phillipe Moschkowitch was based on a Source Code object that used the File System Object:

Const ForReading = 1

Const ForWriting = 2

Set fso = CreateObject("Scripting.FileSystemObject")

'replace &(1:) with your file'

Set xFile = fso.OpenTextFile(&(1:), ForReading, True)

strText = xFile.ReadAll

xFile.Close

Set xFile = Nothing

strNewText = Replace(strText, "TextToFind", "ReplacementText")

Set xFile = fso.OpenTextFile(&(1:), ForWriting, True)

xFile.WriteLine strNewText

xFile.Close

Set xFile = Nothing

Set fso = Nothing

Where &(1:) is the FullPath to the text file (File Name and extension included such as c:\yourfile.xml) where the first line is to be replaced

47E. How can I copy all the files from a Source Directory to a target location?

Solution: Create the following "CopyAllFilesInDirectoryVB" VBSCript code that makes use of the FileSystemObject:

'Lucio Gayosso. Copy all files from a source directory to target location.

Dim ObjFso

Dim StrSourceLocation

Dim StrDestinationLocation

Dim StrSourceFileName

Dim StrDestinationFileName

StrSourceLocation = &(1:)

StrDestinationLocation = &(2:)

'All files will be copied to destination

StrSourceFileName = "*.*"

StrDestinationFileName = ""

'Creating the file system object

Set ObjFso = CreateObject("Scripting.FileSystemObject")

'Copying the files

ObjFso.CopyFile StrSourceLocation & "\" & StrSourceFileName, StrDestinationLocation & "\" & StrDestinationFileName, False

Make an API call passing the source and target directory paths, which should not be ending with '\'

47F. How can I move all the files from a Source Directory to a target location?

Solution: Create the following "MoveAllFilesInDirectoryVB" VBSCript code that makes use of the FileSystemObject:

'Lucio Gayosso 08/03/09 JEMS5108672. Move all files from a source directory to target location.

Dim ObjFso

Dim StrSourceLocation

Dim StrDestinationLocation

Dim StrSourceFileName

Dim StrDestinationFileName

StrSourceLocation = &(1:)

StrDestinationLocation = &(2:)

'All files will be copied to destination

StrSourceFileName = "*.*"

StrDestinationFileName = ""

'Creating the file system object

Set ObjFso = CreateObject("Scripting.FileSystemObject")

'Copying the files

ObjFso.MoveFile StrSourceLocation & "\" & StrSourceFileName, StrDestinationLocation & "\" & StrDestinationFileName

Make an API call passing the source and target directory paths, which should not be ending with '\'

47G. How can I work with file extensios and paths?

Solution: The following Source Code objects can be called as APIs for miscellaneous Extensions and Path tasls:

a) "AddFileExtension" Source Code:

#include <atlpath.h>

{
// Source Code created using ATL Server Library Reference|Utilities Reference. ATL Server provides code for manipulating paths and URLs in the form of CPathT and CUrl. Per MSDN "A thread pool, CThreadPool, is used in the implementation of the ATL Server ISAPI extension class and can also be used in your own applications. This code can be found in atlpath.h and atlutil.h"
// Adds a specified file extension to the provided Full Path (Path + File Name) if one doesn't exist.
CPath WorkPath(&(2:));
&(1:) = WorkPath.AddExtension(&(3:));
&(2:) = WorkPath.m_strPath;
}

Where:
& (1:)=ReturnStatus (Numeric)
& (2:)=FullPath (Path + File Name, i.e. Char, 1024)
& (3:)=FileExtension (Char such as .EXE, .DLL, etc.)

b) " GetFileExtension" Source Code:
#include <atlpath.h>
{
// Source Code created using ATL Server Library Reference|Utilities Reference. ATL Server provides code for manipulating paths and URLs in the form of CPathT and CUrl. Per MSDN "A thread pool, CThreadPool, is used in the implementation of the ATL Server ISAPI extension class and can also be used in your own applications. This code can be found in atlpath.h and atlutil.h"
// Retrieve the file extension for a given Full Path (Path + File Name), if one exists.
CPath WorkPath(&(1:));
&(2:) = WorkPath.GetExtension();
}

Where:
& (1:)=FullPath (Path + File Name, i.e. Char, 1024)
& (2:)=FileExtension (Char such as .EXE, .DLL, etc.)

c) " GetFileNameFromFullPath" Source Code:
#include <atlpath.h>
{
// Source Code created using ATL Server Library Reference|Utilities Reference. ATL Server provides code for manipulating paths and URLs in the form of CPathT and CUrl. Per MSDN "A thread pool, CThreadPool, is used in the implementation of the ATL Server ISAPI extension class and can also be used in your own applications. This code can be found in atlpath.h and atlutil.h"
// Retrieve the File Name from a provided Full Path (Path + File Name)
CPath WorkPath(&(1:));
WorkPath.StripPath();
&(2:) = (CString) WorkPath;
}

Where:
& (1:)=FullPath (Path + File Name, i.e. Char, 1024)
& (2:)=FileName (i.e. Char, 1024)
d)" GetPathFromFullPath" Source Code:
#include <atlpath.h>
{
// Source Code created using ATL Server Library Reference|Utilities Reference. ATL Server provides code for manipulating paths and URLs in the form of CPathT and CUrl. Per MSDN "A thread pool, CThreadPool, is used in the implementation of the ATL Server ISAPI extension class and can also be used in your own applications. This code can be found in atlpath.h and atlutil.h"
// Retrieve the Path Portion from a provided Full Path (Path + File Name)

CPath WorkPath(&(2:));
&(1:) = Work.RemoveFileSpec();
&(3:) = (CString) WorkPath;
}

Where:
& (1:)=ReturnStatus (Numeric)
& (2:)=InputFullPath (Path + File Name, i.e. Char, 1024)
& (3:)=OutputPath (Path + File Name, i.e. Char, 1024)
e)"CheckIfPathIsADirectory" Source Code
{
// Checks if the path is a directory or not

&(1:) = PathIsDirectory(&(2:));
}

Where:
& (1:)=ReturnValue (Boolean)
& (2:)=InputPath (i.e. Char, 1024)

A related checkup would be whether the Path is formed with Universal Naming Conventions (UNC):

"CheckIfPathIsUNC" Source Code:

{
// Checks if the path is formed with UNC (\\...)

&(1:) = PathIsUNC(&(2:));
}

Where:
& (1:)=ReturnValue (Boolean)
& (2:)=InputPath (i.e. Char, 1024)

47H. How can I append the contents of File A into an existing and loaded File B?

Create the following 'Append PC File A to File B' VBScript Source Code and make an API call to it passing Field A (Input File) and Field B (Resulting File):

' Lucio Gayosso 01/08/10.

Const ForReading = 1

' Create FSO Scripting object

Set objFSO = CreateObject("Scripting.FileSystemObject")

' Create an interim output file by concatenating the target merge file name (File B) with suffix MERGE

' This file will be written two times:

' 1) with the existing contents of resulting file found in the BATCH directory

' 2) with the contents of the new input file

Set objOutputFile = objFSO.CreateTextFile(&(2:) + "MERGE")

' Read all the contents of the existing file in the Batch directory (File B)

Set objTextFile = objFSO.OpenTextFile(&(2:), ForReading)

strText = objTextFile.ReadAll

objTextFile.Close

' Write the contents of the existing file in Batch directory (File B) into the interim MERGE file

objOutputFile.WriteLine strText

' Read all the contents of the new input file (File A)

Set objTextFile = objFSO.OpenTextFile(&(1:), ForReading)

strText = objTextFile.ReadAll

objTextFile.Close

' Write the contents of the new input file (File A) into the interim MERGE file

' At this point the interime MERGE file contains File B + File A

objOutputFile.WriteLine strText

objOutputFile.Close

' Delete the target file located in the Batch directory

objfso.DeleteFile(&(2:))

'Rename the combined file (suffix MERGE) into the original target name (original file name in the Batch directory)

objfso.MoveFile &(2:) + "MERGE",&(2:)

Where:

&(1:): Is the Input File A described as Full Path + File Name With Extension (FIELDS/FullPath)

&(1:): Is the Existing File B described as Full Path + File Name With Extension (FIELDS/FullPath)

More details on the following CA FORUMS' thread:

http://caforums.ca.com/ca/board/message?board.id=caplexgeneraldiscussion&message.id=2093&jump=true

  1. How can I rename a PC file?
Solution: As of now (Plex 4.5) there is no Plex's shipped Class Library object to accomplish this task. You can however create a Source Code object to do it:

******************************************************************************************************
// Lucio Gayosso. This Source Code renames a file with the contents of 'old name and path' parameter.

CStdioFile Rename;
CFile::Rename(&(1:),&(2:));

******************************************************************************************************

Where:
&(1:) = old name and path (OBASE/Narrative, length 128, C Format = Varying)
&(2:) = new name and path (OBASE/Narrative, length 128, C Format = Varying)

You can finally make an API Call to this object passing the required parameters.
  1. How can I read the contents of a text file without using the FileSystemObject model?
Solution: There are three basic operations to perform: Open the file to read, Read the file contents, Close the file.
Create the following Source Code objects and make the corresponding API calls in your Action Diagram:
**************************************************
To open a Text File:

CStdioFile readFile;

if (!(readFile.Open(&(1:),CFile::modeRead|CFile::typeText)))

&(2:) = 0;

else

&(2:) = 1;


Where:
&(1:) = File Name and Path (varycharacter)
&(2:) = Return Status (int)
**************************************************
To read from the Text File (one line at a time):

&(2:) = readFile.ReadString(&(1:));

Where:
&(1:) = File Name and Path (varycharacter). This field will serve two purposes: To pass the File Name/Path of the file to read and provide the entire string read.
&(2:) = Return Status (int, 1=successful, 0=EOF)
**************************************************
To close the Text File:

readFile.Close();

**************************************************

NOTE: To enhance the previous PC files manipulation you may want to answer the following question:

How can I check if a PC file (or folder) exists?

Solution: Use the following Source Code:

#include { // Check if file or directory exists
if ( (_access( &(1:), 0 )) != -1 )
&(2:) = "";
else &(2:) = "INF";}


Where:

&(1:) = File or PC Folder
&(2:) = *Returned status

Look within C++ Documentation more information about the "_access" function to further specialize this Source Code.

Alternatively Source Code to check if a file exists

GetFileAttributes (&(1:)); &(2:) = GetLastError();

Where:

&(1:) = OBWIN/File to open
&(2:) = File exists return status (Numeric, 1, C Format Integer, Values: Exist (0)/does not exist (2))


  1. How can I convert a STRING date in a non-standard format to a standard ISO?
Solution: If no function can be implemented directly for the conversion you can manipulate the string (by use of the "substring" statement) and then use one of Plex's date conversion functions. Look at the following example for the STRING DATE MANIPULATION.

  1. Why does a Commit PARENT function not terminate? (Plex 4.50 - Win/AS400 generator)
Solution: Make sure a 'Terminate' or 'Return' statement is added after the 'Commit' statement. The way to choose the command will depend on the implementation of the Commit Parent function: For functions that are called very often use 'Return' as this will keep the program loaded in Memory and ready for the next call. Terminate will close the Parent function completely which is good for functions that are called seldomly.
  1. Error "unable to connect on sockets" (this produced an 'Error loading translation DLL' message). There is an active AS400 connection (verified with Client Access) with TCP/IP access and the AS400 system definition in Plex is setup correctly. (Plex 4.5 Win-AS400 generator)
Solution: Multiple versions of Plex(OBSYDIAN) had been installed in the same machine thus different versions of the NSCONV32.DLL existed. Delete the old versions of this file.

NOTE: The Plex\Bin folder must be included in your windows path (this is done through the installation of Plex).

The "error to connect on sockets" can also be produced by the TCP/IP dispatcher not running on the AS/400. Normally, the dispatcher should start automatically but if it failed to do so (or additional dispatchers on additional ports are required) the dispatcher can be manually started by entering on an AS400 command line:

SBMJOB CMD(CALL PGM(PLEX/YOBSYTCP) PARM('35000')) JOB(YOBLISTEN) JOBD(PLEX/PLEX) JOBQ(QGPL/QINTER)

These are the default values that you should modify as needed (for example change 35000 to the port required)

  1. How can I execute an AS/400 command from a Plex application? (Plex 4.5, Win-AS400 generator)
Solution: There a source code shipped with Plex to do this task: OBAS400/Execute a command.
NOTE:This program will not work if you try to map a predefined field's value. You can make it work this way by modifying the code to do a 'Move left' operation (MOVEL) instead of a 'Move Array' (MOVEA). Create your own version of this source code with:

***************************************************
// Lucio Gayosso 05/10/01 . Correction for OBAS400/Execute a command

C MOVEL%-10.10sYZCMD
C EXSR CMDEXC
*****************************************************

The Source Code expects an OBJECTS/Command string parameter where you will pass your AS/400 command as entered in the command line.

Now, create an external RPG function where you can make an API Call to this source code. Finally you can call this function as you normally do from any client/server function.

  1. How can I drag/drop variable fields from one Action Diagram's Palette to another?
Solution:If you have two action diagrams and need to copy some of the fields from one to the other without using your Object Browser: a)Open up both action diagrams and put them side by side making sure their palettes are open. 2)Minimize any other Plex editor/window open 3)Set cursor to the any action diagram input field 4)Use CTRL+Shift+Tab to cycle through the open functions until the two palettes are visible simultaneously. Now you can drag/drop fields between them.
  1. How can I set States for the different cells of a Panel's grid? (Plex 4.5 Win-AS400 generator)
Solution:
1) Locate the Edit Point right after the grid has been loaded (i.e. Post Point End load page for Grid)
2) For Each Row GridP
2) Get GridP
3) Enter you condition checking and set the corresponding states for each field in the Grid
4) Refresh GridP
Note: remember to set your States properties on the Panel Editor for each one of the elements to modify.
  1. How can I sort the columns on the different grids of a panel dynamically at run-time? (Plex4.5 - WinC functions)
Solution: A quick solution is by using the WINAPI/SortGrid Source Code object:
1) After having loaded the grid, locate an Edit Point where you can insert your code (i.e. 'End load page for grid' Post Point)
2) Make an API Call to the Source Code/refresh the Grid:
******************************************
// Sort grid in ascending order by Field1, Field2 &; Field3
Set GridSort<Control> = <Control.Grid1P>
API Call Source code: WINAPI/SortGrid
Refresh GridP
******************************************
Notes:. a)The 'Control' field stores the 'Control Name' property of the Grid to sort (Grid1P in this example) b) The 'FirstSortColum' input field for the Source Code corresponds to the Colum Number of the first Colum to sort on the Grid c) One limitation of this API is that it can sort a maximum of three columns d) If a parameter is not passed the functions fails compilation.
  1. How can I sort a Grid based on Virtual fields displayed on it?
Solution:
1) Create a "Position" region on the Panel and populate with the fields that you want to sort by (the Virtual fields on the View that is displayed on the grid)
2) Geet the "Grid" when you start loading:

Post Point Start load Grid
    Get Position

3) Add the following metacode for each row that is to be displayed on the grid:

Post Point Start set row usage for Grid
    +For Each Field Position
        ++If Not Empty
            ++If LE FetchedData
                // Do not do anything
            ++Else
                Set GridL<UseRow> = <UseRow.No>

Note: The Post Point suggested correspond to a Patterns approach, look for the equivalent Point for OBASE implementations.
  1. How can I find details at run-time about the server side of my application without having to pass output parameters to the calling client functions? (Plex 4.5, Win-AS/400 generator)
Solution: Use the WRKUSRJOB AS/400 Command while running your application and display messages for it.
Note: The only unconvenience about this approach is the use of generic users (like PLEXUSR). In this case you need to start your process and look for the job just created among the others that will exist for the same user.

  1. How can I accelerate the Extract time from a Group Model? A good network connection is available but there are several Referenced Libraries and also setting the Configuration for new Local Models takes a considerable amount of time and allows for errors. (Plex 4.5 - Win/AS400 generator)
Solution: A good approach/practice to this scenario is the use of a "Template" Local Model where all the Model Configuration entries have been made and all the Referenced Libraries have been exctracted. This template MDL file can be placed in a network folder where all developers can access it. The way to work with it:
1) Copy the Template.MDL from the network to your local folder. Name it as your current local model (i.e. LOCAL.MDL). If a previous model existed this will assimilate the existing LOCAL.BLD and LOCAL.LIB files.
2) Open the Local Model and logon the Group Model.
3) Highlight the "Host" Model (first entry in the Libraries list) and extract from it. Somebody will have to take care of re-extracting the Referenced Libraries in the template model should they change.
4) Save the Local Model.

  1. On my panel I have defined a default button ("Refresh") but this does not execute on ENTER key pressed. Radio buttons have just been added on the panel. (Plex 4.5 - Win/AS400 generator)
Solution: Make sure all elements (static, field, values) for the radio buttons have a unique tab sequence number.

  1. A BlockFetch function is not restricting. The Positioner and Restrict varibles are populated and the values are mapped correctly in the calling function. This BlockFetch function is scoped to a Fetch view that is keyed on Key1, Key2, and Key3 (in that precedence). The Restrict variable is populated with this view and Key2 is ommited (therefore Restrict contains Key1 and key3). (Pattern Development, Plex 4.5 Win/AS400 Generator)
Solution: The problem is that the key2 can not be omitted this way (this is an AS/400 contrain). Create a new View based on the original Fetch (i.e. FetchByKey1Key2) and ommit Key2 here. Finally, define the new view as input for the BlockFetch and keep only the keys (this will make BlockFetch restrict on Key1 and key3)

  1. I loaded data into a Plex-generated table out of an Excel Spreadsheet file (through Microsoft SQL Server 7.0's "Import and Export Data" utility). The data seems to have been loaded correctly but when I try to access it through Plex functions, the operations fail and the AS/400 messages display "Mapping Errors". This occurs with all fields where Null values are present (Nulls in the Excel spreadsheet rows do not contain any value). Plex 4.5/Win-AS400 generator.
Solution: Plex functions cannot access the EMPTY values in the AS/400. These records have to be modified to represent Nulls as the default values for the corresponding field types (a blank or space for Character fields, 01/01/0001 for dates, and 0 for numbers). In this case the replacement can easily be made by selecting all rows in the Excel file and use the Find/Replace utility to make the appropriate changes.

  1. B. For an import process, data validation routines for missing values are failing. After checking database found out that some values included BLANKS (" ") and others NULL values (<NULL>). Blanks are validated correctly but nulls are not identified in AD statements. (Plex 4.5 Microsoft NT Backoffice generator/SQL Server 2000)

    Solution: The application needs to provide NULL support as the NULL value is not the same as an EMPTY value (""). NULL in SQL Implementation is not the same as adding a value triple to the field without a literal value. An easy solution is to check on the collation sequence for BLANKs to identify if a value had been provided or not: IF FIELD >> Field.BLANK then DOSomeProcess.

    Notes on Plex handling of NULLS:

    Nulls and SQL. Plex null support is designed to correspond closely with the concept of SQL NULL. For an SQL/ODBC database, when a null field in a row is being written to or read from the database, SQL NULL indicators are used to transfer the state to or from the database. When the null value is referenced in the select or omit set of a view, the resulting SQL predicate will use the keywords IS NULL or IS NOT NULL, as appropriate (the SQL query will translate these values as IS NULL or IS NOT NULL).

    Plex's implementation of NULL values differs from SQL NULL in that Plex null value is in the collating sequence. SQL NULL is outside the collating sequence. The collating sequence for special field values is:

    Null < Low < Normal Values < High (this was the fundamental for the solution offered on this item)

    When working with existing data in an SQL database, note that the data may include null values which will fail an If Empty condition (even in the absence of a FLD null VAL triple). To avoid this situation data can be modeled correctly by providing null support in the model or eliminate the null values from the database with a SQL Script.

    Nulls and the AS/400
    The AS/400 database and the RPG/400 programming language do not support the concept of a null state. On the AS/400, processing is based on the actual content of the field concerned.

    When a field in a null state is passed from a Windows client to an AS/400 server, the null state is converted to the appropriate default empty value. For example, a null numeric field will be converted to zero. Alternatively, if you explicitly specify a literal value for the large property of the null value, this literal will be used instead of the default. This may be useful when you need to distinguish between the empty and null states of a field.

    Note: A simple example for the checking of the collation sequence to avoid nulls

    If Variable1<Field1> << <Field1.*Blank>

    Set Variable1<Field1> = <Field1.*Blank>

    If Variable2<Field2> << <Field2.*Blank>

    Set Variable1<Field2> = <Field2.*Blank>

    This will eliminate the SQL Server's <NULLS> values and replace by the known empty values.

    In addition, you can get more information on Plex validation for NULL in the following EDGE Thread: ++If NOT Empty problem

  1. I created a database on SQL server but no user can execute the application. The datasource test accesses all tables and views for all users, though. Plex 4.5a/Win-ODBC generator (server: WinNT4.0 with SQL Server 7.0).
Solution: The problem is due to not having DBO as the tables/views owner. The compile process took the default user on the database as the owner thus granting access just to that user even if other users are configured with the same authorities. Unfortunately, with SQL Server 7.0 it is not possible to reassign OWNERSHIP of objects created under a specific user. To correct the problem drop all database objects and recreate them with DBO as the owner (tipically user sa) (if your database is populated use SQL Enterprise Manager Utilities to backup/export/import it).

  1. To compare two functions in two different models, I opened both models side by side. After reviewing the functions I tried closing Plex but the application froze. I used Task Manager and tried to start Plex but it did not launch and terminated after the following message (Plex 4.50):

Solution: The Plex.ini file got corrupted. To avoid re-installing Plex and losing the license re-name Plex.ini and start Plex. The application will prompt you to allow creation of a new Plex.ini. You may have to re-visit this INI file to add entries previously made (refere to your re-named Plex.ini). Opening more than one model at a time is common practive and there should have been another reason why the file got corrupted (out of resources, conflicting application running at the same time, etc.)
  1. I received a Local Model from the Group Model librarian and generated the application (straight out from the model, no modifications). The status fields' combo boxes display nothing and the inherited Prompt events (prompt operations triggered through metacalls) do not work. Using this exact same model on the Model librarian PC (we checked sizes, timestamps, and Model Configuration and it is indeed the same .MDL file) the generation/compilation create panels that operate as expected. The remote development machine has the same configuration (Plex 4.5a, C++ 6.0 with Standard Installation, Service Pack 4.0 for the compiler applied -this Service Pack comes on the Plex installation CD-). Plex 4.5a/ODBC generator (SQL Server 2000).
Solution: This was a complicated problem to track as the remote environment seemed to have worked with the same software components. However, there was a difference: The remote system had been upgraded to Plex 4.5 whereas the local was a direct install of this release and for this reason, the compile environment had a mix of files that generated the expected panel behaviour (even taking the remote PC source code and compiling locally would not produce the desired results). CA's support mentioned there was no fix on this release and that the solution was an upgrade to Plex 5.0. I found a work-around though, but requires meticulous work:

For more details on this, check the following Thread (EDGE Forum Group):
http://neo3.sba.com/forums/Thread.cfm?CFApp=82&Thread_ID=25346&mc=31#Message69858
  1. How can I remove trailing blanks on a field? (Plex 4.5)
Solution: Create a Source Code object with two parameters that will be the strings (input and return):

Source Code:
// Lucio Gayosso 03/20/02.
// This code removes trailing (right) blanks from a character string.
// It uses the TrimRight function inherited from CString.
// It uses long fields (length 1000)
{
&(1:) = &(2:);
&(1:).TrimRight();
}
Where:
&(1:) = Returned string (Character, lenght as required)
&(2:) = Input String (Character, lenght as required)

You can also use the following Source Code to Trim all spaces:
{
&(1:).TrimSpaces();
}

Where:
&(1:) = Parameter string

  1. How can I run an application without displaying it on the taskbar? (Plex 4.5)
Solution: Create/use the following Source Code (no parameters)

//This allows a function to run without being displayed in the taskbar.
{
CWnd *pCWndCurrent ;
pCWndCurrent = ObPanelAPI::GetPanelCWndByName("*current") ;
if (pCWndCurrent)
{
pCWndCurrent->ModifyStyleEx(0, WS_EX_TOOLWINDOW, SWP_DRAWFRAME) ;
}
}

  1. How can I find the position where a string is located in a given string? (Plex 4.5)
Solution: Create/use the following Source Code

&(3:) = &(1:).Find( &(2:) );

Where:
&(1:) = Source String (FIELDS/SourceString)
&(2:) = Search String (FIELDS/SearchString)
&(3:) = Position in String (FIELDS/PostionInString)

  1. How can I get the lenght of a given string? (Plex 4.5)
Solution: Create/use the following Source Code object:

// This code returns the number of characters in a string.
// It uses the GetLength() function inherited from CString.
// It may be necessary to remove the trailing blanks first.
{
&(1:) = &(2:).GetLength() ;
}
Where:
&(1:) = Local String Length (Integer)
&(2:) = Local Character String (Character, length 256)

  1. Plex generated functions do not validate dates on SQL Server 7.0. Two new fields were added to a table (Date and Time both ISO). Data was then loaded from records in a backup of this table that did not have these two fields. Plex 4.5 - ODBC Generator (SQL Server 7.0)
Solution: After the table was re-built to include the two new fields and the data from the backup file was loaded, the values value for the new fields were set to EMPTY (no values) and validation failed because Plex functions did not recognize these values as NULLS. Convert the Empty values to Nulls (Null ISO DATE in SQL Server 7.0 = '01/01/175', Null ISO TIME = Date part of Time stamp, i.e. '4/11/2002')
  1. When viewing the message log, configuration, or other grid-based screens the highlighted line is filled with a white space. Text is not visible unless clicking somewhere else on the screen or push F1 (Development time, Plex 5.0)
Solution: Change Windows Color settings to 24 bits or less.
  1. Plex GPF’s when attempting to open any Action Diagram (Cool: Plex 4.5, 4.5a. 5.0).
Solution: Define a default printer for the PC.
  1. YOBSYTCPDP dispatcher ‘hangs’. The program serves a few successful requests then in stops working (Cool: Plex 4.5, 4.5a, Win/AS400 generator)
There is a latest release of the YOBSYTCPDP dispatcher program dated 3/12/01 that works with Plex 4.5 & Plex 4.5A downloadable from CA e-support website as APAR number QO11083 under Plex 4.5a release
  1. When trying to execute an AS400 client/Server application on Win95 PCs, receive error: OB450LC.DLL was linked to missing export file OLE32.dll (Cool: Plex 4.5, 4.5a, Win/AS400 generator).
Install the latest MS version of DCOM & Winsock 2 update. DCOM for Windows 95 can be downloaded from the following Web location: http://www.microsoft.com/com/dcom/dcom98/dcom1_3.asp.
  1. Error "1-15: Restriction file moved" when launching COOL: PLEX (Cool: Plex 4.5, 4.5a. 5.0).
Solution: This message is due to having a corrupted license. This could have been producted by a hardware and/or OS upgrade. To correct, close Plex and delete the entire OBLICENSE subdirectory under the OS folder (\Windows or \WINNT). Re-start Plex. The message "Plex is not licensed for this workstation" should appear, followed by the Plex registration screen. Request a new license/enter the re-set code on this screen. Note: With Plex 5.0, the folder to delete may be under \Program files (Crypkey License).
  1. Cannot get the Message Log to display maximized at run-time. A function triggers the Message Log but as a minimized window with no controls available (no handles to resize, no popoup menu, no mouse or keyboard actions available). (Plex 4.5, WIN-ODBC generator).
Solution: A panel was not associated with this process. The Message Log was triggered by a stand-alone EXE. Scoped a panel and was able to control the Message Log properties on the application's INI file (section: [Message Log])
  1. How can I convert a string to Upper or Lower Case? (Plex 4.5, Win-ODBC generator)

Solution: Create the following Source Code objects passing the String to convert:

To Convert to Upper Case:

{ // UPPER CASE STRING
char cStartStr[256] = "" ;
strncpy( cStartStr, &(1:).GetText(), 255) ;
if (cStartStr)
{
_strupr( cStartStr );
&(1:) = cStartStr;
}
}


To Convert to Lower Case:

{ // lower case string
char cStartStr[256] = "" ;
strncpy( cStartStr, &(1:).GetText(), 255) ;
if (cStartStr)
{
_strlwr( cStartStr );
&(1:) = cStartStr;
}
}


Where the String field is [Char,255]. Finally make an API Call.

Also possible (to convert to lowercase):

// Set all the alpha characters to lower case but the first one

CString szUpdate = &(1:);
szUpdate.MakeLower();
int nLen = szUpdate.GetLength();
BYTE cUpdate = szUpdate.GetAt(0);
if ( isalpha(cUpdate) )
szUpdate.SetAt( 0, toupper( cUpdate ) );

Where:

&(1:) = FIELDS/VaryCharacter

78b. How can I capitalize only the first letter in a given string? (to format person and street names for example).

Solution: Following is a Source Code to capitalize strings considering special cases where second letter is not alphanumeric (like: O'Conner' O'Brian, St. Andrews, etc) and cases where first letter is 'M' and second is 'c' (like McDonald, McBrian, etc)

//Checks for non-alpha characters and capitalizes the next alpha

//rather than searching for specific replacement characters

{

// Eliminate leading and trailing spaces

&(1:).TrimSpaces();

// Set all the alpha characters to lower case except the first one

CString szUpdate = &(1:);
szUpdate.MakeLower();
int nLen = szUpdate.GetLength();
BYTE cUpdate = szUpdate.GetAt(0);
CString sFirstLetter = szUpdate.GetAt(0);
if ( isalpha(cUpdate) )
szUpdate.SetAt( 0, toupper( cUpdate ) );

// Step through the string and capitalize any character following a non-alpha

int nPos = 1;
while ( nPos<=nLen ) {cUpdate = szUpdate.GetAt(nPos++);

// LG 02/25/04. If second letter is not alpha OR first letter is 'm' and second 'c', capitalize 3rd letter

if ( (isalpha(cUpdate)==0) ||((sFirstLetter == 'm') & (nPos == 2)) & (cUpdate == 'c')) {
// Set the next character to upper case if it is alpha
cUpdate = szUpdate.GetAt(nPos);
if ( isalpha(cUpdate) )
szUpdate.SetAt( nPos++, toupper( cUpdate ) );
}
}
szUpdate.TrimLeft();
szUpdate.TrimRight();
if (szUpdate == "Iii" || szUpdate == "Ii" || szUpdate == "Iv")
szUpdate.MakeUpper();
&(1:) = szUpdate;
}

  1. How can I split a String into diferent component fields (Cool: Plex 4.5, Win/ODBC Generator)

Create a Source Code using the vBScript function "Split()"

Split(Expression, Delimiter, Count, Compare)

The Split function separates a string into substrings and creates a one-dimensional array where each substring is an element. There is only mandatory argument is "Expression"

Source Code:

MyProductArray = Split(&(1:), " ", -1, 1)
&(2:) = UBound(MyProductArray)

Where:

&(1:) = String to split [Char,255]
&(2:) = Subscript of the array [FIELDS/Long]

Note: VBScript UBound Function
Returns the largest available subscript for the indicated dimension of an array. &(2:) can be used later to acess each one of the array elements.

Example of an implementation based on this concept.

The following ‘SplitNameStringIntoComponents’ VBScript source code inputs a string and breaks into its known fields, in this case a Person’s Last, First, and Middle Names:

' Lucio Gayosso 03/04/10. Created function to split a string that contains a Person name
' into its component fields
' Function returns the subscript of the array and the following known array elements
' Last Name (element 0), First Name (element 1), and Middle Name (element 2)
MyStringArray = Split(&(1:), &(3:), -1, 1)
& (2:) = UBound(MyStringArray)
& (4:) = MyStringArray(0)
& (5:) = MyStringArray(1)
& (6:) = MyStringArray(2)

Where:

&(1:) = String to split (FIELDS/VaryCharacter)
& (2:) = Subscript of the array (FIELDS/Long)
& (3:) = ElementsSeparator (FIELDS/TargetString). Any separator can be passed such as ‘~ ‘, ‘,’, ‘$’, etc.
& (4:) = Person’s Last Name (FIELDS/VaryCharacter)
& (5:) = Person’s First Name (FIELDS/VaryCharacter)
& (6:) = Person’s Middle Name (FIELDS/VaryCharacter)

The returned ‘Subscript of the array’ can be used for validation or to process additional array elements not considered by the direct assignment within the Source Code

  1. How can I associate an image with records from the database and save the image into a table? (Cool: Plex 4.5, Win/ODBC generator, SQL Server 2000)
Define a field type BLOB (Binary Large Object) where the associated image will be converted and saved. For detailed instructions check the document: Procedure to associate a PC file with a database record and save it as a BLOB (BINARY LARGE OBJECT) in the database.

Note: BLOBS in the AS400. Storing BLOBs in the AS400 represents a problem as several limitations exist (mostly with the size of the files that can be stored). Some suggestions on how to handle these can be found on the following threads (EDGE Forums):

http://neo3.sba.com/forums/Thread.cfm?CFApp=82&&Message_ID=68468&_#Message68468
http://neo3.sba.com/forums/Thread.cfm?CFApp=82&&Message_ID=74519&_#Message74519
http://neo3.sba.com/forums/Thread.cfm?CFApp=82&&Message_ID=57490&_#Message57490

  1. How can I add multiple times the same parameter field on the same Message object? (Plex all versions)
Include a "for QLF" continuation triple to qualify each new addition of the parameter.
  1. Can I use UNC (Universal Naming Convention) path to specify pre-built C++ libraries for compilation?. This is required to centralize the LIB files location in a network folder and avoid truncation of the pre-built libraries path (Plex all versions).
Solution: Yes, as long as you follow the proper syntax: \\computer\sharename\subdirectory (example: \\plexdevpc\F\PlexLib\Model1.lib;\\plexdevpc\F\PlexLib\Model2.lib)
  1. How can an Edit Box be enabled to allow "word-wrapping". This is particularly important when information is pasted on an Edit Box and only part of it is put on the box (Plex all versions, Window panels).
Solution: On the Panel Editor, for the Edit Box set the Multi Line property = YES, Scrolling = Vertical, and Scroll Bars = Vertical.
  1. How can I find and replace character on an Input String without using Source Code objects. Some Source Code objects cannot be implemented on AS400 Server Functions (Plex all versions, all Generators).

Solution: Look for the detailed instructions on how to create this function under the DOWNLOADS section of PLEX WORLD (Function to replace all BLANKS by UNDERSCORES without using Source Code objects for an Input String)

84 B) How can I replace some character(s) in a String by other ones with a count on the number of replacements?

Solution: Create the following ‘ReplaceCharacterWithReplaceCount‘ VBScript Source Code object and make an API call to it:

' Lucio Gayosso 03/04/10 Created function to replace characters in a string with a replacement count.

&(1:) = Replace(&(1:),&(2:),&(3:),1,&(4:))

Where:

&(1:) = String (FIELDS/VaryCharacter)
&(2:) = OriginalCharacter (FIELDS/VaryCharacter)
&(3:) = NewCharacter (FIELDS/VaryCharacter)
&(4:) = NumberOfReplacements (FIELDS/Number)

  1. How can I change the Column Heading dinamically at run time. Using States to define the different values is not an option as the Text for the headings will be data-driven (Plex 4.5, WinC Clients)
Solution: Make use of the following Source Code object

HWND hGrid=ObPanelAPI::GetControlHandleByName(&(1:));
PostMessage(hGrid,HGFM_SETNAME,nn,(LPARAM)&(2:).GetText());

Where:
&(1:) = Grid Control Name (i.e. GridP)
&(2:)= New caption
nn = column number to change.

Note: This Source Code can further be enhanced to input &(3:) = Column Number

{
HWND hGrid=ObPanelAPI::GetControlHandleByName(&(1:));
if (hGrid)
{
PostMessage(hGrid,HGFM_SETNAME,&(3:),(LPARAM)&(2:).GetText());
}
}

If multiple columns are being changed simultaneously, the message type needs to be changed to SendMessage, check for more details EDGE Thread "Changing column headings at run time "

  1. How can I Show/Hide columns dinamically at run-time? (Plex 4.5, WinC Clients)
Solution: Make use of the following Source Code object

HWND hGrid = ObPanelAPI::GetControlHandleByName(&(1:));
ASSERT ( hGrid );
if (hGrid) SendMessage(hGrid,HGFM_SETSTATE,&(2:),MAKELONG(&(3:),HGFF_HIDDEN));


Where:
&(1:) = Control Name (i.e. GridP)
&(2:) = Column number
&(3:) = Show=0/Hide=1

Update: Apparently this is no longer working with Plex 5.0. No work around as of 02/10/03.


WORKING WITH COMBO BOXES
  1. How can I clear a Combo Box dinamically at run-time (Plex 45, WinC clients)
Use the following Source Code:

{
pHComb myCombo;
myCombo = (pHComb) ObPanelAPI::GetControlByName( &(1:) );
if ( myCombo )
myCombo->Clear();
}

Where:
&(1:) = FIELDS/ActiveXControl
and
FIELDS/ActiveXControl takes its value from Work:
Name Field: Field_to_clear, Work

 

87A. Why do combo boxes loaded dynamically cannot display certain values? -these are displayed as blanks- (Plex 4.5 windows Clients)

Solution: In this particular case, the program that sets the control (on either a combo or edit box) failed for certain values that were located past a limit imposed by Plex on the number of values that can be displayed in a control (128 values). No work around was found and the control was changed to a promptable Edit Box.

Note: The dynamic load of the combo box on this example was accomplished with the following Source Code (AddComboValue)

{
pHComb myCombo;
myCombo = (pHComb) ObPanelAPI::GetControlByName( &(1:) );
if ( myCombo )
myCombo->AddValuePair( ObCharFld(), (LPCSTR)&(3:).strGetText(), (LPCSTR)&(2:).strGetText() );

Where:


&(1:) = ActiveXControl (this is the Control Name for the combo from Plex's Panel Designer)
&(2:) = Code (value initially loaded for the control)
&(3:) = Description (value displayed for end-user for the code above)


  1. How can I display messages for the Server functions of my application running on an NT server? (Plex 4.5 / Win-Backoffice generator. Win200Server).
Solution: Use Windows Event Viewer.Follow this procedure:

Settings|Control Panel|Administrative Tools|Event Viewer
Select the option "Connect to another Computer" (select the Server to display messages from).
Run your application or execute the function for which you want to get messages.
Under the "Application" Log View, sort by Date (descending) and find the messages by looking for the entries where the User column matches your PC or the user ID used to execute your application.
Double click the Information field to display the event Description where your message details are displayed.

Notes: Add the messages as type Dialog on the AD of your Server functions. If no messages are displayed make sure the Log is not full (you can clear by highlighting Event Viewer|Application log and right-mouse click to select Clear all Events)

  1. My AS400 submitted jobs display a status of "ON HOLD". How can I get details about this? (Plex 4.5 - Win/AS400 generator).
Solution: Use the Work with Job Queue As400 command (WRKJOBQ) to get details about the JOB QUEUE your jobs are sent to. By default AS400 jobs are sent by Plex to QBATCH in library QGLP. You can check what JOBQ is used by going to Gen & Build Options|Systems Definition, under your AS400 system defined for your compilation. WRKJOBQ provides an option to release the job queue (OPT 6).
  1. Why are new values on drop-down boxes for Status Fields not visible on the panels? (Plex 4.5 WinNT/Backoffice generator)
Solution: The values had not been "refreshed" on the panel. On the Panel Editor select the Status Fields and right-mouse Click|Refresh values. Re-create function.
  1. How can I change the implementation names for fields that derive from a qualified relation (ENT refers to ENT, ...for QLF)? (Plex all versions)
In thiskind of references the fields that are qualified are not exactly fields but "attributes" which are most of the times considered a synonym for fields but that have some differences (they don't always behave the same like when they are used on sets for views selection). A piece of advice is the "replacement" of such attributes by actual fields (by using "..replaces" continuation triples) right after the ..for QLF.
  1. What's the difference between pre, edit and post points? (Plex all versions)
"Edit points" exist only for compatibility with Previous Plex versions (when the tool was still named OBSYDIAN). The term to use now is "Collection points" which is basically used to name the Pre and Post points! (yes, this is kind of complicated but if you have experienced the evolution of the tool some of these issues start becoming clearer). If the Plex development lab gets to read this I would suggest to include an option to hide the Edit Point from the Action Diagrams at users will and just leave Per and Post points. "Collection Points" are code containers. The difference is that edit points overwrote each other on subsequent levels (down the inheritance tree) and this led to a lot of confusion when multiple people worked on the same Action Diagram. Collection Points on the other hands are accumulative and serve as a way to "share" logic in a sequential manner. To determine wether to use a Pre or Post Point just think about this Pre points execute before the Post Points. I always use Post Points unless there a specific reason not to because if the Prepoint is use there is no way for another person to add code previous to mine at a later time. Another piece of advise, whenever you make use of a collection Point add another with the EDIT POINT statement.
  1. An "EnquiryReply" field cannot be displayed correctly after Enquiry Message statement. Field displays non-existing value (Plex 4.5 / WinC Client)
Solution: "EnquiryField" had been placed on a Panel region. Moved to Action Diagram variable (Enquiry Message message, variable.field).
  1. I have received messages related to the LPROP.DAT file during extraction. How can I find out if the Group Model is corrupted? (Plex 4.5 and previous releases, Group Model Extraction)
Solution: LPROP.DAT is the file that stores the Large Properties for all objects in your Group Model. First you need to determine whether Group Model corruption has occurred. Corruption can show as:

  • Missing triples or objects in a local model
  • Seek errors
    These errors are displayed in the error log during extraction and mean that objects are looking for their triples beyond the LPROP.DAT end of file. The most common errors: System Error: "E-SYS-1439: Unrecoverable disk address error. Triples for object, '%s', cannot be found, System Error: "E-SYS-1440: Unrecoverable disk error. Some triples found missing for object, '%s', *** Seek error: A ‘seek’ error occurred accessing the file "GroupModelPath\LPROP.DAT"
  • Errors in the Num.Num file
    These errors are displayed if the Group Model has been repaired. Messages along the lines *** ERROR found in group model file, "Num.num"***
  • Missing group model data files
    A Group Model is formed by several files of different types (GRP, DAT, TAB, etc). If any of these is missing or cannot be opened some messages like “The file "GroupModelPathName" was found missing 1 or more files. Restore from backup”, will be displayed

    If Corruption has occurred and you get any of this messages, restore to the previous backup of the Group Model. If errors are still present after using that backup go to the one before and so on.

    If no sign of corruption is detected and you are able to update/extract the errors detected about not being able to pen the LPROP.DAT file might have occured because the network connection from the Local to the Group Model was temporarly dropped.
    1. How can I modify an INI file entry? (Plex 4.5 - Windows Clients):
  • Solution: You can use the following Source Code in an API Call:

    ObAppAPI::SetOption(&(1:), &(2:), &(3:), OB_OPT_USER_DEFINED);

    Where:

    &(1:) = INI Section

    &(2:) = INI Key

    &(3:) = INI Value.

    This is a variant of OBWIN/Set INI system value Source Code

    In addition, if you need to read a given INI value you can make use of the OBWIN/Get INI system value Source Code (read Plex's documentation on SetOption API for more details)


    1. How can I get the current system directory? (Plex 4.5 Bld 29, Windows Client)
    Solution: Use the following Source Code

    {
    char buffer[_MAX_PATH];
    GetSystemDirectory( buffer, _MAX_PATH );
    &(1:) = buffer;
    }

    Where:

    &(1:) = Current Directory(Char, 256)

    Alternatively,

    "Get Application Path" Source Code:

    {

    _getcwd(&(1:).GetBuffer(1024), 1024);

    &(1:).ReleaseBuffer();

    }

    "Set ApplicationPath" Source Code:

    {

    int nLen = &(1:).GetLength()+1;

    _chdir( &(1:).GetBuffer(nLen) );

    }

    Where:

    (&1:) = FIELDS/FullPath (Char, 1024)

    1. How can I modify the current window's Caption? (Plex 4.5.0 Bld 29, Windows Clients)

    Solution: Make use of the following Source Code:

    Set Current Windows Caption

    {
    CWnd *pWnd = ObPanelAPI::GetPanelCWndByName("*Current");
    ASSERT(pWnd);
    if (pWnd)
    {
    pWnd -> SetWindowText(&(1:));
    }
    }

    Where:

    &(1:) = New Windows Caption (OBWIN/Property Value, 100)


    1. I am getting an "_HtmlHelpA@16" error during compilation (Plex 4.5, Windows Clients)
    Solution: This error is produced if the htmlhelp.lib is missing or corrupted. Just replace it and recompile (file located under -i.e.- C:\Plex 4.5\LIB)
    1. How can I set an Edit Mask dinamically at run-time (Plex 4.5, Windows Client)

    Solution: Make use of the following Source Code:

    &(1:)=&(2:).strGetMaskedText((LPCSTR)&(3:).strGetText());

    Where:

    &(1:) = Formatted output for the field

    &(2:) = Value to be formatted

    &(3:) = Edit Mask.

    1. After installing/launching Plex on Win2000 received dialog box 'Licensing Error' and message "Error ID:8-102 Network: Network Driver appears to not be serving this directory" then "Error Id 2-104 INIT_crypkey not called successfully". (Plex 4.5).
    Solution: Crypkey service was not running on this PC. On Control Panel|Services and started Crypkey service. Message can also be produced when the Crypket license service was not installed before Plex, in this case go to services and end Crypkey service, re-install Crypkey, then Plex.

    1. How can I clear the entire contents of a given application's INI File SECTION? (Plex 4.5)
    Use the following 'INI File Cleanup.Delete INI Section C++' C++ Source Code:

    { WritePrivateProfileSection(&(1:), NULL, &(2:)); }

    Where:

    &(1:) = INI section (OBWIN/INI section)
    &(2:) = INI file name (OBWIN/INI file name)

    For additional details check:

    1. What intermediate files resulting from Plex generation/compilation can be deleted? Accumulation of these files are taking up a lot of disk space (Plex all versions)
    • Delete intermediate objects created during generation/compilation:
      • .rpg, .cpp, .h, .rc, .def, .rtf, and .hpj under \GEN
      • .lst under \Gen\Release (objects created when C++ source files are built).
      • Files that were compiled with option for DEBUG under \Gen\Debug (C++ source files built with the Build For Microsoft Debugging option selected which are the same as C:\Gen\Release, but also includes .PDB )
      • .res, .pch, and .obj under \Gen\Debug\obj (intermediate object files for a C++ build)
      • .res, .pch, and .obj under \Gen\Release\obj (intermediate object files for a C++ build).
      • .dsp under \Gen\Project (Visual C++ workspace )
    • You can also delete the Project folders created by the compiler (like 577E5406-8E27-4E6C-A5F6-B9F35B22866C) which are normally deleted when Plex and the compiler are closed but that at times are left behind due to different lock conditions.
    • The deletion of all these objects can be easily automated by creating a BAT file with the ERASE command such as:
    ERASE Drive:\YourPlexPath\GEN\WIN\Release\obj\*.obj
    ERASE Drive:\YourPlexPath\GEN\WIN\Release\obj\*.res
    ERASE Drive:\YourPlexPath\GEN\WIN\Release\obj\*.pch
    ERASE Drive:\YourPlexPath\GEN\WIN\Release\obj\*.idb
    ERASE Drive:\YourPlexPath\GEN\WIN\Release\*.exp
    ERASE Drive:\YourPlexPath\GEN\WIN\Release\*.imp
    ERASE Drive:\YourPlexPath\GEN\WIN\Release\*.lib
    ERASE Drive:\YourPlexPath\GEN\WIN\Release\*.lst
    ERASE Drive:\YourPlexPath\GEN\Project\*.dsp
    ERASE Drive:\YourPlexPath\GEN\WIN\*.obl
    ERASE Drive:\YourPlexPath\GEN\*.h
    ERASE Drive:\YourPlexPath\GEN\*.cpp
    ERASE Drive:\YourPlexPath\GEN\*.dat
    ERASE Drive:\YourPlexPath\GEN\*.msg
    ERASE Drive:\YourPlexPath\GEN\*.rc
    ERASE Drive:\YourPlexPath\GEN\*.rpg
    ERASE Drive:\YourPlexPath\GEN\*.def
    ERASE Drive:\YourPlexPath\GEN\*.rtf
    ERASE Drive:\YourPlexPath\GEN\*.hpj
    ERASE Drive:\YourPlexPath\GEN\*.tbl
    ERASE Drive:\YourPlexPath\GEN\*.txt
    ERASE Drive:\YourPlexPath\GEN\*.val
    ERASE Drive:\YourPlexPath\GEN\*.viw
    ERASE Drive:\YourPlexPath\GEN\*.str
    ERASE Drive:\YourPlexPath\GEN\*.java
    ERASE Drive:\YourPlexPath\GEN\*.jbl
    ERASE Drive:\YourPlexPath\GEN\*.mkj

    1. The Action Diagram Palette is not visible in an Action Diagram. Pressing the Activate Palette button does not work either (Plex 4.5)

    Solution: The Palette is out of the visible range thus it is not accessible. To move it to the visible area do the following: Push the Action Diagram Palette button and press ALT + SPACE to activate the palette's menu and then 'M' (move) then move the palette to the visible area using the arrow keys.

    1. How can I define a printer? (Plex 4.5)

    Solution: Use the following Source Code "PrinterSetup "

    {
    #include "commdlg.h"
    CPrintDialog thePrinter(TRUE,0);
    thePrinter.DoModal();
    &(1:) = thePrinter.GetDeviceName();
    &(2:) = thePrinter.GetDriverName();
    &(3:) = thePrinter.GetPortName();
    thePrinter.GetDevMode();
    // mode.dmOrientation = 2;
    &(5:) = DEVMODE.dmOrientation;
    }
    // Printer.Orientation = vbPRORLandscape
    // Printer.Orientation = vbPRORPortrait

    Where:

    PrinterSetup ParameterFLD PrinterName (Char, 70, case MIXED)
    PrinterSetup ParameterFLD PrinterDriver (Char, 70, case MIXED)
    PrinterSetup ParameterFLD PrinterPort (Char, 70, Case Mixed)
    PrinterSetup ParameterFLD PrinterPaperSize (Char, 40)
    PrinterSetup ParameterFLD Wrk_PrinterOrientation (FIELDS/Number, 1)

    1. How can I make a call to a Plex function defined in a Local Model that is not a referenced library in the current Local Model?

    Solution: Suppose we have a function in model A (Function A). We want to call this function from Local Model B but Local Model A IS NOT a referenced library thus Function A is not accessible in the current Local Model B (Function A will not show up in the Object Browser).

    Define a function (Function B) in Local Model B with the exact File Name, Implementation Name, Language SYS, type SYS as Function A. Set Impl SYS = NO.

    Define any Input/Output Dual fields in Function A in the exact same way in Function B (input FLD, dual FLD, output FLD). The implementation names of the fields in Local Model B DO NOT HAVE to match the ones in Local Model A.

    Enter the appropriate continuation triples to assign the I/O fields to the same Variable names as Function A (...for VAR). Note: It is important that Function B's I/O Groups and Variables are in the exact same order as the ones in Function A as if differences occur, Function B will be called but the mapping for the fields will be incorrect producing unexpected results.

    Define the appropriate variables in Function B (var VAR, ...as SYS)

    Example:

    CallAPlexFunctionFromANonReferingModel.zip

    1. How can I insert an entire text file into a SQL Server database table without having to read a row at a time? (Plex 4.5, WinNT Backoffice Generator)

    Solution: A very simple way to do this is by using a BULK insert SQL statement. This statement inputs a text file location + FileName and the specification on a delimiter for the records to import and then copies the data into a SQL Server table.

    The limitations to this approach are:

    • It does not create the table
    • All records need to match the destination table format. If any of them is incorrect the entire file is rejected.

    To use the bulk insert:

      1. Create a Source Code object with:

        bulk insert &(2:).&(3:) from &(1:) WITH ( FIELDTERMINATOR = '~' )

    Where:

    &(1:) = File Name with Path, all surrounded by Single-quote (FIELDS/FileName, 128)

    &(2:) = Table Owner

    &(3:) = Table Name

    Notes: If the application is NOT RUNNING ON THE SERVER and the path to the text file is through a relative path (with a drive letter like C:\file.txt) the process that performs the BULK insert WILL NOT work. In this case a Universal Naming Convention (UNC) path is required. To get it browse through My Network Places, Entire Network, and then through the folders to find the file. The UNC name for the path will be displayed like \\LocalSystem\C\File.txt The Field Terminator can be any character The last field on each record on the TXT file does not need a Field terminator

      1. Create a wrapper function where the Source Code is called with an EXEC SQL statement.
    1. Create a Client Function (WinC) that calls the wrapper function. This Client function should define the Server connection.

    A common error during BULK insert operations: Error Server: Msg 4861, Level 16, State 1, Line 1 Could not bulk insert because file '\\FullPath\File.txt' could not be opened. Operating system error code 5(Access is denied.).

    Solution: Folder where File.TXT was located did not have the appropriate security settings.

    1. Error "The COOL:Plex developer has tried to set a multi-occurrence variable index to a value larger than its declared size. Contact the developer.Program terminating. Declared size = (Number) FunctionName"
      (Cool: Plex 4.5 WinC Clients)
    The problem is due to a multi-occurrence variable (a variable that can store multiple instances of each field as defined by the FNC variable VAR ...occurs NBR triples like the Output variables from BlockFetch functions) being assigned a non-existing index value. Most common cases are the assignment through the USE statement (Use variable, variable). Ensure the assignment of the index field does not exceed the value defined (either directly or inherited) by the ...occurs SYS triple.
    1. Error "There is no data for the values you have entered" (Plex 4.5, Windows Client)

    Solution: This message is typically the result of some Metavalidation (through the Call VALIDATE/Meta.ValidateFields in the Validate Detail subroutine) that failed. Make sure all the detail fields (typically on variable DetailP) contain an adequate value.

    Note: Meta-validation checks if an optional field (or any of the fields, in a optional composite key) contains a value. If any of the composite or optional fields contains a value (is not NULL or BLANK) validation is triggered as shown in the following in the Metacode block (section of "Post Point Start validate Detail"):

    1. How can I fix the erratic behaviour of the Action Diagram scrolling with the mouse-wheel? (Plex 4.5)

    Solution: Known bug. To fix you need the Tweak UI Utility (free download from Microsoft site: Tweak UI 1.33

    To install and configure your Plex development PC:

    A) Download the zip file and unzip into a local folder.

    B) Move the extracted file to a system folder in your path (1.e. C:\WINNT\system32). When you open Control Panel next time a new option will show up: Tweak UI

    C) Double-click Tweak UI and go to General tab. Uncheck "List box animation". This should fix the problem.

    Additional discussion on this on the following EDGE Forum thread on erratic scrolling in Action Diagrams

    For XP systems: An alternative to PowerTools setting exists. Uncheck the option "Smooth-scroll list boxes" found in Control Panel|System Properties|Advanced|Settings

    1. What is the minimum logic to fetch and process all records from a table in a client program? (vs. doing it on the server with a ProcessGroup function). (Plex all versions, Windows Clients)

    Solutions: Following are the Action Diagram statements to acomplish this task.

    Note: This approach was required on a process that had to validate, process, and create an output on the client PC for every record fetched. It is s recommended to accumulate all this logic in a Subroutine or Seq Construct.

    Seq ProcessDBRecords
        Read and fetch all table records
        RowCount is the total nbr of records processed but could be omitted
        Set Control<RowCount> = <RowCount.*Zero>
        Control variable fields used for this process. This is is where fields are initialized.
        Set Control<MoreData> = <MoreData.Yes>
        Set Control<Position> = <Position.Yes>
        Set Control<BufferedRows> = <BufferedRows.*Zero>
        While Control<MoreData> == <MoreData.Yes> OR Control<BufferedRows> >> <BufferedRows.*Zero>
            Set Control<UseRow> = <UseRow.Yes>
            If Control<BufferedRows> >> <BufferedRows.*Zero>
                Use the buffered data
                Set Control<Current> = Control<Current> + <Current.*One>
                Set Control<BufferedRows> = Control<BufferedRows> - <BufferedRows.*One>
                Use Report Files.SLED Disposition Temp.Fetch.BlockFetchDynamicByRPTCde&Usr/FetchedData, Control<Current>

    This is where Processing can be entered for 2nd and remaining records on every call to BlockFetch function.

                Set Control<RowCount> = Control<RowCount> + <RowCount.*One>
            Else
                If Control<MoreData> == <MoreData.Yes>
                    Get more data from the server
                    Call Report Files.SLED Disposition Temp.Fetch.BlockFetchDynamicByRPTCde&Usr
                    Set Control<Position> = <Position.No>
                    Case
                        When Environment<*Call status> IS <State: OBJECTS/*Call status.*Abnormal>
                            Handle Error Conditions
                            +++Set Value Field: OBJECTS/*Message, Message: FIELDS/FunctionCallFailed
                            +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, Environment<*Message ID>
                            Name Function: Report Files.SLED Disposition Temp.Fetch.BlockFetchDynamic, Environment<*Object>
                            Format Message Message: FIELDS/FunctionCallFailed, Environment<*Message text>
                            Go Sub Send message
                            Set Control<MoreData> = <MoreData.No>
                            Set Control<BufferedRows> = <BufferedRows.*Zero>
                            Set Control<UseRow> = <UseRow.No>
                        Otherwise
                            If Environment<*Returned status> IS <State: OBJECTS/*Returned status.*Abnormal>
                                Set Control<MoreData> = <MoreData.No>
                            If data is sucessfully fetched, process records
                            If Control<BufferedRows> != <BufferedRows.*Zero>
                                Set Control<Current> = <Current.*One>
                                Set Control<BufferedRows> = Control<BufferedRows> - <BufferedRows.*One>
                                Set Control<RowCount> = Control<RowCount> + <RowCount.*One>
                                Use Report Files.SLED Disposition Temp.Fetch.BlockFetchDynamicByRPTCde&Usr/FetchedData, Control<Current>

    This is where processing takes places for the first record fetched on every call to BlockFetch function.

                            Else
                                Set Control<UseRow> = <UseRow.No>
                Else
                    Set Control<UseRow> = <UseRow.No>

    Field 'BufferedRows' field can be replaced by FIELDS/RowsFetched to provide a meaningful description of the purpose of this control field.

    1. How can I open a Word document? (Plex 4.5, WinC function)

    Create the following OpenWordDocument Source Code object (Script Engine SYS VBScript)

    'Start Word application
    bExit = True
    Err.Clear
    On Error Resume Next
    Set Word = GetObject(, "Word.Application")
    If Err.Number <> 0 Then
    Err.Clear
    Set Word = CreateObject("Word.Application")
    Else
    bExit = False
    End If

    'Open WORD in invisible mode
    Word.Visible = False
    Set WordApp = Word.Application
    Set WordDoc = Word.Documents.Open(&(1:))

    Where:

    &(1:) = FIELDS/FullPath represents the FullPath +FullFile Name

    1. Two users could access the Group Model at the same time, why? Could this produce an update error? One was extracting when the other one started updating. (Plex all version, Group Model updates)

    Solution: This is normal behavior. One user (the one extracting) only had a READ LOCK on the Group Model which allowed the second user start his UPDATE process.

    Note: Group Model Locks are created whenever a user is logged to read or write data in the Group Model.

    COOL:Plex creates two types of locks:

    a) READ Lock is created while reading the Group Model. This lock does not stop users from logging in to the Group Model for reading purposes therefore multiple EXTRACTIONS can take place simultaneously

    b) WRITE Lock is created when updating the Group model. This lock is EXCLUSIVE and prevents other users from logging in to the Group Model or, if users are already logged in, it stops them from reading the Group Model.

    1. How can I improve the performance of the Action Diagram Parser? Sometime when entering complex expressions this operation takes a long time to complete (Plex 4.5 and previous versions)

    COOL:Plex displays the PARSING dialog box while it is processing action diagram instructions that you have entered. Some instructions may take a long time to process. In these cases, you can cancel the entry and re-specify the instructions in a form that is quicker for the Action Diagrammer to process. The Action Diagrammer assumes that anything contained within the < and > delimiters is complete. When parsing variable-to-variable comparisons, however, it is not possible to use these delimiters, and it is here that performance problems may be encountered. For example, if the variable names in the following instruction appear many times in the Local Model, the instruction should be broken down into nested If statements:

    If Var1 = Var2 AND Var1 = Var3 AND Var1 = Var4

    As a general rule use < and > delimiters wherever possible. In complex expressions, especially those which cannot use the < and > delimiters, keep the number of operands down by nesting one or more nested expressions such as:

    IF Var 1 = Val1 AND Var 1 = Val2 AND Var 1 = Val3

    IF Var 2 = Val1 AND Var 2 = Val2 AND Var 2 = Val3

    ELSE

    To represent Var 1 = Val1 AND Var 1 = Val2 AND Var 1 = Val3 AND Var 2 = Val1 AND Var 2 = Val2 AND Var 2 = Val3

    1. What is the relationship between Plex models objects (panel, function, table, etc.) and the generated Source? (Plex all versions, generation/compilation process)

    The following list displays what kind or source files are generated out of the primary Plex's model objects for Windows, NT, and AS400 implementations:

    • Executable (Function): applies to .EXE files built with the Create Exe command for an external function.

    • Panel: applies to the resource-only DLLs (.PNL files) built when a function scoping a panel is compiled.
    • Topic: applies to the Windows help (.HLP) files created when topic objects are compiled.
    • WinC External Function: applies to the .DLL files created when an external Windows client function is compiled and linked with its internal functions.
    • WinC Internal Function: applies to the intermediate .OBJ files created when you compile an internal Windows client function. The source for the Internal function is embedded in the calling functions so no DLL associated to the internal function is generated.

    For WinC/AS400 Configurations:

    • Table: Generates DDS Source files
    • View: Generates VIW Source files
    • Server External Function: Generates an RPG function.

    FOR NT/Backoffice configurations:

    • WinNTC External Function: applies to the .DLL files created when an external Windows NT server function is compiled and linked with its internal functions.
    • WinNTC Internal Function: applies to the intermediate .OBJ files created when you compile an internal Windows client

    WORKING WITH EXCEL FILES
    1. How can I create an Excel file? (Plex 4.5, WinC client)

    Solution: Create the following 'Create Excel File' Source Code (Script Engine = VBScript) and make an API call to use it:

    Dim objFile, objWorkbook, objWorkbookSheet
    Path = Trim(&(1:))
    set objFile = CreateObject("Excel.Application")
    objFile.Visible = False
    Set objWorkbook = objFile.Workbooks.Open(Path, 1)

    Where:

    &(1:) = FIELDS/FullPath

    Also, other approach is commented on the following EDGE Forums thread:

    http://www.edgeusergroup.org/forums/Thread.cfm?CFApp=82?&&Message_ID=77498&_#Message77498

    More examples on how to work with Excel in PLEX are found in:

    http://caforums.ca.com/ca/attachments/ca/caplexgeneraldiscussion/1251/1/001.005.DoLoadFromExcel.Sample.JPG

    Which is part of the following CA User Forums' Excel to PLEX thread:

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

    1. How can I write to a specific Excel Spreadsheet's Worksheet? (Plex 4.5, WinC client)
    Solution: Create the following "Use Excel Worksheet" Source Code (Script Engine = VBScript) and make an API call to use it:

    Dim WorksheetNum1
    WorksheetNum1 = CInt(&(1:))
    Set objWorkbookSheet = objWorkbook.Worksheets(WorksheetNum1)

    Where:

    &(1:) = FIELDS/Number specifying the Spreadsheet's Workbook sheet number to use

    NOTE: The following EDGE thread deals with related information: Export a grid result to Excel (97)


    1. How can I bypass the ODBC connection popup? I have added the following ODBC Settings values in my application's INI file but this dialog still pops up for the end user to confirm but because this is an automated task no user-intervation is required (Plex 4.5, WinC Client):

      [ODBC Settings]
      SAVE DSN=true
      DSN=MyODBCDSNName
      Userid=sa
      Password= (blank because no password is required)
      Database=MyDBName
      Errorlog=True
      Fetch Type=
      Default Connect=True

    Solution: Set the following value on that section Password = NOT_REQUIRED.

    This is the additional description of the ODBC Settings parameters:

    SAVE DSN. If the DSN or user id in the .INI file is blank, the end user is automatically prompted to enter the required details. If SAVE DSN is set to True, the details entered by the user are written back to the .INI file. If SAVE DSN is set to False (the default), no changes are made to the .INI file.

    Data source name (DSN). The ODBC data source name to be used for connection

    Userid. Any required user ID for database access

    Password. Any required password for database access. If you know that the target DBMS does not require the end-user to logon with a password, enter NOT_REQUIRED for the password value. Otherwise, ODBC will assume that the information was not provided and prompt the end-user for a password during run-time.

    Database. Name of the target database

    Errorlog. The error log setting. When the Errorlog setting = True, it enables error logging to the file ERROR.LOG, which is found in the directory from which the application is run. If not provided, it defaults to False, and error logging is disabled.

    Default Connect. The default setting for this parameter is True. This option allows you to code your own database connections. For example, you may wish to do this in order to use your own encryption routines for passwords and specifying a database to connect to.

    If set to false, the COOL:Plex run-time will not connect to the database. Instead, you will need to use the OBODBC/connect source code object to make the connection.

    Points to note regarding the Default Connect parameter:

    The connection must be executed before the first database access.

    The OBDC run-time remembers the first connection made and uses it for all database accesses. Thus, if you execute the OBODBC/connect Source Code more than once in an application, the second and subsequent executions will have no effect.

    In addition to those values shown in the above sample [ODBC Settings] section, each DBMS may have their own list of required values. Because these values can vary greatly among products, they cannot be added to the [ODBC Settings] section of the application .INI file. If necessary, the ODBC driver prompts end-users for these values during run-time, each time a Connect statement is encountered.

     

    1. Getting "compiler limit : terminating line number emission" warning during compilation. Nno generation warnings/errors and function compiles. (Plex 4.5, WinC client)

    Solution: This is just an informational message that won't have any repercussion in the compiled object other than not being able to edit source with some tools.

    For additional details looks at the following EDGE Forums thread: warning C4049: compiler limit : terminating line number emission.

    Full Message text:.

    Command Lines

    Creating temporary file "C:\Documents and Settings\Lucio\Local Settings\Temp\RSP218.tmp" with contents [ /nologo /MD /W3 /O1 /I "C:\Plex45\LIB\..\INCLUDE" /D "WIN32" /D "_WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /D "OB_WIN_CLIENT" /D "OB_SQL" /D "_WINDLL" /Fp"C:\PLEXDEV\JES\GEN47\WIN32\Release/obj/obwafx.pch" /Yu"obwafx.h" /Fo"C:\PLEXDEV\JES\GEN47\WIN32\Release\obj/" /Fd"C:\PLEXDEV\JES\GEN47\WIN32\Release\obj/" /FD /GD /c "C:\PLEXDEV\JES\GEN47\JE1wtF.CPP" ] Creating command line "cl.exe @"C:\Documents and Settings\Lucio\Local Settings\Temp\RSP218.tmp"" Creating temporary file "C:\Documents and Settings\Lucio\Local Settings\Temp\RSP219.tmp" with contents [ "C:\Plex45\LIB\MFC32C.OBJ" "C:\Plex45\LIB\ob450LC.LIB" "C:\PLEXDEV\JES\GEN47\WIN32\Release\JE47RDD.lib" "C:\Plex45\Class450\Patternlibs\Obpt32.lib" "C:\Plex45\Class450\ClassLibs\obcl32.lib" "c:\Plex45\lib\atol350n.lib" "C:\Plex45\LIB\atol350p.lib" "c:\Plex45\lib\crpe32m.lib" "\\GENPLEX\F\PlexLib\PBASE.lib" "\\GENPLEX\F\PlexLib\CTABLES450.lib" "\\GENPLEX\F\PlexLib\htmlhelp.lib" "\\GENPLEX\F\PlexLib\CRP32D60.LIB" "C:\Program Files\Microsoft Visual Studio\VC98\Lib\WinMM.lib" "\\Genplex\F\PlexLib\pfpro.lib" kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"C:\PLEXDEV\JES\GEN47\WIN32\Release/JE1wtF.pdb" /machine:I386 /nodefaultlib:"libcd.lib" /nodefaultlib:"libcmtd.lib" /nodefaultlib:"msvcrtd.lib" /out:"C:\PLEXDEV\JES\GEN47\WIN32\Release/JE1wtF.dll" /implib:"C:\PLEXDEV\JES\GEN47\WIN32\Release/JE47RDD.imp" /libpath:"C:\Plex45\LIB" "\PLEXDEV\JES\GEN47\WIN32\Release\obj\JE1wtF.obj" "..\WIN32\Release\JE47RDD.lib" ] Creating command line "link.exe @"C:\Documents and Settings\Lucio\Local Settings\Temp\RSP219.tmp""

    Output Window

    Compiling... JE1wtF.CPP C:\PLEXDEV\JES\GEN47\JE1wtF.CPP(65537) : warning C4049: compiler limit : terminating line number emission Linking... Creating library C:\PLEXDEV\JES\GEN47\WIN32\Release/JE47RDD.imp and object C:\PLEXDEV\JES\GEN47\WIN32\Release/JE47RDD.exp Creating temporary file "C:\Documents and Settings\Lucio\Local Settings\Temp\RSP21D.bat" with contents [ @echo off if not exist .\Release md .\Release if not exist .\Release\obj md .\Release\obj copy "C:\PLEXDEV\JES\GEN47\WIN32\Release\obj\JE1wtF.obj" ".\Release\obj" lib /nologo "C:\PLEXDEV\JES\GEN47\WIN32\Release\JE47RDD.lib" ".\Release\obj\JE1wtF.obj" lib /nologo "C:\PLEXDEV\JES\GEN47\WIN32\Release\JE47RDD.lib" /REMOVE:".\Release\obj\JE1wtF.obj" ] Creating command line ""C:\Documents and Settings\Lucio\Local Settings\Temp\RSP21D.bat"" Executing post-build cleanup 1 file(s) copied.
    1. Why can't a file be opened if referenced by a UNC path in a WINNTC server function? (PLEX 4.5, NT Backoffice generator, SQL Server2000)

    Solution: Two approaches have been found to work around this:

    1) Log on the Dispatch service under a named domain account.

    2) Enable Null Session Shares on target file server.

    For more details on this approach check the following EDGE THREAD: Accessing UNC paths in server functions? .

    It is also suggested that you use tools to monitor your system activities such as:

    FILEMON for Windows (FREEWARE). Monitors and displays file system activity on a system in real-time.

    REGMON for Windows (FREEWARE). A System Registry monitoring utility that shows which applications are accessing Registry, which keys they are accessing, and the Registry data that they are reading and writing, all in real-time.

    1. When evaluating values for a field, do I have to enter (or drag from the Variable Palette) values pertaining to that field to be able to enter the statements in the Action Diagram editor? (test with Plex 4.5, Action Diagram editor)

    The short answer is NO. Howerver, for certain conditions where fields in AD's multiple variables' fields contain the desired value, Plex will attemp to provide a list of possible instructions in the Resolve Ambibuous intructions popup.

    Note: Is is also a good technique to use the Resolve Ambiguous instruction popup to accelerate complex statements that take too long to parse into the Action Diagram

    1. What are the meaning of the 3-char codes for the View Status and how are they get set?

    Table of View action diagram statements:

    Action Diagam Statement and purpose

    Sets *View Status to:

    Process related

    Insert

    Creates a row using the current values in the view variable.

    SCS, ERR

    Creating rows

     

    Update

    Updates a row using the current values in the view variable.

    SCS, ERR

    Updating rows

    Delete [keyvariable]

    Deletes the current or specified row.

    RPG/400: If specified, the keyvariable must contain the full key of a row and only one row is deleted.
    SQL: A partial key can be specified, in which case multiple rows can be deleted.

    SCS, ERR

    Deleting rows

    Delete Where variable<character field>
    RPG/400: Not supported.
    SQL: Deletes the rows that meet the specified selection criteria.

    SCS, ERR

    Deleting rows

    Select Where variable<character field> 

    RPG/400: Not supported.
    SQL: Selects the rows that meet the specified selection criteria.

    SCS, INF, ERR

    The Select Where statement

    Position EQ keyvariable [, For Update]

    RPG/400: Moves the file pointer to a specified key value.
    SQL: Selects the set of rows that satisfy the key variable.

    SCS, INF, ILK*, ERR

    Positioning the file pointer in RPG/400 functions (RPG)
    Position EQ/GE/GT in SQL. (SQL)

    Position GE keyvariable [, For Update]

    RPG/400: Moves the file pointer to a specified key value or the next key in sequence.
    SQL: Selects the set of rows that satisfy the key variable.

    SCS, INF, ILK*, ERR

    Positioning the file pointer in RPG/400 functions. (RPG)
    Position EQ/GE/GT in SQL. (SQL)

    Position GT keyvariable [, For Update]

    RPG/400: Moves the file pointer after a specified key value.
    SQL: Selects the set of rows that satisfy the key variable.

    SCS, INF, ILK*, ERR

    Fetch GE/GT/LE/LT (in RPG/400. (RPG)
    Fetch EQ/GE/GT/LE/LT in SQL. (SQL)

    Fetch EQ keyvariable [, For Update]

    RPG/400: Reads a record with a specified key. A full key must be specified.
    SQL: Selects a set of rows and reads the first one. A partial key can bespecified.

    SCS, INF, ILK*, ERR

    Fetch EQ in RPG/400. (RPG)
    Fetch EQ/GE/GT/LE/LT in SQL. (SQL)

    Fetch GE keyvariable [, For Update]

    RPG/400: Reads a record with a specified key or the next record.
    SQL: Selects a set of rows and reads the first one.

    SCS, INF, ILK*, EOV, ERR

    Fetch GE/GT/LE/LT in RPG/400. (RPG)
    Fetch EQ/GE/GT/LE/LT in SQL. (SQL)

    Fetch GT keyvariable [, For Update]

    RPG/400: Reads the next record after a specified key.
    SQL: Selects one or more rows and reads the first one.

    SCS, INF, EOV, ILK*, ERR

    Fetch GE/GT/LE/LT in RPG/400. (RPG)
    Fetch EQ/GE/GT/LE/LT in SQL. (SQL)

    Fetch LE keyvariable [, For Update]

    AS/400: Reads a record with a specified key or the first record before the key.
    SQL: Selects one or more rows and reads the first one.

    SCS, INF, BOV, ILK*, ERR

    Fetch GE/GT/LE/LT in RPG/400. (RPG)
    Fetch EQ/GE/GT/LE/LT in SQL. (SQL)

    Fetch LT keyvariable [, For Update]

    AS/400: Reads the first record before a specified key.
    SQL: Selects one or more rows and reads the first one.

    SCS, INF, BOV, ILK*, ERR

    Fetch GE/GT/LE/LT in RPG/400. (RPG)
    Fetch EQ/GE/GT/LE/LT in SQL. (SQL)

    Exec SQL sourcecode [, viewvariable]

    SQL only: Enables you to use custom SQL SELECT
    statements and other types of SQL statements.

     

    The Exec SQL statement

    FetchNext [keyvariable] [, For Update]

    AS/400: Reads the next row after the file pointer and, optionally, tests whether that row satisfies a partial set of keys.
    SQL: Reads the next row in the currently selected set and, optionally, tests whether that row satisfies a partial set of keys.

    SCS, INF, EOV, ILK* or ERR

    FetchPrev and FetchNext in RPG/400. (RPG)
    FetchNext in SQL. (SQL)

    FetchPrev [keyvariable] [, For Update]

    AS/400: Reads the first record that satisfies a partial set of keys or the record before the file pointer.
    SQL: Not supported.

    SCS, INF, BOV, ILK* or ERR

    FetchPrev and FetchNext in RPG/400. (RPG)

    Release Lock

    AS/400: Unlocks the record after the file pointer.
    SQL: Not applicable.

    SCS or ERR

    Row locking in DB2/400

    Open

    AS/400: Opens the view.
    SQL: Not applicable. Ignored by the generator.

    SCS or ERR

    Opening and closing the view

    Close 

    AS/400: Closes the view once the job ends.
    ODBC: Releases ODBC statement handles.

    SCS or ERR

    Opening and closing the view

    Commit

    Commits database changes.

    SCS or ERR

    Commitment control

    Rollback

    Undoes uncommitted database changes.

    SCS or ERR

    Commitment control

    There are the error codes descriptions: SCS = Successful, ERR = Error, INF = Instance Not Found, ILK = Instance Locked, EOV = End Of View, and BOV = Beginning Of View

    * ILK status applies within RPG/400 functions only.

    1. Error "An error occurred while transferring the source for 'View'sFullQualifiedName'. Check that gen directories are properly shared and that you have correct permissions." during compilation. No generation errors or warning. All properties on view look OK. Plex 4.5a/Win BackOffice generator (SQL Server 2000).
    Solution: File and Implementation Names were the same 32-char string; length was OK for Implementation Name but too long as a File Name. Possible solutions: 1) If you want to keep the File and Implementation Name to be the same, rename to make shorter (28 chars worked). 2) Delete the File Name triple and let Plex generate an appropriate name (implementation name can remain the same 32-char string).
    1. On Plex 4.5a implementation names for WinC functions starting with a number generate an error (like "Cannot locate source file, 'C:\GENPATH\XFUNCTIONNAME.CPP". The X is appended by Plex at compilation time).
    Solution: Change the name to start with an alpha character. Additional info available in on-line help (Chapter 17 /Name Allocation /Configuring the Name Allocation System/Assigning Implementation and File Names Manually). Abstract: C++ names can use all 32 characters, but should not start with a number and should contain no spaces. Allowed characters are A-Z, a-z, 0-9 and the underscore (_). The names are case-sensitive. If the name contains an illegal character, the character will be replaced by an underscore (_) in the generated code (or an "x" if it is the first character). In some cases, this could result in name conflicts. For example, "1abc" and "2abc" will both generate as "xabc". This is also present in Plex 5.0, 5.1, and 5.1SP1.
    1. Error "E-LIC: 7317. Licensing problem. The enterprise license grace period for component 2API, the Advantage Plex tool has expired" when launching Advantage Plex 5.5. Application terminates.
    Solution: A new licensing entry needs to be updated on CA.OLF (entry similar to FEATURE CA_LICENSE CAI_lic_d 1.000 + Code). Contact CA, Licensing Services
    1. Error CPF3C3C "Value for parameter 2 not valid" with Plex 5.5 applications trying to connect to the 400. (login error with application generated with Plex 5.5 and using Client/Access to connect to an i-Series server running OS400 V5R3).

    Solution: This is a known error (CA Solution Fix #QI54937). Problem appears to be related to the incompatibility of the latest version of IBM API QSYSGETHP. Additional information CA provides: A change was needed in V5R3 to the QSYGETPH API to close a security gap. This change has or will hit some customers by surprise. Because of this impact, IBM has a temporary fix, PTF SI14206 which will allow V5R3 code to run under the "old rules". This will be for a limited time, to allow Computer Associates to modify the Plex product to accommodate the new OS changes. If you are experiencing this problem please contact IBM for PTF SI14206.

    After applying IBM PTF SI14206 it is required its 'activation'. This is done by running the following command as a user with privileges:

    CRTMSGQ MSGQ(QSYS/QSYAPI) MSGQFULL(*WRAP)

    Also the following could help reduce job logs:

    CRTDTAARA DTAARA(QSYS/QSYNOMSG) TYPE(*CHAR) LEN(3)

    1. Unable to launch application generated with Plex 5.5 Windows/AS400 generator. Connectivity software: Client Access Express For Windows V4R5. No specific error codes/messages. Just the following popup:

      Solution: Missing GXT file in runtime folder (Plex 5.5 now uses .GXT files –instead of .MAP files- for the ASCII to EBCDIC translations) In addition, also have to comment out the following INI file entry referring to an invalid Code Page value: Code Page=10

    1. A PLex 4.5 Model has been upgraded to Plex 5.5. Statics on panels are covering Labels on Edit Controls or superimposing other statics at runtime. (AllFusion Plex 5.5).
    2. Solution: This seems to be a bug due to the drawing sequence on the panel elements. Work arounds: 1) Define the static as type Group or 2) set the Tab Sequence to be last, after the labels (labels need to also include a Tab Sequence). This attachment shows an example

      NOTE: If multiple Static Types Frames are contained within another one, the top one needs to be defined with Static Type = GROUP.

    1. Problem during compilation of WinNTC server functions. Precompiled header "obrt.pch" gets deleted during job submission and is not recreated. Compilationgenerated the PNL file but DLL is not created. (Plex 5.5, WinNTC compilation).
      Full error: Compiling...

      FncName.cpp

      \old_F_drive\obbuild\patbuild51\patdevlg\FncName.cpp(19) : fatal error C1083: Cannot open precompiled header file: 'C:\old_F_drive\obbuild\patbuild51\patdevlg\gen\Release\obj\obrt.pch': No such file or directory
    2. Solution: Copied to OBJ folder files obrt.pch, _OBCORE.obj, and vc70.idb from other developer's OBJ folder.

    1. How can I locate ATTRIBUTE fields? If I do a search by their name in the Object Browser with the scope on fields it doesn’t show up? (Object Browser on Plex, all versions
    2. Solution: Attributes are scoped to the field that was qualified to create the Attribute. Lookup up for that field on the browser, expand it and find all Attributes under.

      Additional information from Plex’s Help related to Attributes: Attribute (ATR) object type A special type of object that represents those attributes of an entity to which qualifying text has been added (if any). Attribute objects are created and maintained automatically by COOL:Plex. An attribute object is scoped by its field and is named after the qualifier to which it corresponds. If the name of the qualifier changes, the name of the attribute changes automatically. Thus the full name of an attribute object takes the form: field.qualifier If either the field or the qualifier is deleted, the attribute object ceases to exist. Within action diagrams, you utilize attribute objects in exactly the same way as fields. Attributes may be given an implementation name using the ATR impl name NME verb.

    1. Why does the option "Show Local Modifications"in an Action Diagram displays sometimes just the local code (no inherited logic) and other times inherited logic is also displayed? (Plex 5.5)
    2. Solution: This is due to Local Modifications being displayed in Edit Points (Pre or Post Points) that already include inherited code instead of using points with just local modifications. For example: if a function is a UISTYLE/ShowDetail and if the "Pre Point Subroutines" is used (where the Sub Close, Sub Prompt request, Sub Load Detail, etc. are already defined), local modifications will display the local subroutines plus the inherited ones however, if the "Post Point Subroutines" is used showing local modification (CTRL+SFHT+L) will only display that local code, making the scrolling to read local code easier.

    1. Error “Protocol not supported” when launching a Selector function (Plex 5.5)
    2. Solution: A WinC function in a WinNT BackOffice application had been compiled with host Model in 400 variant therefore server functions looked were type RPG and when deployed they could not be found. Changed HOST model to Base and recreated. Function called WinNTC server functions successfully


    WORKING WITH PC FOLDERS, DIRECTORIES, AND PATHS
    1. How can I add a file extension to a fully qualified path that includes a file location and name?:

      Solution: Create the following "AddFileExtension" Source Code and make an API CALL to it:
      #include <atlpath.h>
      {
      // Source Code created using ATL Server Library Reference|Utilities Reference. ATL Server provides code for manipulating paths and URLs in the form of CPathT and CUrl. Per MSDN "A thread pool, CThreadPool, is used in the implementation of the ATL Server ISAPI extension class and can also be used in your own applications. This code can be found in atlpath.h and atlutil.h"
      // Adds a specified file extension to the provided Full Path (Path + File Name) if one doesn't exist.
      CPath WorkPath(&(2:));
      &(1:) = WorkPath.AddExtension(&(3:));
      &(2:) = WorkPath.m_strPath;
      }

      Where:
      &(1:)=ReturnStatus (Numeric)
      &(2:)=FullPath (Path + File Name, i.e. Char, 1024)
      &(3:)=FileExtension (Char such as .EXE, .DLL, etc.)

    2. How can I get the file extension of a fully qualified path that includes a file location and name?

      Solution: Create the following "GetFileExtension" Source Code and make an API CALL to it:
      #include <atlpath.h>
      {
      // Source Code created using ATL Server Library Reference|Utilities Reference. ATL Server provides code for manipulating paths and URLs in the form of CPathT and CUrl. Per MSDN "A thread pool, CThreadPool, is used in the implementation of the ATL Server ISAPI extension class and can also be used in your own applications. This code can be found in atlpath.h and atlutil.h"
      // Retrieve the file extension for a given Full Path (Path + File Name), if one exists.
      CPath WorkPath(&(1:));
      &(2:) = WorkPath.GetExtension();
      }

      Where:
      &(1:)=FullPath (Path + File Name, i.e. Char, 1024)
      &(2:)=FileExtension (Char such as .EXE, .DLL, etc.)

    3. How can I get the file name on a fully qualified path that includes a file location and name?

      Solution: Create the following "GetFileNameFromFullPath" Source Code and make an API CALL to it:
      #include <atlpath.h>
      {
      // Source Code created using ATL Server Library Reference|Utilities Reference. ATL Server provides code for manipulating paths and URLs in the form of CPathT and CUrl. Per MSDN "A thread pool, CThreadPool, is used in the implementation of the ATL Server ISAPI extension class and can also be used in your own applications. This code can be found in atlpath.h and atlutil.h"
      // Retrieve the File Name from a provided Full Path (Path + File Name)
      CPath WorkPath(&(1:));
      WorkPath.StripPath();
      &(2:) = (CString) WorkPath;
      }

      Where:
      &(1:)=FullPath (Path + File Name, i.e. Char, 1024)
      &(2:)=FileName (i.e. Char, 1024)

    4. How can I get the path portion of a fully qualified path that includes the File Location Name?
    5. Solution: Create the following "GetPathFromFullPath" Source Code and make an API CALL to it:
      #include <atlpath.h>
      {
      // Source Code created using ATL Server Library Reference|Utilities Reference. ATL Server provides code for manipulating paths and URLs in the form of CPathT and CUrl. Per MSDN "A thread pool, CThreadPool, is used in the implementation of the ATL Server ISAPI extension class and can also be used in your own applications. This code can be found in atlpath.h and atlutil.h"
      // Retrieve the Path Portion from a provided Full Path (Path + File Name)

      CPath WorkPath(&(2:));
      &(1:) = Work.RemoveFileSpec();
      &(3:) = (CString) WorkPath;
      }

      Where:
      &(1:)=ReturnStatus (Numeric)
      &(2:)=InputFullPath (Path + File Name, i.e. Char, 1024)
      &(3:)=OutputPath (Path + File Name, i.e. Char, 1024)

    6. How can I determine whether a path is a directory or not? (includes a file name or not).

      Solution: Create the following "CheckIfPathIsADirectory" Source Code and make and API CALL to it:
      {
      // Checks if the path is a directory or not

      &(1:) = PathIsDirectory(&(2:));
      }


      Where:
      &(1:)=ReturnValue (Boolean)
      &(2:)=InputPath (i.e. Char, 1024)

      A related checkup would be whether the Path is formed with Universal Naming Conventions (UNC):

      "CheckIfPathIsUNC" Source Code:

      {
      // Checks if the path is formed with UNC (\\...)

      &(1:) = PathIsUNC(&(2:));
      }


      Where:
      &(1:)=ReturnValue (Boolean)
      &(2:)=InputPath (i.e. Char, 1024)

      Another common checking is to determine whether a path is a Uniform Resource Location:

      {

      &(1:) = PathIsURL(&(2:).strGetText());

      }

      Where:

      &(1:) = OBWIN/Boolean

      &(2:) = FIELDS/URL

      Note on PathIsDirectory (10/08/07):

      From Microsoft Developer Network (http://msdn2.microsoft.com/en-us/library/ms628575.aspx): "The return value isn't really TRUE (1) when the path is a valid directory but FILE_ATTRIBUTE_DIRECTORY (16). So tests like, if return value is equal to TRUE, wont work" therefore define validation of returned status based on the FALSE value

    136B. How can I determine if a windows folder/directory contains any file? How can I check if it contains specific file types?:

    Solution: Create the following Source Code object and make an API Call to it specifying the required parameters:

    Source Code 'Find Files of Specified Type':

    CString szFolder = CString(&(1:));

    szFolder.TrimRight();

    CString szFilter = CString( &(2:) );

    szFilter.TrimRight();

    CString szSource = szFolder + CString("\\") + szFilter;

    // Check every file in the directory

    CFileFind ffSource;

    int nRet = ffSource.FindFile( szSource );

    if ( nRet == 0 ) {

    &(3:) = ObCharFld( "ERR" );

    }

    else {

    &(3:) = ObCharFld( " " );

    }

    Where:

    &(1:) = Source Path (FIELDS/FullPath)

    &(2:) = File Filter (FIELDS/FullPath). Possible values: DLL Files = *.DLL, Word Files = *.DOC, XML Files = *.XML, No extension = *., All Files = *.*, or PDF FIles = *.PDF

    &(3:) = *Returned Status. Possible values: Successful ( ) if files are found or Error (*ERR) if not found

    136C. How can I get a list of all the files found in a Windows Folder/Directory?

    Solution: Create the following Source Code object and make an API Call to it specifying the required parameters:

    Source Code 'Retrieve File Names In Path'

    // Initialize the field that will contain File Name

    CString szFile;

    // Check for the next file in the specified Path

    int nRet = ffSource.FindNextFile();

    szFile = ffSource.GetFilePath();

    // Assign the full path (Path+FileName+Extension)

    &(1:) = ObCharFld( szFile );

    // Validate the return info

    if ( nRet==0 ) {

    if (GetLastError() != ERROR_NO_MORE_FILES)

    &(2:) = ObCharFld( "ERR"); // Error retrieving next file

    else

    &(2:) = ObCharFld( "EOV"); // Last file to be copied

    }

    else {

    &(2:) = ObCharFld( " ");

    }

    Where:

    &(1:) = Source Path (FIELDS/FullPath). Initially pass the source path without a File Name

    &(2:) = *Returned Status

    136D. How can I add functionality to panel to allow browsing for a PC Folder?

    Solution: Send me an email to request the document that includes the process to implement a function with functionality to browse for a PC Folder (PROCEDURE TO IMPLEMENT A DIALOG FOR PC FOLDER BROWSING.zip)

    1. How can I validate that a string is a Windows Path?
    2. Solution: create the following Source Code (script engine VBScript) and make an API call to it:

      'This Source Code utilizes the FileSystemObject

      ' Create the Windows Folder if necessary

      Set fso = CreateObject("Scripting.FileSystemObject")

      szNewPath = &(1:)

      If (fso.FolderExists( szNewPath )) Then

      'Do nothing as the provided path was found

      Else

      fso.CreateFolder( szNewPath )

      End If

      Where (1&:) = Fields/FullPath

      Alternatively you can create the following Source Code which does not require a client function scoping a panel as it is C++ and not VBScript:

      {

      CFileFind ffDir;

      int nRes = ffDir.FindFile( &(1:) );

      if ( nRes==0 ) {

      _mkdir( &(1:) );

      }

      }


    3. How can I reply AS400 (iSeries) server messages that require a response? A Plex function calls a 400 process that issues a Message that requires a reply to complete processing.
    4. Solution: In the 400 Command Line type WRKACTJOB (Work with Active Jobs), look for your job and enter Option 7 (Display Message) next to it. This will display a window where the message is displayed and a command line to enter the reponse.

    5. Error retrieved on WinNTC server function "Location 'RMT_LOC: ' not valid or not found. Please review settings and try again"
    6. Solution: The program was attempting a call to a client function. WinNTC server programs cannot call WinC clients. Replaced the client function by a server version.

    7. An error occurs during bulding of WinNT View but view does not exist in the target DB. Error (Message Details: BLD1863 Error Message: "An error occured while deleting database object for 'ObjectName'"). An LST file with the object name gets created in the remote server's compilation folder with message "Could not open connection to database". WinNT Back Officer Generator.
    8. Solution: NT Configuration|NT ODBC Connection information was incorrect. In this case it was the DB Password.

    9. Received the following error launching Plex: "E-LIC: 7317. Licensing problem. The enterprise license grace period for component 2API, the Advantage Plex tool has expired" when launching Advantage Plex 5.5. Application terminates.
    10. Solution: A new licensing entry needs to be updated on CA.OLF (entry similar to FEATURE CA_LICENSE CAI_lic_d 1.000 + Code). Contact CA, Licensing Services

    11. Error: An external C++ client issued error "The procedure entry point ??0ObFixedDecImpl@@QAE@J@Z could not be located in the dynamic link library ob550lc.dll" when calling another client function (clients created with Plex 5.5)
    12. Solution: A Plex run-time used by dynamic link library ob550lc.dll had been deployed. Error fixed by ensuring latest Plex runtimes had been deployed.

    13. How can I convert a 7-char string time to ISO format?
    14. Solution: Substring the Hour & Minute time components to form a structured time then convert to ISO. See the following document (due to space limitations file is not hosted. Send me an email to request the CONVERT 7-CHAR STRING TIME TO ISO.zip file)

    15. Received the error "error C2601: 'ObSbr_JEo3gF87' : local function definitions are illegal" during compilation of WinC clients
    16. Solution: Error was caused by a second stage of inheritance where the parent function included references to invalid fields. As in this case the grand child function was as close to the grand parent's functionality as the parent's functionality, changed inheritance to defined GrandChild IS A GrandParent and compilation errors were corrected

    17. Why are some Panel Editor changes not version dependent? A function' panel layout was modified in one version which affected all other versions.
    18. Solution: Eventhough the Panel object is version dependent not all elements on it are tracked per version therefore certain changes will affect all versions/levels.

      From Plex online help on Level considerations: "In general, every change you make to a panel is level-dependent. Certain exceptions are described in Changing the ownership of menu items and other panel elements"

      The elements that are not level dependent are those whose ownership is not recorded by triples such as:

    • Moving a toolbar button from one toolbar to another.
    • Moving separators from one menu or toolbar to another.
    • Moving a push button, standalone ActiveX control or static control from one region to another.
    1. How can I use a SQL statement to do a string replacement of a database field?
    2. Solution: Create a Plex function with an EXEC SQL statement that updates the database with the results of a REPLACE(FieldName, 'SourceString', 'ReplacementString') statement.

      Example:

      The following script identifies broken records in an iSeries (400) field where a string representing a fully qualified path was created with an incorrect extension PDF instead of TIFF

      select * from LIBRARY/FILE where IMGPATH like '%SOURCEPATH%' and IMGPATH like '%.PDF%'

      Where:

      SOURCEPATH is the beginning portion of the fully qualified path for the broken data such as \\\\Servername\FilesDirectory\Subfolder

      IMGPATH is the field that contains the fully qualified path

      Once records are identified, modify this script to perform a database UPDATE such as:

      UPDATE LIBRARY/FILE SET IMGPATH = replace(IMGPATH, 'PDF', 'TIF')

      where IMGPATH like '%SOURCEPATH%' and IMGPATH like '%.PDF%'

    3. How can I create a Single Fetch function that is not affected by case-sensitivity of the lookup data? I have a process that depends on finding a record by a combination of a Name Field and Date. The process fails in finding existing records because the Field Name is writen in mixed case (such as Smith, Perez, etc.) and the looked up values passed are all upper (such as SMITH, PEREZ), etc. This failing Single Fetch needs to be implemented in both Windows NT and iSeries servers (Plex 5.5).
    4. Solution: This approach involves Source Codes that are platform independent (NT and iSeries platforms currently supported) and are executed on the server. Send me an email to request the file InstructionsToDefineACaseInsensitiveSingleFetch.zip with details on how to accomplish this.

    5. What object changes are tracked across all versions, levels, and variants? Which ones are only tracked for the current version and variant? An application has been created for NT and AS400 variants and would like to know which changes on the Action Diagrams will remain constant for all configurations
    6. Solution: Check the following table (retrieved from Plex’s Online Help) to determine what changes are scoped for (only dependent on) the current Versions/Levels/Variants/National Languages:

       

      Version/level?

      Variant?

      National language?

      Notes

      Object names, permissions, and flags

      No

      No

      No

      Object names and permissions are the same across all configurations. See also National language-dependent triples.

      Object and large property deletion

      No

      No

      No

      When you delete an object or large property, it is deleted across all configurations.

      Object narrative

      Yes

      Yes

      Yes

       

      Object scope

      No

      No

      No

      When you change the scope of an object, it changes across all configurations.

      Triples

      Yes

      Partial

      Partial

      Only certain verbs are variant and language dependent. When you select a triple in the Model Editor, its configuration is displayed in the Status Bar.

      Triple sequence

      Yes

      No

      No

      Prior to version 3.0 of Advantage Plex, triple sequence was not tracked by level.

      Diagram large property (LP)

      Yes

      Yes

      Yes

      The presence of nodes and links and their layout are configured.

      Action diagrams

      Yes

      See notes

      See notes

      Each individual component is configured by level. Special action diagram processing is required for variant and national language configuration.

      Panel LP

      Yes

      Partial

      Partial

      Each individual element and its properties are configured. Only certain properties are variant and national language dependent. Certain changes are not configuration dependent as described in Changing the ownership of menu items and other panel elements.

      Report LP

      Yes

      Partial

      Partial

      Each individual element and its properties are configured.

      Message LP

      Yes

      Yes

      Yes

       

      Source code LP

      Yes

      Yes

      Yes

       

      Label LP

      Yes

      Yes

      Yes

       

      Value LP

      Yes

      Yes

      No

       

      Help topic LP

      Yes

      Yes

      Yes

       

      Generated source and objects

      Yes

      Yes

      Yes

      You can use different build directories to maintain the source and objects for each configuration.

      Limitations
      The configuration control system does not track the existence, name, and scope of objects. This means that you need to take care when, for example, deleting an object that has been used across multiple levels – the object is removed from all of them.

      When you delete an object, all triples pointing to or from the object are also deleted, together with any other objects that it scopes. Advantage Plex performs some validation to determine whether you have authority to the levels in which these triples exist and whether you have permission to the objects. You are prevented from deleting the object if you do not have permission or authority.

      Note: This validation does not extend to large properties. For example, when you delete a function, Advantage Plex does not check whether its action diagram contains statements entered at levels to which you do not have authority. This is because the configuration information about the action diagram is stored inside the large property and is not available to the deletion mechanism. This same limitation applies when you delete a large property using the Delete Large property command on the Tools menu of the Object Browser.

    7. How can I create a function that launches a URL in the system's default Internet Browser?
    8. Solution: Create a VBScript Source Code with the code below an make an API Call to it. For an entire description including an example see the attached document (due to space limitations file is not hosted. Send me an email to request the Launch default browser with URL.zip file)

      set oShell = CreateObject("WScript.Shell")
      oShell.Run &(1:)

      Where:

      &(1:) = URL

    9. How can I concatenate multiple component fields to form a single string where each component field is separated by a single space? If a Format Message is used (i.e. &(1:) &(2:) &(3)...) more than 1 space is found among field components when some of these are blank.
    10. Solution: Create the following Source Code object (Script Engine = VBScript) where each individual input field is trimmed then added a single space if it contains a value. Finally, the output is returned in one of the input fields for consumption by the calling function. This example forms a Street Name formed by the concatenation of up to 5 fields (street number, street prefix, street name, street type, street suffix) and the returned concatenated string is VL Street Name:

      StreetNumber = trim(&(1:))

      StreetPrefix = trim(&(2:))

      StreetName = trim(&(3:))

      StreetType = trim(&(4:))

      StreetSuffix = trim(&(5:))

      ' Append space to non-blank fields

      If StreetNumber > " " Then

      StreetNumber = StreetNumber + " "

      else

      StreetNumber = StreetNumber

      end if

      if StreetPrefix > " " Then

      StreetPrefix = StreetPrefix + " "

      else

      StreetPrefix = StreetPrefix

      end if

      if StreetName > " " Then

      StreetName = StreetName + " "

      else

      StreetName = StreetName + " "

      end if

      if StreetType > " " Then

      StreetType = StreetType + " "

      else

      StreetType = StreetType

      end if

      if StreetSuffix > " " Then

      StreetSuffix = StreetSuffix + " "

      else

      StreetSuffix = StreetSuffix

      end if

      ' Concatenate all fields

      ConcatenatedStreetName = StreetNumber + StreetPrefix + StreetName + StreetType + StreetSuffix

      &(3:) = ConcatenatedStreetName

    11. The Model Editor does not display any triple for any object in the Model. The objects have not been deleted and they display correctl on the object browser

      Solution: The Model editor entry in the ini file was changed where the Verb Group would not display a value. Following are the incorrect and correct settings to display triples correctly:

      Failing PC:

      [ModelEditor]

      Verb group=-1
      Insert=0
      ShowLevel=1
      ShowStop=1
      ShowCont=1
      Focus=2,3,15,10,18,4,22,6,32,1,11
      Red=ff
      Green=8000
      Blue=ff0000
      show_options=1
      header_cent=Model Editor
      footer_cent=Page : $P
      header_left=Model: $N
      footer_left=
      header_right=$D
      footer_right=
      Tabs options=50
      Tabs report=70, 110
      Pad chars=----
      Top=10
      Right=15
      Bottom=10

      Working settings:

      [ModelEditor]

      Verb group=0
      Insert=0
      ShowLevel=0
      ShowStop=0
      ShowCont=1
      Focus=2,3,15,10,18,4,22,6,32,1,11
      Red=ff
      Green=8000
      Blue=ff0000
      show_options=1
      header_cent=Model Editor
      footer_cent=Page : $P
      header_left=Model: $N
      footer_left=
      header_right=$D
      footer_right=
      Tabs options=50
      Tabs report=70, 110
      Pad chars=----
      Top=10
      Right=15
      Bottom=10

    12. 400 Server compilations fails with error 'Cannot allocate remote conversation. (Reason: errror Sending Data 10053)'

      Solution: Stop/start the YOBLISTENER (WRKACTJOB) if its already running as it was the case when this issue was found.

    13. How can I format a string with either filling leading zeroes or filling trailing blanks? For example, for a string length 5 (ABCDE) I would like to format to either fill with leading zeroes (00000ABCDE) or trailing blanks (ABCDE ) depending on validation criteria

      Solution: Create the following two Source Codes:

      1) FormatFieldToFixedLengthWLead0

      {

      CString szOrig;

      int nLen = &(2:) - &(3:).GetLength();

      szOrig.Format( "%0*s%s", nLen, &(1:).pszGetText() , &(3:).pszGetText());

      &(3:) = ObCharFld( szOrig );

      }

      Where:

      &(1:) = WRK_Char 200 (Char, 200)

      &(2:) = StringLength (NUmeric, 4, 0)

      &(3:) = WRK_Output Char 200 (Char, 200)

      %0*s%s = Formatting specification. An integer placed between a '%' sign and the format command 's', in this case nLen, acts as a minimum field width specifier and pads the output with spaces or zeros to make it long enough. To pad with zeros a zero has been placed before the minimum field width specifier

      2) Format Field to Fixed Length

      {

      CString szOrig;

      int nLen = &(2:) - &(3:).GetLength() + &(1:).GetLength();

      szOrig.Format( "%s%*s", &(3:).pszGetText(), nLen, &(1:).pszGetText() );

      &(3:) = ObCharFld( szOrig );

      }

      Where:

      &(1:) = WRK_Char 200 (Char, 200)

      &(2:) = StringLength (NUmeric, 4, 0)

      &(3:) = WRK_Output Char 200 (Char, 200)

      %s%*s = Formatting specification. An integer placed between a '%' sign and the format command 's', in this case nLen, acts as a minimum field width specifier and pads the output with spaces or zeros to make it long enough. To pad with spaces (blanks) only the character '*' is used before the minimum field width specifier

      In your Action Diagram, depending on your validation, make an API Call to either the 1st or 2nd Source Code to format and pad the required field which is processed in (&3:). &(2:) is passed the maximum length for the field and &(1:) is a delimiter that is placed between the padding characters and the strings. In the implementation of these Source Codes, the delimiter was set to match either a 0 when padding with 0s or ' ' when padding with spaces.

    14. Compilation fails with error "COMPILE : error C2601: 'ObSbr_JEo3gF87' : local function definitions are illegal"
    15. Solution: Error was caused by a second stage of inheritance where the parent function included references to invalid fields. As in this case the grand child function was as close to the grand parent's functionality as the parent's functionality, changed inheritance to defined GrandChild IS A GrandParent and compilation errors were corrected.

    16. Compilation fails for a WinC client with error: "COMPILE : error RC2135 : file not found: M:/obsy/bitmaps/case.ico". The path M:/obsy/bitmaps used is not the one defined in System Definitions | System Properties | Resource Directories and no visible button on the panel includes such reference.
    17. Solution: The Panel’s 'Icon File' property included an icon that was referenced with this incorrect path instead of just including the ICO file name. Removed the path and recompiled successfully as the Gen & Build Options for the Resource Directories is now read.

    18. For a Windows/ODBC application, a Panel pops up at runtime with the message" Location 'RemoteWinNT' not valid or not found. Please review settings and try again.
    19. Solution: A client WinC was calling a server that had been generated with an incorrect WinNT/Backoffice variant, instead of Windows/ODBC, therefore such server looked for a non-existing NT Server

    20. A WinC client function fails during compilation with error 'Internal Check Failed: Line 508 of .\Src\Gen\Wcppgen\Stat_gen.cpp Please contact Computer Associates, Inc. product support with the above information'. No generation errors encountered (PLEX 5.5 SP1)
    21. Solution: An event on the Panel Designer had been set to Exist = NO but its associated logic in the Action Diagram was still present. Resolved by leaving the event on the panel (set back to Exist = YES) and disassociating the physical event on the panel elements that triggered such logical event.

    22. A WinNTC function fails to perform a SQL Script via an Exec SQL statement. This function works correctly in a different database that contains similar data but in the current DB the function returns a *view Status = ERR. The structure of the Source Code object, use to clear data in a group of tables, is:

      truncate table owner.Table1ImplementationName

      truncate table owner.Table2ImplementationName

      truncate table owner.Table3ImplementationName

      truncate table owner.Table4ImplementationName

      truncate table owner.Table5ImplementationName

      Solution: The problem was caused by a missing file in the list of files accessed by the SQL logic which caused the entire SQL Source Code to fail with the reported *view error. Two solutions:

      1) Ensure all tables accessed by the SQL Statements exist before executing this Source Code

      2) Split into multiple SQL Source Codes so if one or more tables is not found, the other SQL Source Codes will still execute correctly.

      3) TRUNCATE TABLE will fail on files that include a Foreign Key constraint (FK). In such instances transform the statement to use DELETE FROM i.e. delete from owner.Table1ImplementationName

    23. An external RPGIV server function used to retrieve the User ID for the current connection is returning a generic user ID (i.e. GENERIC) instead of the current user (i.e. USERNAME). This function was designed years ago and makes use of the Source Code 'OBAS400/Get AS400 User ID' to retrieve the current user. This stopped working once we migrated to r6.1 (Build 43.012) from AllFusion Plex r6.0 (Build 47.030)

      Solution: Resolved issue following CA's recommendation to replace the use of OBAS400/Get AS400 User ID Source Code to the 400 Function AS400/GetJobIdentifierprogram.

      The external API AS400/GetJobIdentifier calls the function YOBRTVJOBC in the PLEX610 library to retrieve the qualified job identifier of a server job. The function outputs the parameters: Output OBJECTS /*Returned Status, Output OBJECTS/Job Number, Output OBJECTS/User ID, and Output OBJECTS/Job Name

    24. How can I move a 400 RPG From Library to Library in the iSeries Server?

      Solution: Use the Move Object (MOVOBJ) command in the command line. I.E.

      MOVOBJ OBJ(A/TEST) OBJTYPE(*PGM) TOLIB(B)

      moves the RPG function TEST from Library A to B

    25. A Get statement in a panel's InputP region fails to read the values entered.

      Solution: The panel had been updated to include multiple regions and fields and for some unknown reason the DetailP region was not being 'read'. Deleted (removed on the Panel Editor) the fields within the DetailP variable and re-introduced them. After doing this, the GET statement successfully read the values from the panel.


    26.  
       
       

    Do you have any problem/solution you would like to share? Send me an email 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).

    If you need assistance developing or managing your projects don't hesitate to call me. I provide independent hourly consulting at a very competitive cost.


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


     


    You are visitor

    Email: l_gayosso@hotmail.com



    Home



    Background music: Tangerine Dream's "Poland" (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...