Is there an API or other function to list current users of a specific pgm?

10 pts.
Tags:
API
AS/400 administration
We need to be able to list users who are presently running certain program objects. Example: User Bob is presently running pgm A, which cannot be running when User Joe kicks off pgm B. We would like to be able to detect within the call to Joe's pgm B that Bob is presently running pgm A so as to send message to Joe's with list of current users of pgm A. (DSPACTJOB is not a good option for this purpose) Any guidance will be appreciated.

Answer Wiki

Thanks. We'll let you know when a new response is added.

Perhaps you will be able to find what you’re looking for, however, what I’ve seen has
PgmA write a value into a Data area when it starts and clear the area when it’s done.
PgmB checks the area and only continues if it’s clear.

Of course PgmA could lock an object like a dtaara and when PgmB attempts to lock it, it would
discover that the object was locked, then it’s just a matter of determining what job is locking
the object.

Discuss This Question: 4  Replies

 
There was an error processing your information. Please try again later.
Thanks. We'll let you know when a new response is added.
Send me notifications when members answer or reply to this question.

REGISTER or login:

Forgot Password?
By submitting you agree to receive email from TechTarget and its partners. If you reside outside of the United States, you consent to having your personal data transferred to and processed in the United States. Privacy
  • Sloopy
    If the programs in question are 'screen' programs, they will hold locks on the DSPF (Display File) objects. These locks can be detected easily. I think I have something in my toolbox that sends messages to users locking a particular object - I will look and let you know. Regards, Sloopy
    2,195 pointsBadges:
    report
  • philpl1jb
    Right file objects, display files, printer files, physical files will be locked by the job while they are open, just not program objects.
    49,850 pointsBadges:
    report
  • Sloopy
    OK - here is the Send Lock Message (SNDLCKMSG) command and its processing program :
                 CMD        PROMPT('Send message to locking jobs')        
                                                                          
                 PARM       KWD(RTCD) TYPE(*CHAR) CONSTANT(*CMD) MIN(1)   
                                                                          
                 PARM       KWD(OBJ) TYPE(Q1) MIN(1) PROMPT('Object name')
                                                                          
                 PARM       KWD(OBJTYPE) TYPE(*CHAR) LEN(10) RSTD(*YES) + 
                              VALUES(*CTLD *DEVD *DTAARA *DTAQ *FILE +    
                              *JOBD *JOBQ *JOBSCD *JRN *JRNRCV *LIB +     
                              *MSGF *MSGQ *OUTQ *QRYDFN *SBSD *USRPRF +   
                              *USRQ *USRSPC) MIN(1) PROMPT('Object type') 
                                                                          
                 PARM       KWD(MBR) TYPE(*NAME) LEN(10) EXPR(*YES) +     
                              PROMPT('Member name')                       
                                                                          
                 PARM       KWD(MSGTXT) TYPE(*CHAR) LEN(200) DFT(*DFT) +  
                              SPCVAL((*DFT)) EXPR(*YES) PROMPT('Message + 
                              text')                                      
                                                                          
                 PARM       KWD(INQMSG) TYPE(*CHAR) LEN(4) RSTD(*YES) +   
                             DFT(*YES) VALUES(*YES *NO) +                
                             PROMPT('Send as Inquiry message')           
                                                                         
    Q1:         QUAL       TYPE(*NAME) LEN(10) MIN(1)                    
                QUAL       TYPE(*NAME) LEN(10) DFT(*LIBL) +              
                             SPCVAL((*LIBL) (*CURLIB)) PROMPT('Library') 
    
    NOTE: Before creating the CL program, create the workfile so that the program will compile: CRTPF FILE(QTEMP/WBLCKP) RCDLEN(150)
                 PGM        PARM(&RTCD &OBJC &TYPE &MBNM &TEXT &BRKM)                
                                                                                     
    /* --------------------------------------------------------------------------- */
    /* Declare variables                                                           */
    /* --------------------------------------------------------------------------- */
                                                                                     
                 DCLF       FILE(WBLCKP)                                             
                                                                                     
                 DCL        VAR(&RTCD)   TYPE(*CHAR) LEN(7)                          
                 DCL        VAR(&OBJC)   TYPE(*CHAR) LEN(20)                         
                   DCL        VAR(&LIBR)   TYPE(*CHAR) LEN(10)                       
                   DCL        VAR(&OBJN)   TYPE(*CHAR) LEN(10)                       
                 DCL        VAR(&TYPE)   TYPE(*CHAR) LEN(7)                          
                 DCL        VAR(&MBNM)   TYPE(*CHAR) LEN(10)                         
                 DCL        VAR(&TEXT)   TYPE(*CHAR) LEN(200)                        
                 DCL        VAR(&BRKM)   TYPE(*CHAR) LEN(4)                          
                                                                                     
                 DCL        VAR(&JBNM)   TYPE(*CHAR) LEN(10)                         
                 DCL        VAR(&USER)   TYPE(*CHAR) LEN(10)                         
                 DCL        VAR(&JBNO)   TYPE(*CHAR) LEN(6)                          
                                                                                     
                 DCL        VAR(&DFTT)   TYPE(*CHAR) LEN(1)                          
                 DCL        VAR(&MTYP)   TYPE(*CHAR) LEN(5) VALUE('*INFO')           
                                                                                     
                 DCL        VAR(&MSGI)   TYPE(*CHAR) LEN(7)                          
                 DCL        VAR(&MSGF)   TYPE(*CHAR) LEN(10)                         
                 DCL        VAR(&MSGL)   TYPE(*CHAR) LEN(10)                         
                 DCL        VAR(&MSGD)   TYPE(*CHAR) LEN(500)                        
                                                                                     
    /* --------------------------------------------------------------------------- */
    /* Global message monitor                                                      */
    /* --------------------------------------------------------------------------- */
                                                                                     
                 MONMSG     MSGID(CPF0000 RPG0000 MCH0000 PWB0000) +                 
                              EXEC(GOTO CMDLBL(PGMERR))                              
                                                                                     
    /* --------------------------------------------------------------------------- */
    /* Get object name & library                                                   */
    /* --------------------------------------------------------------------------- */
                                                                                     
                 CHGVAR     VAR(&OBJN) VALUE(%SST(&OBJC  1 10))                      
                 CHGVAR     VAR(&LIBR) VALUE(%SST(&OBJC 11 10))                      
                                                                                     
                 IF         COND(&LIBR *EQ ' ') THEN(CHGVAR VAR(&LIBR) +             
                              VALUE('*LIBL'))                                        
                                                                                     
                 IF         COND(&BRKM *EQ '*YES') THEN(CHGVAR +                     
                              VAR(&MTYP) VALUE('*INQ'))                              
                                                                                     
    /* Check for default message text :                                            */
                                                                                     
                 IF         COND(&TEXT *EQ '*DFT') THEN(CHGVAR +                     
                              VAR(&DFTT) VALUE('Y'))                                 
                                                                                     
    /* --------------------------------------------------------------------------- */
    /* Print object locks, capture into workfile                                   */
    /* --------------------------------------------------------------------------- */
                                                                                     
                 CHKOBJ     OBJ(QTEMP/WBLCKP) OBJTYPE(*FILE)                         
                 MONMSG     MSGID(CPF0000 MCH0000) EXEC(CRTPF +                      
                              FILE(QTEMP/WBLCKP) RCDLEN(150))                        
                                                                                     
                 OVRPRTF    FILE(QPDSPOLK) HOLD(*YES)                                
                                                                                     
                 IF         COND(&MBNM *EQ ' ') THEN( +                              
                 WRKOBJLCK  OBJ(&LIBR/&OBJN) OBJTYPE(&TYPE) +                        
                              OUTPUT(*PRINT))                                        
                                                                                     
                 IF         COND(&MBNM *NE ' ') THEN( +                              
                 WRKOBJLCK  OBJ(&LIBR/&OBJN) OBJTYPE(&TYPE) MBR(&MBNM) +             
                              OUTPUT(*PRINT))                                        
                                                                                     
                 CPYSPLF    FILE(QPDSPOLK) TOFILE(QTEMP/WBLCKP) +                    
                              SPLNBR(*LAST)                                          
                 MONMSG     MSGID(CPF0000 MCH0000)                                   
                                                                                     
                 DLTSPLF    FILE(QPDSPOLK) SPLNBR(*LAST)                             
                                                                                     
    /* --------------------------------------------------------------------------- */
    /* Read the file and send message text to all users                            */
    /* --------------------------------------------------------------------------- */
                                                                                     
                 OVRDBF     FILE(WBLCKP) TOFILE(QTEMP/WBLCKP)                        
                                                                                     
     DO_1:       RCVF                                                                
                 MONMSG     MSGID(CPF0864) EXEC(GOTO CMDLBL(PGMEND))                 
                                                                                     
             IF COND(&TYPE *EQ '*FILE') THEN(DO)                                     
                 CHGVAR     VAR(&JBNO) VALUE(%SST(&WBLCKP 37 6))                     
                 IF         COND(&JBNO *LT '000000' *OR &JBNO *GT +                  
                              '999999') THEN(GOTO CMDLBL(DO_1))                      
                 CHGVAR     VAR(&JBNM) VALUE(%SST(&WBLCKP 15 10))                    
                 CHGVAR     VAR(&USER) VALUE(%SST(&WBLCKP 26 10))                    
             ENDDO                                                                   
             ELSE DO                                                                 
                 CHGVAR     VAR(&JBNO) VALUE(%SST(&WBLCKP 28 6))                     
                 IF         COND(&JBNO *LT '000000' *OR &JBNO *GT +                  
                              '999999') THEN(GOTO CMDLBL(DO_1))                      
                 CHGVAR     VAR(&JBNM) VALUE(%SST(&WBLCKP 4 10))                     
                 CHGVAR     VAR(&USER) VALUE(%SST(&WBLCKP 16 10))                    
             ENDDO                                                                   
                                                                                     
                 IF         COND(&DFTT *EQ 'Y') THEN(CHGVAR VAR(&TEXT) +             
                              VALUE('You are locking object' *BCAT +                 
                              &LIBR *TCAT '/' *CAT &OBJN *BCAT 'type' +              
                              *BCAT &TYPE *BCAT 'in job' *BCAT &JBNO +               
                              *TCAT '/' *CAT &USER *TCAT '/' *CAT &JBNM +            
                              *TCAT '. Please sign out of the job or +               
                              release the object lock.'))                            
                                                                                     
                 SNDBRKMSG  MSG(&TEXT) TOMSGQ(&JBNM) MSGTYPE(&MTYP)                  
                 MONMSG     MSGID(CPF0000 MCH0000)                                   
                                                                                     
                 GOTO       CMDLBL(DO_1)                                             
                                                                                     
    /* --------------------------------------------------------------------------- */
    /* Resend error messages to caller, if run as a command                        */
    /* --------------------------------------------------------------------------- */
                                                                                     
     PGMERR:     RCVMSG     MSGTYPE(*EXCP) RMV(*NO) MSGDTA(&MSGD) +                  
                              MSGID(&MSGI) MSGF(&MSGF) MSGFLIB(&MSGL)                
                                                                                     
                 IF         COND(&RTCD *EQ '*CMD' *AND &MSGI *NE ' ') +              
                              THEN(DO)                                               
                 SNDPGMMSG  MSGID(&MSGI) MSGF(&MSGL/&MSGF) MSGDTA(&MSGD) +           
                              MSGTYPE(*ESCAPE)                                       
                 MONMSG     MSGID(CPF0000)                                           
                 ENDDO                                                               
                                                                                     
    /* --------------------------------------------------------------------------- */
    /* End program                                                                 */
    /* --------------------------------------------------------------------------- */
                                                                                     
     PGMEND:     ENDPGM                                                              
    
    Regards, Sloopy
    2,195 pointsBadges:
    report
  • TomLiotta
    Processing a spooled file for this kind of data isn't very efficient, nor is it guaranted to be reliable. Much better would be to use the facilities that are supplied specifically for the purpose. In this case, that would be the List Object Locks (QWCLOBJL) API. APIs are avoided because people are afraid to code tests and because many of them require a group of APIs to be used together. Tests for a single API turn into something that seems complicated. But the parts can be fairly simple. Here's a simple program that accepts object name, library and type, plus an optional member name in case the object is a physical file. As written, it sends a basic program message back to the previous call stack entry when it finds a lock in any job other than the current job. (That can be replaced by any other action you need.) The program uses a basic service program to do the general user space actions that go along with the QWCLOBJL API. The *SRVPGM modules are each simple ILE CL. They can be used over and over again in different programs that use different list APIs. The consistency is one reason the user space APIs are useful. The first *SRVPGM module is CRTUS (Create user space). It creates an initial *USRSPC with some basic characteristics. Eventually, the values might be changed if necessary:
    pgm    ( +
             &pqUsrSpc    +
             &pErr        +
           )
    
       dcl   &pqUsrSpc    *char    20
       dcl   &pErr        *lgl
    
    
    /* API User Space and General Variables */
       dcl   &ErrCod      *char   128  value( x'0000008000000000' )
    
    /* General fields for RUSGENHDR...                                  */
    
       dcl   &usAttr     *char    10
       dcl   &usText     *char    50
    
       dcl   &qusrspc    *char    20
    
    
    /*---------------------------------------------------------------------------*/
    /* Global MONMSG...                                                          */
    /*---------------------------------------------------------------------------*/
    
       monmsg    ( cpf0000 mch0000 ) exec( goto Std_Err )
    
    
    /* Set the qualified *usrspc name...                                         */
       chgvar     &qusrspc      &pqUsrSpc
    
       call  QUSCRTUS         ( +
                                &qusrspc                +
                                &usAttr                 +
                                x'00004000'             +
                                X'00'                   +
                                '*ALL      '            +
                                &usText                 +
                                '*YES      '            +
                                &ErrCod                 +
                              )
    
    
       return
    
    
     Std_Err:
    
       /* Move any *DIAG messages up the stack...        */
    
       Qsys/call       QSYS/QMHMOVPM       ( +
                                             '    '          +
                                             '*DIAG     '    +
                                             x'00000001'     +
                                             '*         '    +
                                             x'00000001'     +
                                             x'00000000'     +
                                           )
       Qsys/monmsg     ( CPF0000 MCH0000 )
    
       /* Resend any *ESCAPE messages up the stack...     */
    
       call       QSYS/QMHRSNEM       ( +
                                        '    '          +
                                        x'00000000'     +
                                      )
       monmsg     ( CPF0000 MCH0000 )
    
       return
    
    
    endpgm
    Next is GETUSLSTE (Get user space list attributes). The attributes most often needed are the offset into the space to the beginning of the list, the number of entries in the list and the size of each list entry. Although the entry size will be known when the program is written, the size is retrieved and used in case a format changes in the future:
    pgm    ( +
             &pqUsrSpc    +
             &offslst     +
             &nbrlste     +
             &sizlste     +
             &pErr        +
           )
    
       dcl   &pqUsrSpc    *char    20
       dcl   &offslst     *int
       dcl   &nbrlste     *int
       dcl   &sizlste     *int
       dcl   &pErr        *lgl
    
    
    /* General API error parm... */
       dcl   &ErrCod      *char   128  value( x'0000008000000000' )
    
    /* User space header...                                             */
       dcl   &us_hdr      *char   150
    
       dcl   &qusrspc     *char    20
    
    
    /*---------------------------------------------------------------------------*/
    /* Global MONMSG...                                                          */
    /*---------------------------------------------------------------------------*/
    
       monmsg    ( cpf0000 mch0000 ) exec( goto STD_ERR )
    
    
    /* Set the qualified *usrspc name...                                         */
       chgvar          &qusrspc              &pqUsrSpc
    
    
    /* Retrieve the user space header...                                         */
    
       call        QUSRTVUS   ( +
                                &qusrspc                +
                                x'00000001'             +
                                x'00000096'             +
                                &us_hdr                 +
                                &ErrCod                 +
                              )
    
    /* Get the offset to the list within the space, the number   */
    /*   of list entries and size of each entry from the header. */
    
       chgvar          &offslst        %bin( &us_hdr    125 4 )
       chgvar          &nbrlste        %bin( &us_hdr    133 4 )
       chgvar          &sizlste        %bin( &us_hdr    137 4 )
    
    /* Convert "offset" to "position"...                         */
    
       chgvar          &offslst            ( &offslst + 1 )
    
       return
    
    
     Std_Err:
    
       /* Move any *DIAG messages up the stack...        */
    
       Qsys/call       QSYS/QMHMOVPM       ( +
                                             '    '          +
                                             '*DIAG     '    +
                                             x'00000001'     +
                                             '*         '    +
                                             x'00000001'     +
                                             x'00000000'     +
                                           )
       Qsys/monmsg     ( CPF0000 MCH0000 )
    
       /* Resend any *ESCAPE messages up the stack...     */
    
       Qsys/call       QSYS/QMHRSNEM       ( +
                                             '    '          +
                                             x'00000000'     +
                                           )
       Qsys/monmsg     ( CPF0000 MCH0000 )
    
       return
    
    endpgm
    Last is RTVUSE (Retrieve user space entry). The next entry in the list is returned. The entry will be a data structure that is defined by the "format" you ask for when you call the particular list API. The length of the data structure is the "size" of the list entry:
    pgm    ( +
             &pqUsrSpc    +
             &poffslst    +
             &pnbrlste    +
             &psizlste    +
             &pEnt        +
             &pErr        +
           )
    
       dcl   &pqUsrSpc    *char    20
       dcl   &poffslst    *int
       dcl   &pnbrlste    *int
       dcl   &psizlste    *int
       dcl   &pEnt        *char   512
       dcl   &pErr        *lgl
    
    
    /* General API error code...  */
       dcl   &ErrCod      *char   128  value( x'0000008000000000' )
    
    /* The entry that was retrieved...                                  */
       dcl   &us_Ent      *char   512
    
       dcl   &qusrspc     *char    20
    
    
    /*---------------------------------------------------------------------------*/
    /* Global MONMSG...                                                          */
    /*---------------------------------------------------------------------------*/
    
       monmsg    ( cpf0000 mch0000 ) exec( goto STD_ERR )
    
    
    /* Set the qualified *usrspc name...                                         */
       chgvar          &qusrspc              &pqUsrSpc
    
    
    /* Retrieve next entry from the *usrspc...                   */
    
       call        QUSRTVUS   ( +
                                &qusrspc                +
                                &poffslst               +
                                &psizlste               +
                                &us_Ent                 +
                                &ErrCod                 +
                              )
    
    /*                                                           */
    /* Increment offset, decrement NumberOfListEntries...        */
    /*                                                           */
       chgvar          &poffslst           ( &poffslst + &psizlste )
       chgvar          &pnbrlste           ( &pnbrlste - 1 )
    
    /* Set Entry value...                                        */
       chgvar    %sst( &pEnt 1 &psizlste ) %sst( &us_Ent  1 &psizlste )
    
       return
    
    
     Std_Err:
    
       /* Move any *DIAG messages up the stack...        */
    
       Qsys/call       QSYS/QMHMOVPM       ( +
                                             '    '          +
                                             '*DIAG     '    +
                                             x'00000001'     +
                                             '*         '    +
                                             x'00000001'     +
                                             x'00000000'     +
                                           )
       Qsys/monmsg     ( CPF0000 MCH0000 )
    
       /* Resend any *ESCAPE messages up the stack...     */
    
       Qsys/call       QSYS/QMHRSNEM       ( +
                                             '    '          +
                                             x'00000000'     +
                                           )
       Qsys/monmsg     ( CPF0000 MCH0000 )
    
       return
    
    
    endpgm
    Every time RTVUSE is called, the offset is incremented by the size of the list entry and the number of entries is decremented by one. The next RTVUSE is called, the offset points to the next entry. When the number of entries drops to zero, the list is exhausted. Create the service program as:
    CRTSRVPGM SRVPGM( mylib/US_PROC )
              MODULE( CRTUS GETUSLSTA RTVUSE )
              EXPORT( *ALL )
    The *SRVPGM name and the names of the modules can be whatever you choose as long as the main program references your names. The LSTOBJLCK program is:
    pgm    ( +
             &pObj        +
             &pObjLib     +
             &pObjType    +
             &pMbr        +
           )
    
       dcl   &pObj        *char    10
       dcl   &pObjLib     *char    10
       dcl   &pObjType    *char    10
       dcl   &pMbr        *char    10
    
    
    /* A lock entry in format OBJL0100...                               */
       dcl   &us_lcke       *char      64
    
    
    /*  The job holding the lock...                                     */
       dcl   &LckJob        *char      10
       dcl   &LckUser       *char      10
       dcl   &LckNbr        *char       6
    
    /*  Space name...                                                   */
       dcl   &usrspc        *char      10     value( 'OBJLCK' )
       dcl   &usrspclib     *char      10     value( 'QTEMP' )
       dcl   &qusrspc       *char      20
    
    /*  Qualified lock object name...                                   */
       dcl   &qlckobj       *char      20
    
    /*  For file member checks...                                       */
       dcl   &Mbr           *char      10
    
    /*  List offset, number of entries, entry size...                   */
       dcl   &offslst     *int
       dcl   &nbrlste     *int
       dcl   &sizlste     *int
    
       dcl   &ErrInd      *lgl
       dcl   &ErrCod        *char     128     value( x'0000000000000000' )
    
    /*  The current job...                                              */
       dcl   &CurJob        *char      10
       dcl   &CurUser       *char      10
       dcl   &CurNbr        *char       6
    
    
    /*  Grab member if supploied, else set the default...               */
       chgvar            &Mbr                  &pMbr
       monmsg  ( mch3601 )  exec( do )
          rcvmsg     msgtype( *LAST ) rmv( *YES )
          monmsg   ( cpf0000 )
          chgvar         &Mbr                  '*NONE'
       enddo
    
    /* Set qualified names...                                           */
       chgvar            &qlckobj            ( &pObj *cat &pObjLib )
       chgvar            &qusrspc            ( &usrspc *cat &usrspclib )
    
    /*  Create a usrspc to hold the objlck data from this usrprf...     */
    
       callprc     CRTUS      ( &qusrspc &ErrInd )
    
    /*                                                                  */
    /*  Populate the usrspc with appropriate objlck data...             */
    /*                                                                  */
    
       call  qwclobjl         ( +
                                &qusrspc     +
                                'OBJL0100'   +
                                &qlckobj     +
                                &pObjType    +
                                &Mbr         +
                                &ErrCod      +
                              )
    
    
    /*  Get current job info to see if WE have it locked HERE...        */
       rtvjoba     job( &CurJob ) user( &CurUser ) nbr( &CurNbr )
    
    /*  Retrieve the initialization data...                             */
    
       callprc     GETUSLSTA  ( +
                                &qusrspc     +
                                &offslst     +
                                &nbrlste     +
                                &sizlste     +
                                &ErrInd      +
                              )
    
       if  ( &nbrlste *eq 0 )     do
          sndpgmmsg  msgid( CPF9898 ) msgf( QCPFMSG ) +
                       msgdta( 'No active locks found' )
          goto   Clean_up
       enddo
    
    /* Entries have been placed in the *usrspc for every objlck on the  */
    /*  named object. We can now loop through to see if any locks are   */
    /*  held by another job...                                          */
    
    /* Start retrieval of objlck entries from the *usrspc...            */
       callprc     RTVUSE     ( +
                                &qusrspc     +
                                &offslst     +
                                &nbrlste     +
                                &sizlste     +
                                &us_lcke     +
                                &ErrInd      +
                              )
    
       dountil  ( &nbrlste *le 0 )
    
    /* Extract job info from list entry...                       */
          chgvar         &LckJob         %sst( &us_lcke     1  10 )
          chgvar         &LckUser        %sst( &us_lcke    11  10 )
          chgvar         &LckNbr         %sst( &us_lcke    21   6 )
    
    /*  Does it match?...                                               */
    /*  ...but ignore THIS job...                                       */
          if ( &LckJob *ne &CurJob *or &LckUser *ne &CurUser +
               *or &LckNbr *ne &CurNbr )  do
             sndpgmmsg  msgid( CPF9898 ) msgf(QCPFMSG) +
                          msgdta( +
                                  'Job(' *bcat &LckNbr *cat '/' *cat +
                                  &LckUser *tcat '/' *cat &LckJob +
                                  *bcat ')'  +
                                ) +
                          msgtype( *INFO )
          enddo
    
    /* Retrieve next entry...                                           */
          callprc  RTVUSE     ( +
                                &qusrspc     +
                                &offslst     +
                                &nbrlste     +
                                &sizlste     +
                                &us_lcke     +
                                &ErrInd      +
                              )
       enddo
    
    
    Clean_up:
    
       call  Qsys/QUSDLTUS  ( &qusrspc &ErrCod )
    
       return
    
    endpgm
    Create the program with:
    CRTPGM PGM( mylib/LSTOBJLCK )
           BNDSRVPGM( US_PROC )
           ACTGRP( *NEW )
    The activation group doesn't have to be *NEW, but I can't think of any reason not to have it create itself and go away when it finishes. If the action that replaces the example SNDPGMMSG requires some other activation group setting, then change it. (I haven't come up with a useful example reason.) Once the *SRVPGM exists, most of your programs that use list APIs like QWCLOBJL will look very much the same. The logic is straightforward and easy. If the modules are all compiled with debug data, you can follow through to see how it works. Tom
    125,585 pointsBadges:
    report

Forgot Password

No problem! Submit your e-mail address below. We'll send you an e-mail containing your password.

Your password has been sent to:

To follow this tag...

There was an error processing your information. Please try again later.

REGISTER or login:

Forgot Password?
By submitting you agree to receive email from TechTarget and its partners. If you reside outside of the United States, you consent to having your personal data transferred to and processed in the United States. Privacy

Thanks! We'll email you when relevant content is added and updated.

Following