PrevPrev Go to previous topic
NextNext Go to next topic
Last Post 02/24/2017 12:47 PM by  jaherb
User Exit Eamples--
 9 Replies
Sort:
You are not authorized to post a reply.
Author Messages
tambrosi
Enterprise System Analysis
Private
Advanced Member
(97 points)
Advanced Member
Posts:45


Send Message:

--
03/11/2015 9:41 AM

     

    Hello,  I am very, very new to the Lawson software, and was asked to look at the user exit process.  I was wondering if somebody would be willing to share a simple user exit program.   I have been going thru the doc's and any posts or all information I can find.  But an example would go along way.

    I am not real sure of the naming convention that needs to be followed and if the user exit needs to be defined in the source lib or the obj lib.  I think the obj lib is for the executable.   

    IE:  I am looking at pgm CU01,,   would it be named CU01EPD and CU01EWS (invoke exit at end) and would they be defined in the syscode SRC lib.   IFSRC in this case.  

    Any help would be appreciated. 

    Thanks

     

     

    Matt Daniels
    Application System Administrator
    Memorial Health System
    Basic Member
    (38 points)
    Basic Member
    Posts:14


    Send Message:

    --
    03/11/2015 10:45 AM
    Your naming convention is correct and I've never added them to the SRC lib, but I have only done this once before. You will need to create the directory $LAWDIR//usrobj if it does not already exist. Then you will need to compile the user exit and the program itself.

    For user exit and the program code will contain the exit letter for instance cu01e
    qcompile -u Productline SystemCode ProgramCode

    For program
    qcompile Productline SystemCode ProgramCode

    Hope this helps. This is on Unix. Windows may be slightly different.

    Cheers,
    Matt
    jaherb
    Private
    Private
    Veteran Member
    (471 points)
    Veteran Member
    Posts:163


    Send Message:

    --
    03/11/2015 10:46 AM
    User Exits are routines called from an on-line program. You have a BEGIN, MID & END user exits. In the example you gave, that would be an END user-exit and would be executed after the form had process the data and just before the data is refreshed back onto the form. Depending on what you want to do, you would have to decide which user exit to use.

    Once coded, you would then need to compile the program using the -u option to create the executable object.

    Lawson has specific places in a generated program that will check to see if there is an user exit existing and will flag it for execution. If you do a bldsh on your program you can look through there and see where it is checking for a user exit routine and subsequently executing it if there is one.

     

    the following is some documentation I placed together and a sample of one I did for the AP20 program

     

     

    USER EXITS

     

     

    Lawson User Exits are only available in on-line programs.
    Every on-line program tries to call a Begin, Middle and End User Exit.  If one if found, a flag will be set that one does exist.

     

    004788     CALL "OPENDBVIEW" USING PRSFD-HANDLE,

    004789                             WS-DB-PRODUCT-LINE,

    004790                             PRSFD-FILENAME,

    004791                             PRSFD-DATESTAMP,

    004792                             PRSFD-FLDS.

    004793

    004794

    004795     CALL "BegUsrExitExists" USING CRT-PROGRAM-CODE,

    004796                                   WS-BEG-UE-PGM,

    004797                                   WS-BEG-UE-FOUND.

    004798     CALL "MidUsrExitExists" USING CRT-PROGRAM-CODE,

    004799                                   WS-MID-UE-PGM,

    004800                                   WS-MID-UE-FOUND.

    004801     CALL "EndUsrExitExists" USING CRT-PROGRAM-CODE,

    004802                                   WS-END-UE-PGM,

    004803                                   WS-END-UE-FOUND.

    004804

    004805     MOVE CRT-ONE                TO CRT-FIELD-NBR.

    004806     PERFORM 700-GET-TRANSACTION.

    004807     PERFORM PROCESS-TRANSACTION

    004808         UNTIL END-OF-PROGRAM.

    004809

    .

    .

    .


    At pre-determined points in the on-line program, the User Exit flag is checked and if one does exist, that logic will be executed.

     

    004816******************************************************************

    004817 PROCESS-TRANSACTION             SECTION.

    004818******************************************************************

    004819 PROC-TRANS.

    004820

    004821     IF (WS-BEG-UE-FOUND = "Y")

    004822         MOVE CRT-PROGRAM-CODE TO CRT-SV-PROGRAM-CODE

    004823         CALL WS-BEG-UE-PGM USING CRT-CONTROL,

    004824                                  CRT-TRANSACTION

    004825         MOVE CRT-SV-PROGRAM-CODE TO CRT-PROGRAM-CODE

    004826         IF (ERROR-FOUND)

    004827             GO TO SP-CONTINUE.

    004828     SET EMSTATUS-NOTFOUND TO TRUE.

    004829     INITIALIZE EMSTATUS.

    004830     SET INSTCTRYCD-NOTFOUND TO TRUE.

    004831     INITIALIZE INSTCTRYCD.

    004832     SET PRSYSTEM-NOTFOUND TO TRUE.

    .

    .

    004848 SP-CONTINUE.

    004849

    004850     IF  (NO-ERROR-FOUND)

    004851     AND (WS-END-UE-FOUND = "Y")

    004852         MOVE CRT-PROGRAM-CODE TO CRT-SV-PROGRAM-CODE

    004853         CALL WS-END-UE-PGM USING CRT-CONTROL,

    004854                                  CRT-TRANSACTION

    004855         MOVE CRT-SV-PROGRAM-CODE TO CRT-PROGRAM-CODE.

    004856

    004857     CALL "CloseDBCursors".

    004858

    004859     PERFORM 700-GET-TRANSACTION.

    .

    .

    .

    008290******************************************************************

    008291 400-PROCESS-TRAN.

    008292******************************************************************

    008293

    008294     IF (WS-MID-UE-FOUND = "Y")

    008295         MOVE CRT-PROGRAM-CODE TO CRT-SV-PROGRAM-CODE

    008296         CALL WS-MID-UE-PGM USING CRT-CONTROL

    008297                                  CRT-TRANSACTION

    008298         MOVE CRT-SV-PROGRAM-CODE TO CRT-PROGRAM-CODE.

    008299

    008300     IF (HR03F1-FC = "A")

    008301         PERFORM 410-ADD

    008302         THRU    410-END

    008303     ELSE

    008304     IF (HR03F1-FC = "C")

    008305         PERFORM 420-CHANGE

    .

    .

    .

    UE Logic

    Depending on the type of UE being coded, you must set up a PD & WS in the application source lib.  A “Begin UE” will have the logic coded in a member called XX##BPD and the working storage will be XX##BWS.  Both the PD and WS must contain sections for all the sub-forms associated with the program.

    For example, the AP20 program has forms AP20.1, AP20.2, AP20.3 through AP20.9. 

    Naming Conventions

    Type                    PD                    WS

    BEGIN-UE              AP20BPD               AP20BWS

    MIDDLE-UE             AP20MPD               AP20MWS

    END-UE                AP20EPD               AP20EWS

     

    In the example here, I have added “begin UE” logic for the AP20.2 form, but still must account for the other forms although there is no new logic for these other forms.

    AP20BPD

    JH1004*****************************************************************

    JH1004 AP20BS1-TRANSACTION             SECTION.

    JH1004*****************************************************************

    JH1004 AP20BS1-START.

    JH1004*

    JH1004*

    JH1004 AP20BS1-TRANSACTION-END.

    JH1004*****************************************************************

    JH1004 AP20BS2-TRANSACTION             SECTION.

    JH1004*****************************************************************

    JH1004 AP20BS2-START.

    JH1004*

    JH1004*  THIS CUSTOM USER EXIT WILL MOVE THE VENDOR VALUE ON THE MAIN

    JH1004*  TAB TO THE PAY VENDOR VALUE ON THE OPTIONS TAB. THIS WILL

    JH1004*  KEEP THE TWO VENDOR VALUES THE SAME.

    JH1004*

    JH1004     MOVE AP20F2-API-VENDOR      TO AP20F2-API-PAY-VENDOR.

    JH0920*

    JH0920*  THIS CUSTOM USER EXIT WILL CHECK THE VENDOR LOCATION TABLE

    JH0920*  FOR THE "REMIT-TO-CODE" PROVIDED ON THE "MAIN" TAB.  ACCESSING

    JH0920*  THE VENDOR LOCATION FOR THAT CODE IT WILL RETURN THE BANK-

    JH0920*  INST-CODE TO THE "PAYMENT & OPTIONS" TAB ALONG WITH THE CASH-

    JH0920*  CODE.  IF THE BANK-INST-CODE IS BLANK, IT WILL THEN READ THE

    JH0920*  APVENMAST TABLE TO PULL IN THE VENDOR SETUP CODES.

    JH0920*

    JH0920     MOVE "XXXX"                   TO DB-VENDOR-GROUP.

    JH0920     MOVE AP20F2-API-VENDOR        TO DB-VENDOR.

    JH0920     MOVE AP20F2-API-REMIT-TO-CODE TO DB-LOCATION-CODE.

    JH0920     PERFORM 840-FIND-VLOSET1.

    JH0920     IF (APVENLOC-FOUND)

    JH0920         MOVE VLO-BANK-INST-CODE   TO AP20F2-APP-BANK-INST-CODE

    JH0920                                      AP20F2-API-BANK-INST-CODE

    JH0920         MOVE VLO-CASH-CODE        TO AP20F2-APP-CASH-CODE

    JH0920                                      AP20F2-API-CASH-CODE

    JH0920     ELSE

    JH0920         MOVE SPACES               TO AP20F2-APP-BANK-INST-CODE

    JH0920                                      AP20F2-API-BANK-INST-CODE

    JH0920                                      AP20F2-APP-CASH-CODE

    JH0920                                      AP20F2-API-CASH-CODE

    JH0920     END-IF.

    JH0920

    JH0920     IF (AP20F2-APP-BANK-INST-CODE = SPACES)

    JH0920         MOVE "XXXX"               TO DB-VENDOR-GROUP

    JH0920         MOVE AP20F2-API-VENDOR    TO DB-VENDOR

    JH0920         PERFORM 840-FIND-VENSET1

    JH0920           IF (APVENMAST-FOUND)

    JH0920             MOVE VEN-BANK-INST-CODE TO AP20F2-APP-BANK-INST-CODE

    JH0920                                        AP20F2-API-BANK-INST-CODE

    JH0920             MOVE VEN-CASH-CODE      TO AP20F2-APP-CASH-CODE

    JH0920                                        AP20F2-API-CASH-CODE

    JH0920           ELSE

    JH0920             MOVE SPACES             TO AP20F2-APP-BANK-INST-CODE

    JH0920                                        AP20F2-API-BANK-INST-CODE

    JH0920                                        AP20F2-APP-CASH-CODE

    JH0920                                        AP20F2-API-CASH-CODE

    JH0920           END-IF

    JH0920     END-IF.

    JH0920

    JH1004

    JH1004 AP20BS2-TRANSACTION-END.

    JH1004*****************************************************************

    JH1004 AP20BS3-TRANSACTION             SECTION.

    JH1004*****************************************************************

    JH1004 AP20BS3-START.

    JH1004*

    JH1004*

    JH1004 AP20BS3-TRANSACTION-END.

    .

    .

    .

    JH1004*****************************************************************

    JH1004 AP20BS9-TRANSACTION             SECTION.

    JH1004*****************************************************************

    JH1004 AP20BS9-START.

    JH1004*

    JH1004*

    JH1004 AP20BS9-TRANSACTION-END.

    JH1004*

     

    AP20BWS

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

           01  AP20BWS.

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

               02  AP20BWS-FILLER          PIC X(1) VALUE SPACES.

     

     

    Add your working storage fields as needed. 

     

    UE Logic Implementation

    Once the logic is entered into the UE and WS fields are added, you need to compile the UE independently of the actual program.  You do this by using the “qcompile –u” command.

    qcompile –u  

                qcompile –u prod ap AP20B

    Check the source library for any error file generated and correct if necessary.  If no error file, make sure the executable object exists in the usrobj library. ($LAWDIR//usrobj)

    …/usrobj

    -rw-rw-rw-    1 lawson   lawson        13169 Sep 20 09:00 AP20B.gnt

    If the .gnt is not present, make sure you have no errors and then that your ID has write access to this directory path.

    It is not necessary to recompile the main program, in this case AP20, but it doesn’t hurt either.


    tambrosi
    Enterprise System Analysis
    Private
    Advanced Member
    (97 points)
    Advanced Member
    Posts:45


    Send Message:

    --
    03/11/2015 2:12 PM

    Hello All, 1st,  Thanks for all of the replies, and examples.  They really helped!!!!

    After setting up my exit, and it compiles clean, and I see the .gnt in the usrobj lib,   is there away to see if the user exit gets invoked.  Can I put a Display/show/

    process in the Exit to see if the main code line is hitting the exit routine?   

    I did try to compile the base program, that had no effect either.  

    Any help would be appreciated.   

    Thanks.

     

     

    jaherb
    Private
    Private
    Veteran Member
    (471 points)
    Veteran Member
    Posts:163


    Send Message:

    --
    03/11/2015 2:54 PM
    Depending on if you are unix or windows, you can animate the program... or an easier way is to place a display statement in the program... For on line programs you can see the display statements by clicking on Options and the Display Statements.

    Another way that I have used before is to log a simple entry into a csv file, since they are so easy to setup and use, and then look at the csv file.

    tambrosi
    Enterprise System Analysis
    Private
    Advanced Member
    (97 points)
    Advanced Member
    Posts:45


    Send Message:

    --
    03/12/2015 6:46 AM

    I have a dumb question,  where/how do I invoke the Display statement.  

    Options and display statements.   We are Windows and version 10. 

    I added it to my exit, compiled clean,  

    000000 CU01MS1-TRANSACTION              SECTION.
    000100 CU01MS1-START.
               DISPLAY "Here in Exit".
               MOVE CU01F1-CUC-CURRENCY-CODE TO DB-CURRENCY-CODE. 
               PERFORM 840-FIND-CUCSET1.
               IF (CU01F1-FC = "C")         

    Is there a documentation book that I can get to see how to trace thru the cobol execuatables. 

    Thanks for any and all help. 

    jaherb
    Private
    Private
    Veteran Member
    (471 points)
    Veteran Member
    Posts:163


    Send Message:

    --
    03/12/2015 9:49 AM
    The format of the DISPLAY statement is just as you entered it.

    Unfortunately, with a WINDOWS operating system, you do not have access to animator unless you use it from the main system console. I only had that luxury one time so I made heavy use of the display statements or made entries in a csv file to monitor what what going on
    tambrosi
    Enterprise System Analysis
    Private
    Advanced Member
    (97 points)
    Advanced Member
    Posts:45


    Send Message:

    --
    03/12/2015 12:51 PM

    Thanks for all of the help on this!!.  

    To find the trace, I had to go out the the joblog directory and look for files named IE. lapm.####  My trace/log showed in there.  

     

     

     

    Rob Marshall
    Senior Consultant
    RPI Consultants, Inc
    New Member
    (3 points)
    New Member
    Posts:1


    Send Message:

    --
    02/17/2017 1:16 PM
    Hi everyone. I know this is an old thread, but wanted to drop some information here.

    The BEGIN and END user exit programs seem to work universally in 4GL online programs (including invokes), but the MID only works when the main program's PD has a (literally) "400-PROCESS-TRAN" section. Many programs do not comply to the "400-" section standard, instead using other section names.

    Luckily my use case worked OK for the BEGIN.

    Happy coding! Rob
    jaherb
    Private
    Private
    Veteran Member
    (471 points)
    Veteran Member
    Posts:163


    Send Message:

    --
    02/24/2017 12:47 PM

    On the NT Servers... you can see DISPLAY statement value by going to the submission form, clicking on Options and then Display Log File.

    You are not authorized to post a reply.