• The Four Hundred
  • Subscribe
  • Media Kit
  • Contributors
  • About Us
  • Contact
Menu
  • The Four Hundred
  • Subscribe
  • Media Kit
  • Contributors
  • About Us
  • Contact
  • Submit Job Schedule Entries Immediately

    December 1, 2004 Ted Holt

    The code for this article is available for download.

    You can buy better job schedulers than the one that comes bundled with OS/400. Unfortunately for many of us, the OS/400 job scheduler is the only one we’re permitted to use. Because I recently found myself forced to work within that restriction, I wrote a command to overcome one of the built-in job scheduler’s limitations. Later I discovered that my new utility overcame a second limitation. It occurred to me that some of you might like to have this utility.

    In “Job Scheduler’s Other Defaults,” I explained to Beau that the OS/400 job scheduler runs a Submit Job (SBMJOB) command, filling in certain parameters with non-default values. A problem occurs when someone needs to submit a scheduled job to run outside of the regularly scheduled time. The Work with Job Schedule Entries panel includes option 10, “submit immediately,” which at first seems to address the need, but doesn’t really. The Submit Immediately option runs SBMJOB with SBMJOB’s usual default parameter values, not the non-default parameter values that that the job scheduler uses. This means that the job scheduler does not include an option to immediately submit an entry in the same way the job scheduler normally submits the entry. This is the limitation I needed to overcome.

    For this reason, I wrote the Submit Job Schedule Entry (SBMJOBSCDE) utility. It retrieves a job scheduler entry and builds a SBMJOB command, filling in the parameters with the non-default values the job scheduler uses. The utility consists of three objects: the SBMJOBSCDE command, an OPM CL command-processing program named JOBSCDE1C, and a help panel group called JOBSCDE1H.

    SBMJOBSCDE is easy to use. It has only two parameters. The first is the name of the entry as it appears in the job scheduler. The second parameter works only in interactive mode. It permits you to prompt the generated SBMJOB command so you can make changes before the new job is submitted to batch. Here’s the source code.

    /* ==================================================== */
    /* Submit a job schedule entry for immediate execution. */
    /* ==================================================== */
    /* To create:                                           */
    /*     CRTCMD CMD(xxx/SBMJOBSCDE)                       */
    /*            PGM(xxx/JOBSCDE1C)                        */
    /*            SRCFILE(xxx/QCMDSRC)                      */
    /*            HLPPNLGRP(JOBSCDE1H)                      */
    /*            HLPID(*CMD)                               */
    /* ==================================================== */
    CMD        PROMPT('Submit Job Schedule Entry')
    PARM       KWD(JOB) TYPE(*CHAR) LEN(10) MIN(1) +
                 EXPR(*YES) PROMPT('Job schedule entry name')
    PARM       KWD(PROMPT) TYPE(*CHAR) LEN(4) RSTD(*YES) +
                 DFT(*NO) VALUES(*YES *NO) EXPR(*YES) +
                 PROMPT('Prompt before submitting?')
    

    The CL program uses the List Job Schedule Entries (QWCLSCDE) API to retrieve the job schedule entry information into user space QTEMP/SBMJOBSCDE. It extracts that information from the user space to build the SBMJOB command.

    /* ==================================================== */
    /* Submit a job schedule entry for immediate execution. */
    /* ==================================================== */
    /* To compile:                                          */
    /*      CRTCLPGM PGM(xxx/JOBSCDE1C)                     */
    /*               SRCFILE(xxx/QCLSRC)                    */
    /*               SRCMBR(JOBSCDE1C)                      */
    /* ==================================================== */
    
    pgm parm(&inJobScdE &inPrompt)
    
       dcl &inJobScdE   *char     10
       dcl &inPrompt    *char      4
    
       dcl &UsrSpcName  *char     10  'SBMJOBSCDE'
       dcl &UsrSpcLib   *char     10  'QTEMP'
       dcl &UsrSpc      *char     20
       dcl &FmtName     *char      8  'SCDL0200'
       dcl &NbrEntries  *dec      10
       dcl &Offset      *dec      10
       dcl &EntryLen    *dec      10
       dcl &Continue    *char     16
       dcl &StartPos    *dec       5
       dcl &UsrSpcData  *char x'1000'
       dcl &UsrSpcSize  *char      4  x'00001000'
       dcl &Error       *char     16  x'00000010'
       dcl &JobType     *char      1
    
       dcl &Cmd         *char    512
       dcl &CmdLen      *dec       3
       dcl &InfoStatus  *char      1
       dcl &JobName     *char     10
       dcl &JobQ        *char     10
       dcl &JobQLib     *char     10
       dcl &JobD        *char     10
       dcl &JobDLib     *char     10
       dcl &MsgQ        *char     10
       dcl &MsgQLib     *char     10
       dcl &UsrPrf      *char     10
    
       dcl &CmdString   *char   4096
       dcl &Quote       *char      1  ''''
    
       dcl &Abending    *lgl
       dcl &MsgID       *char      7
       dcl &MsgDta      *char    256
       dcl &MsgF        *char     10
       dcl &MsgFLib     *char     10
       dcl &MsgKey      *char      4
       dcl &RtnType     *char      2
       dcl &PgmName     *char     10
       dcl &Sender      *char     80
    
       monmsg cpf0000 exec(goto abend)
    
       /* retrieve the program name */
       sndpgmmsg msg(' ') topgmq(*same) msgtype(*info) keyvar(&MsgKey)
       rcvmsg    pgmq(*same) msgtype(*info) sender(&Sender) rmv(*yes)
       chgvar    &PgmName   %sst(&Sender 56 10)
    
       /* create a temporary user space                 */
       /* and load it with job schedule information     */
    
       chgvar     &UsrSpc   (&UsrSpcName *cat &UsrSpcLib)
    
       chkobj &UsrSpcLib/&UsrSpcName *usrspc
       monmsg cpf0000 exec(do)
          call quscrtus (&UsrSpc ' ' &UsrSpcSize ' ' *all &Error)
       enddo
       call qwclscde  (&UsrSpc &FmtName &inJobScdE &Continue &Error)
       call qusrtvus  (&UsrSpc x'00000001' &UsrSpcSize &UsrSpcData &Error)
    
       chgvar &NbrEntries   %bin(&UsrSpcData 133 4)
       if (&NbrEntries *lt 1) do
          chgvar var(&MsgDta) value('Job schedule entry' *bcat &inJobScdE +
                                    *bcat 'could not be found.')
          sndpgmmsg  msgid(cpf9897)  msgf(qcpfmsg)   msgtype(*diag) +
                       msgdta(&MsgDta)
          goto Escape
       enddo
    
    /* extract job info from the job schedule entry */
       chgvar &Offset       %bin(&UsrSpcData 125 4)
       chgvar &EntryLen     %bin(&UsrSpcData 137 4)
    
       chgvar &StartPos     (&Offset + 1)
       chgvar &InfoStatus   %sst(&UsrSpcData &StartPos 1)
       chgvar &StartPos     (&Offset + 2)
       chgvar &JobName      %sst(&UsrSpcData &StartPos 10)
       chgvar &StartPos     (&Offset + 198)
       chgvar &JobQ         %sst(&UsrSpcData &StartPos 10)
       chgvar &StartPos     (&Offset + 208)
       chgvar &JobQLib      %sst(&UsrSpcData &StartPos 10)
       chgvar &StartPos     (&Offset + 527)
       chgvar &JobD         %sst(&UsrSpcData &StartPos 10)
       chgvar &StartPos     (&Offset + 537)
       chgvar &JobDLib      %sst(&UsrSpcData &StartPos 10)
       chgvar &StartPos     (&Offset + 547)
       chgvar &UsrPrf       %sst(&UsrSpcData &StartPos 10)
       chgvar &StartPos     (&Offset + 557)
       chgvar &MsgQ         %sst(&UsrSpcData &StartPos 10)
       chgvar &StartPos     (&Offset + 567)
       chgvar &MsgQLib      %sst(&UsrSpcData &StartPos 10)
       chgvar &StartPos     (&Offset + 641)
       chgvar &CmdLen       %bin(&UsrSpcData &StartPos 4)
       chgvar &StartPos     (&Offset + 645)
       chgvar &Cmd          %sst(&UsrSpcData &StartPos &CmdLen)
    
    /* Was prompting requested? */
       rtvjoba type(&JobType)
       if (&JobType *eq '1') do /* Interactive job */
          if ((%sst(&inPrompt 2 1) *eq 'Y') +
          *or (%sst(&inPrompt 2 1) *eq 'y')) do
             chgvar  &CmdString '?'
          enddo
       enddo
    
    /* build a command string from the job schedule entry */
       chgvar  &CmdString (&CmdString *tcat 'SBMJOB JOB(' +
                           *cat &JobName *tcat ')')
    
       chgvar  &CmdString (&CmdString *bcat 'JOBD(')
       if (%sst(&JobD 1 1) *ne '*') do
          chgvar  &CmdString (&CmdString *tcat &JobDLib *tcat '/')
       enddo
       chgvar  &CmdString (&CmdString *tcat &JobD *tcat ')')
    
       chgvar  &CmdString (&CmdString *bcat 'JOBQ(')
       if (%sst(&JobQ 1 1) *ne '*') do
          chgvar  &CmdString (&CmdString *tcat &JobQLib *tcat '/')
       enddo
       chgvar  &CmdString (&CmdString *tcat &JobQ *tcat ')')
    
       chgvar  &CmdString (&CmdString *bcat 'CMD(' +
                           *cat %sst(&Cmd 1 &CmdLen) +
                           *cat ')')
    
       chgvar  &CmdString (&CmdString *bcat 'USER(' *cat &UsrPrf *cat ')')
    
       chgvar  &CmdString (&CmdString *bcat 'MSGQ(')
       if (%sst(&MsgQ 1 1) *ne '*') do
          chgvar  &CmdString (&CmdString *tcat &MsgQLib *tcat '/')
       enddo
       chgvar  &CmdString (&CmdString *tcat &MsgQ *tcat ')')
    
       chgvar  &CmdString (&CmdString *bcat 'SYSLIBL(*SYSVAL) +
                              CURLIB(*USRPRF) INLLIBL(*JOBD) +
                              PRTDEV(*JOBD) OUTQ(*JOBD) +
                              PRTTXT(*JOBD) RTGDTA(*JOBD) +
                              SRTSEQ(*USRPRF) LANGID(*USRPRF) +
                              CNTRYID(*USRPRF) CCSID(*USRPRF)')
    
       call   qcmdexc   (&CmdString 4096)
       monmsg cpf6801
       rcvmsg     msgtype(*last) msgdta(&MsgDta) msgid(&MsgID) +
                     rtntype(&RtnType) +
                     msgf(&MsgF) sndmsgflib(&MsgFLib)
       sndpgmmsg  msgid(&MsgID)  msgf(&MsgF) msgtype(*comp) +
                    msgdta(&MsgDta)
       return
    
       /* Routine to handle unexpected errors */
    Abend:
          if &Abending then(return)
          chgvar   &Abending '1'
    
    ForwardMsg:
          rcvmsg     msgtype(*any) msgdta(&MsgDta) msgid(&MsgID) +
                        rtntype(&RtnType) +
                        msgf(&MsgF) sndmsgflib(&MsgFLib)
          if ((&RtnType *eq '02') *or   /* diagnostic */ +
              (&RtnType *eq '15') *or (&RtnType *eq '17')) do  /* *escape */
             sndpgmmsg  msgid(&MsgID)  msgf(&MsgF)   msgtype(*diag) +
                       msgdta(&MsgDta)
          enddo
          if (&RtnType *ne '  ') then(goto ForwardMsg)
    Escape:
       sndpgmmsg  msgid(cpf9898) msgf(qcpfmsg) msgtype(*escape) +
                    msgdta('Program' *bcat &PgmName *bcat +
                           'ended abnormally')
    endpgm
    

    The command is easy enough to use, but I put together some brief help text anyway. Store it in member JOBSCDE1H.

    .* ====================================================================
    .* Help text for the SBMJOBSCDE command
    .* ====================================================================
    .* To create:
    .*      CRTPNLGRP PNLGRP(xxx/JOBSCDE1H)
    .*                SRCFILE(xxx/QPNLSRC)
    .*                SRCMBR(JOBSCDE1H)
    .* ====================================================================
    
    :PnlGrp.
    
    
    :Help Name = 'SBMJOBSCDE' .Submit Job Schedule Entry - Help
    
    :P.
    The Submit Job Schedule Entry (SBMJOBSCDE) command allows you to submit
    a job scheduler entry using the parameter values the job scheduler
    applies to the SBMJOB command. SBMJOBSCDE allows you to run a scheduled
    job on demand in the same way it would run if the job scheduler started
    it.
    
    :EHelp.
    
    :Help Name = 'SBMJOBSCDE/Job' .Job name (JOB) - Help
    :XH3 .Job entry (JOB)
    
    :P.
    The name of the job as it is known to the job scheduler.
    
    :P.
    This is a required parameter.
    
    :EHelp.
    
    :Help Name = 'SBMJOBSCDE/PROMPT' .Prompt command (PROMPT) - Help
    :XH3 .Prompt command (PROMPT)
    
    :P.
    This parameter applies to interactive execution of SBMJOBSCDE only.
    It allows you to modify the generated SBMJOB comamnd before submitting
    the job to batch for execution.
    
    :P.
    The possible values are:
    
    :Parml.
    :pt.:pk def.*NO:epk.
    :pd.SBMJOB will not be prompted before execution.
    :pt.:pk.*YES:epk.
    :pd.SBMJOB will be prompted for execution. You will be allowed to
    modify parameter values.
    :EParmL.
    
    :EHelp.
    
    :EPnlGrp. 
    

    I mentioned that my new utility overcame a second limitation. After I wrote SBMJOBSCDE, I realized I had found the answer to the problem I wrote about in “Scheduling a Job to Run More than Once a Day.” In a follow-up to that article, reader Rocky suggested creating multiple, identical job schedule entries in order to run a job schedule entry more than once a day. The problem with that approach is that changing one entry means having to change them all.


    SBMJOBSCDE addresses this problem as well. Create one entry with the proper settings. Make the others run SBMJOBSCDE to kick off the original entry at other times.

    So far I have been pleased with SBMJOBSCDE. This utility has worked correctly in all my tests and in production. I hope some of you will find it helpful as well. Please contact me with bug reports or suggestions for improvements, if you have a better idea, or just to let me know it’s helped you.

    Ted Holt is editor of Four Hundred Guru. Click here to contact Ted Holt by e-mail.

    Share this:

    • Reddit
    • Facebook
    • LinkedIn
    • Twitter
    • Email

    Tags:

    Sponsored by
    DRV Tech

    Get More Out of Your IBM i

    With soaring costs, operational data is more critical than ever. IBM shops need faster, easier ways to distribute IBM applications-based data to users more efficiently, no matter where they are.

    The Problem:

    For Users, IBM Data Can Be Difficult to Get To

    IBM Applications generate reports as spooled files, originally designed to be printed. Often those reports are packed together with so much data it makes them difficult to read. Add to that hardcopy is a pain to distribute. User-friendly formats like Excel and PDF are better, offering sorting, searching, and easy portability but getting IBM reports into these formats can be tricky without the right tools.

    The Solution:

    IBM i Reports can easily be converted to easy to read and share formats like Excel and PDF and Delivered by Email

    Converting IBM i, iSeries, and AS400 reports into Excel and PDF is now a lot easier with SpoolFlex software by DRV Tech.  If you or your users are still doing this manually, think how much time is wasted dragging and reformatting to make a report readable. How much time would be saved if they were automatically formatted correctly and delivered to one or multiple recipients.

    SpoolFlex converts spooled files to Excel and PDF, automatically emailing them, and saving copies to network shared folders. SpoolFlex converts complex reports to Excel, removing unwanted headers, splitting large reports out for individual recipients, and delivering to users whether they are at the office or working from home.

    Watch our 2-minute video and see DRV’s powerful SpoolFlex software can solve your file conversion challenges.

    Watch Video

    DRV Tech

    www.drvtech.com

    866.378.3366

    Share this:

    • Reddit
    • Facebook
    • LinkedIn
    • Twitter
    • Email

    Pat Townsend Launches Stand-Alone AES/400 Encryption Solution Choose Wisely: High Availability Performance and Reliability Issues

    Leave a Reply Cancel reply

Volume 4, Number 40 -- December 1, 2004
THIS ISSUE
SPONSORED BY:

Linoma Software
WorksRight Software
Guild Companies

Table of Contents

  • Submit Job Schedule Entries Immediately
  • V5R3 CL Enhancements on V5R2
  • Admin Alert: Tips for Dealing with Deleted Records in AS/400 Files

Content archive

  • The Four Hundred
  • Four Hundred Stuff
  • Four Hundred Guru

Recent Posts

  • Meet The Next Gen Of IBMers Helping To Build IBM i
  • Looks Like IBM Is Building A Linux-Like PASE For IBM i After All
  • Will Independent IBM i Clouds Survive PowerVS?
  • Now, IBM Is Jacking Up Hardware Maintenance Prices
  • IBM i PTF Guide, Volume 27, Number 24
  • Big Blue Raises IBM i License Transfer Fees, Other Prices
  • Keep The IBM i Youth Movement Going With More Training, Better Tools
  • Remain Begins Migrating DevOps Tools To VS Code
  • IBM Readies LTO-10 Tape Drives And Libraries
  • IBM i PTF Guide, Volume 27, Number 23

Subscribe

To get news from IT Jungle sent to your inbox every week, subscribe to our newsletter.

Pages

  • About Us
  • Contact
  • Contributors
  • Four Hundred Monitor
  • IBM i PTF Guide
  • Media Kit
  • Subscribe

Search

Copyright © 2025 IT Jungle