<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-8909486560224298250</id><updated>2012-02-16T19:36:10.083-08:00</updated><category term='XML in RPG'/><category term='Image Handling'/><category term='IFS Folder'/><category term='DDS'/><category term='PDF AS400'/><title type='text'>Prabhat Mohapatra</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://prabhatmohapatra.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8909486560224298250/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://prabhatmohapatra.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Prabhat</name><uri>http://www.blogger.com/profile/14496453689733819797</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>13</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8909486560224298250.post-7528773948316376688</id><published>2009-10-09T02:54:00.000-07:00</published><updated>2011-07-14T17:06:14.317-07:00</updated><title type='text'>Converting from AS400 reports to HTML</title><content type='html'>&lt;script type="text/javascript"&gt;&lt;!--&lt;br /&gt;google_ad_client = "pub-4291413222633996";&lt;br /&gt;/* PKM, 300x250, created 14/07/11 */&lt;br /&gt;google_ad_slot = "5553551703";&lt;br /&gt;google_ad_width = 300;&lt;br /&gt;google_ad_height = 250;&lt;br /&gt;//--&gt;&lt;br /&gt;&lt;/script&gt;&lt;br /&gt;&lt;script type="text/javascript"&lt;br /&gt;src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;&lt;br /&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;Converting AS400 spool files to HTML.....&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;     H&lt;br /&gt;&lt;br /&gt;     Fcvtwork02 IF   F  382        DISK&lt;br /&gt;&lt;br /&gt;     Fcvtwork01 UF A F  378        DISK&lt;br /&gt;&lt;br /&gt;      * Standard HTML header lines&lt;br /&gt;&lt;br /&gt;     D aaHeader        S             80A   DIM(2) CTDATA PERRCD(1)&lt;br /&gt;&lt;br /&gt;      * Standard HTML footer line&lt;br /&gt;&lt;br /&gt;     D aaFooter        S             80A   DIM(1) CTDATA PERRCD(1)&lt;br /&gt;&lt;br /&gt;      * Input spooled file data including control characters&lt;br /&gt;&lt;br /&gt;     D InputData       DS&lt;br /&gt;     D   saSkipLine                   3A&lt;br /&gt;     D   ssSkipLine                   3S 0 OVERLAY(saSkipLine:1)&lt;br /&gt;     D   saSpceLine                   1A&lt;br /&gt;     D   ssSpceLine                   1S 0 OVERLAY(saSpceLine:1)&lt;br /&gt;     D   saInput                    378A&lt;br /&gt;&lt;br /&gt;      * Output HTML-format data&lt;br /&gt;&lt;br /&gt;     D OutputData      DS&lt;br /&gt;     D   saOutput                   378A&lt;br /&gt;&lt;br /&gt;      * Program parameters - title and page length in lines&lt;br /&gt;&lt;br /&gt;     D paTitle         S             50A&lt;br /&gt;     D piPageLen       S             10I 0&lt;br /&gt;&lt;br /&gt;      * Line counter variable&lt;br /&gt;&lt;br /&gt;     D wiLine          S             10I 0&lt;br /&gt;&lt;br /&gt;      * Procedure prototypes&lt;br /&gt;&lt;br /&gt;     D HTMLHeader      PR&lt;br /&gt;&lt;br /&gt;     D HTMLFooter      PR&lt;br /&gt;&lt;br /&gt;     D Convert         PR&lt;br /&gt;&lt;br /&gt;     D Merge           PR                  LIKE(saOutput)&lt;br /&gt;     D    iaOutput                         LIKE(saOutput)&lt;br /&gt;     D    iaInput                          LIKE(saInput)&lt;br /&gt;&lt;br /&gt;     D SpceLines       PR&lt;br /&gt;     D    isSpceLine                       LIKE(ssSpceLine)&lt;br /&gt;&lt;br /&gt;     D SkipLines       PR&lt;br /&gt;     D    isSkipLine                       LIKE(ssSkipLine)&lt;br /&gt;&lt;br /&gt;      * Program parameters&lt;br /&gt;&lt;br /&gt;     C     *ENTRY        PLIST&lt;br /&gt;     C                   PARM                    paTitle&lt;br /&gt;     C                   PARM                    piPageLen&lt;br /&gt;&lt;br /&gt;      * Output HTML header lines&lt;br /&gt;&lt;br /&gt;     C                   CALLP     HTMLHeader&lt;br /&gt;&lt;br /&gt;      * Convert spool file lines to HTML&lt;br /&gt;&lt;br /&gt;     C                   READ      cvtwork02     InputData                LR&lt;br /&gt;     C                   DOW       *INLR = *OFF&lt;br /&gt;     C                   CALLP     Convert&lt;br /&gt;     C                   READ      cvtwork02     InputData                LR&lt;br /&gt;     C                   ENDDO&lt;br /&gt;&lt;br /&gt;      * Output HTML footer lines&lt;br /&gt;&lt;br /&gt;     C                   CALLP     HTMLFooter&lt;br /&gt;&lt;br /&gt;     C                   RETURN&lt;br /&gt;&lt;br /&gt;      **********************************************************************&lt;br /&gt;      * Procedure to create HTML header lines                              *&lt;br /&gt;      **********************************************************************&lt;br /&gt;&lt;br /&gt;     P HTMLHeader      B&lt;br /&gt;&lt;br /&gt;     D HTMLHeader      PI&lt;br /&gt;&lt;br /&gt;     C                   EVAL      saOutput = aaHeader(1)&lt;br /&gt;     C                   WRITE     cvtwork01     OutputData&lt;br /&gt;&lt;br /&gt;     C                   IF        paTitle &lt;&gt; '*NONE'&lt;br /&gt;     C                   EVAL      saOutput   = ''&lt;br /&gt;     C                   WRITE     cvtwork01     OutputData&lt;br /&gt;     C                   ENDIF&lt;br /&gt;&lt;br /&gt;     C                   EVAL      saOutput = aaHeader(2)&lt;br /&gt;     C                   WRITE     cvtwork01     OutputData&lt;br /&gt;&lt;br /&gt;     P HTMLHeader      E&lt;br /&gt;&lt;br /&gt;      **********************************************************************&lt;br /&gt;      * Procedure to create HTML footer line                               *&lt;br /&gt;      **********************************************************************&lt;br /&gt;&lt;br /&gt;     P HTMLFooter      B&lt;br /&gt;&lt;br /&gt;     D HTMLFooter      PI&lt;br /&gt;&lt;br /&gt;     C                   EVAL      saOutput = aaFooter(1)&lt;br /&gt;     C                   WRITE     cvtwork01     OutputData&lt;br /&gt;&lt;br /&gt;     P HTMLFooter      E&lt;br /&gt;&lt;br /&gt;      **********************************************************************&lt;br /&gt;      * Procedure to convert spooled file data to HTML text                *&lt;br /&gt;      **********************************************************************&lt;br /&gt;&lt;br /&gt;     P Convert         B&lt;br /&gt;&lt;br /&gt;     D Convert         PI&lt;br /&gt;&lt;br /&gt;      * If 'space' position is zero, 'overprint' previous line&lt;br /&gt;&lt;br /&gt;     C                   IF        saSpceLine = '0'&lt;br /&gt;&lt;br /&gt;     C     *HIVAL        SETGT     cvtwork01&lt;br /&gt;     C                   READP     cvtwork01     OutputData               99&lt;br /&gt;     C                   EVAL      saOutput = Merge(saOutput:saInput)&lt;br /&gt;     C                   UPDATE    cvtwork01     OutputData&lt;br /&gt;&lt;br /&gt;     C                   ELSE&lt;br /&gt;&lt;br /&gt;      * Skip to a line if specified&lt;br /&gt;&lt;br /&gt;     C                   IF        saSkipLine &lt;&gt; *BLANKS&lt;br /&gt;     C                   CALLP     SkipLines(ssSkipLine)&lt;br /&gt;     C                   ENDIF&lt;br /&gt;&lt;br /&gt;      * Space a number of lines if specified&lt;br /&gt;&lt;br /&gt;     C                   IF        saSpceLine &lt;&gt; *BLANKS&lt;br /&gt;     C                   CALLP     SpceLines(ssSpceLine)&lt;br /&gt;     C                   ENDIF&lt;br /&gt;&lt;br /&gt;      * 'Print' line&lt;br /&gt;&lt;br /&gt;     C                   EVAL      saOutput   = saInput&lt;br /&gt;     C                   WRITE     cvtwork01     OutputData&lt;br /&gt;&lt;br /&gt;     C                   ENDIF&lt;br /&gt;&lt;br /&gt;     C                   RETURN&lt;br /&gt;&lt;br /&gt;     P Convert         E&lt;br /&gt;&lt;br /&gt;      **********************************************************************&lt;br /&gt;      * Procedure to merge two overlaid lines of text                      *&lt;br /&gt;      **********************************************************************&lt;br /&gt;&lt;br /&gt;     P Merge           B&lt;br /&gt;&lt;br /&gt;     D Merge           PI                  LIKE(saOutput)&lt;br /&gt;     D    iaOutput                         LIKE(saOutput)&lt;br /&gt;     D    iaInput                          LIKE(saInput)&lt;br /&gt;&lt;br /&gt;     D laOutput        S                   LIKE(saOutput)&lt;br /&gt;&lt;br /&gt;     D i               S              5I 0&lt;br /&gt;&lt;br /&gt;     C                   EVAL      i = 1&lt;br /&gt;     C                   DOW            i &lt;= %size(iaInput )&lt;br /&gt;     C                             and  i &lt;= %size(iaOutput)&lt;br /&gt;     C                             and  i &lt;= %size(laOutput)&lt;br /&gt;     C                   IF        %subst(iaInput:i:1) = *BLANK&lt;br /&gt;     C                   EVAL      %subst(laOutput:i:1) = %subst(iaOutput:i:1)&lt;br /&gt;     C                   ELSE&lt;br /&gt;     C                   EVAL      %subst(laOutput:i:1) = %subst(iaInput :i:1)&lt;br /&gt;     C                   ENDIF&lt;br /&gt;     C                   EVAL      i = i + 1&lt;br /&gt;     C                   ENDDO&lt;br /&gt;&lt;br /&gt;     C                   RETURN    laOutput&lt;br /&gt;&lt;br /&gt;     P Merge           E&lt;br /&gt;&lt;br /&gt;      **********************************************************************&lt;br /&gt;      * Procedure to skip to a given line number                           *&lt;br /&gt;      **********************************************************************&lt;br /&gt;&lt;br /&gt;     P SkipLines       B&lt;br /&gt;&lt;br /&gt;     D SkipLines       PI&lt;br /&gt;     D    isSkipLine                       LIKE(ssSkipLine)&lt;br /&gt;&lt;br /&gt;     C                   EVAL      saOutput = *BLANKS&lt;br /&gt;&lt;br /&gt;     C                   IF        wiLine &gt; isSkipLine&lt;br /&gt;&lt;br /&gt;     C                   DOW       wiLine &lt; piPageLen&lt;br /&gt;     C                   WRITE     cvtwork01     OutputData&lt;br /&gt;     C                   EVAL      wiLine = wiLine + 1&lt;br /&gt;     C                   ENDDO&lt;br /&gt;&lt;br /&gt;     C                   EVAL      saOutput   = '-------------------------'&lt;br /&gt;     C                   WRITE     cvtwork01     OutputData&lt;br /&gt;     C                   EVAL      saOutput = *BLANKS&lt;br /&gt;     C                   EVAL      wiLine = 1&lt;br /&gt;&lt;br /&gt;     C                   ENDIF&lt;br /&gt;&lt;br /&gt;     C                   DOW       wiLine &lt; isSkipLine&lt;br /&gt;     C                   WRITE     cvtwork01     OutputData&lt;br /&gt;     C                   EVAL      wiLine = wiLine + 1&lt;br /&gt;     C                   ENDDO&lt;br /&gt;&lt;br /&gt;     C                   RETURN&lt;br /&gt;&lt;br /&gt;     P SkipLines       E&lt;br /&gt;&lt;br /&gt;      **********************************************************************&lt;br /&gt;      * Procedure to space a number of lines                               *&lt;br /&gt;      **********************************************************************&lt;br /&gt;&lt;br /&gt;     P SpceLines       B&lt;br /&gt;&lt;br /&gt;     D SpceLines       PI&lt;br /&gt;     D    isSpceLine                       LIKE(ssSpceLine)&lt;br /&gt;&lt;br /&gt;     D liCount         S              5I 0&lt;br /&gt;&lt;br /&gt;     C                   EVAL      wiLine  = wiLine  + 1&lt;br /&gt;     C                   EVAL      saOutput = *BLANKS&lt;br /&gt;     C                   DOW       liCount &lt; isSpceLine - 1&lt;br /&gt;     C                   WRITE     cvtwork01     OutputData&lt;br /&gt;     C                   EVAL      wiLine  = wiLine  + 1&lt;br /&gt;     C                   EVAL      liCount = liCount + 1&lt;br /&gt;     C                   ENDDO&lt;br /&gt;&lt;br /&gt;     C                   RETURN&lt;br /&gt;&lt;br /&gt;     P SpceLines       E&lt;br /&gt;**&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8909486560224298250-7528773948316376688?l=prabhatmohapatra.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://prabhatmohapatra.blogspot.com/feeds/7528773948316376688/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://prabhatmohapatra.blogspot.com/2009/10/converting-from-as400-reports-to-html.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8909486560224298250/posts/default/7528773948316376688'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8909486560224298250/posts/default/7528773948316376688'/><link rel='alternate' type='text/html' href='http://prabhatmohapatra.blogspot.com/2009/10/converting-from-as400-reports-to-html.html' title='Converting from AS400 reports to HTML'/><author><name>Prabhat</name><uri>http://www.blogger.com/profile/14496453689733819797</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8909486560224298250.post-7384344134771843288</id><published>2009-10-09T02:52:00.000-07:00</published><updated>2011-07-14T17:09:28.766-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PDF AS400'/><title type='text'>Conversion of AS400 reports to PDF files</title><content type='html'>&lt;script type="text/javascript"&gt;&lt;!--&lt;br /&gt;google_ad_client = "pub-4291413222633996";&lt;br /&gt;/* PKM, 300x250, created 14/07/11 */&lt;br /&gt;google_ad_slot = "5553551703";&lt;br /&gt;google_ad_width = 300;&lt;br /&gt;google_ad_height = 250;&lt;br /&gt;//--&gt;&lt;br /&gt;&lt;/script&gt;&lt;br /&gt;&lt;script type="text/javascript"&lt;br /&gt;src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;&lt;br /&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Fcvtwork01 UF A F  378        DISK&lt;br /&gt;&lt;br /&gt;      * Program parameter - report title&lt;br /&gt;&lt;br /&gt;     D paTitle         S             50A&lt;br /&gt;&lt;br /&gt;      * Program parameter - spooled file information returned by API&lt;br /&gt;&lt;br /&gt;     D SplInfo         DS&lt;br /&gt;     D  saReturned                   10I 0&lt;br /&gt;     D  saAvailabl                   10I 0&lt;br /&gt;     D  saIntJobId                   16A&lt;br /&gt;     D  saSplfId                     16A&lt;br /&gt;     D  saJobName                    10A&lt;br /&gt;     D  saUser                       10A&lt;br /&gt;     D  saJobNbr                      6A&lt;br /&gt;     D  saSplFile                    10A&lt;br /&gt;     D  saSplNbr                     10I 0&lt;br /&gt;     D  saFormType                   10A&lt;br /&gt;     D  saUsrDta                     10A&lt;br /&gt;     D  saStatus                     10A&lt;br /&gt;     D  saFilAvail                   10A&lt;br /&gt;     D  saHold                       10A&lt;br /&gt;     D  saSave                       10A&lt;br /&gt;     D  siPages                      10I 0&lt;br /&gt;     D  siCurrPage                   10I 0&lt;br /&gt;     D  siFromPage                   10I 0&lt;br /&gt;     D  siToPage                     10I 0&lt;br /&gt;     D  siLastPage                   10I 0&lt;br /&gt;     D  siRestart                    10I 0&lt;br /&gt;     D  siCopies                     10I 0&lt;br /&gt;     D  siCopyRem                    10I 0&lt;br /&gt;     D  siLPI                        10I 0&lt;br /&gt;     D  siCPI                        10I 0&lt;br /&gt;     D  siOutPty                      2A&lt;br /&gt;     D  saOutq                       10A&lt;br /&gt;     D  saOutqLib                    10A&lt;br /&gt;     D  saOpenDate                    7A&lt;br /&gt;     D  saOpenTime                    6A&lt;br /&gt;     D  saPrtFile                    10A&lt;br /&gt;     D  saPrtfLib                    10A&lt;br /&gt;     D  saPgmName                    10A&lt;br /&gt;     D  saPgmLib                     10A&lt;br /&gt;     D  saAcgCode                    15A&lt;br /&gt;     D  saPrtTxt                     30A&lt;br /&gt;     D  siRcdLen                     10I 0&lt;br /&gt;     D  siMaxRcds                    10I 0&lt;br /&gt;     D  saDevType                    10A&lt;br /&gt;     D  saPrtType                    10A&lt;br /&gt;     D  saDocName                    12A&lt;br /&gt;     D  saFlrName                    64A&lt;br /&gt;     D  saS36Proc                     8A&lt;br /&gt;     D  saFidelity                   10A&lt;br /&gt;     D  saRplUnprt                    1A&lt;br /&gt;     D  saRplChar                     1A&lt;br /&gt;     D  siPageLen                    10I 0&lt;br /&gt;     D  siPageWdth                   10I 0&lt;br /&gt;     D  siSepartrs                   10I 0&lt;br /&gt;     D  siOvrFlw                     10I 0&lt;br /&gt;     D  saDBCS                       10A&lt;br /&gt;     D  saDBCSExt                    10A&lt;br /&gt;     D  saDBCSSOSI                   10A&lt;br /&gt;     D  saDBCSRotn                   10A&lt;br /&gt;     D  saDBCSCPI                    10I 0&lt;br /&gt;     D  saGraphics                   10A&lt;br /&gt;     D  saCodePage                   10A&lt;br /&gt;     D  saFormDf                     10A&lt;br /&gt;     D  saFormDfLb                   10A&lt;br /&gt;     D  siDrawer                     10I 0&lt;br /&gt;     D  saFont                       10A&lt;br /&gt;     D  saS36SplId                    6A&lt;br /&gt;     D  siRotation                   10I 0&lt;br /&gt;     D  siJustify                    10I 0&lt;br /&gt;     D  saDuplex                     10A&lt;br /&gt;     D  saFoldRcds                   10A&lt;br /&gt;     D  saCtlChar                    10A&lt;br /&gt;     D  saAlign                      10A&lt;br /&gt;     D  saPrtQlty                    10A&lt;br /&gt;     D  saFormFeed                   10A&lt;br /&gt;     D  saVolumes                    71A&lt;br /&gt;     D  saLabels                     17A&lt;br /&gt;     D  saExchange                   10A&lt;br /&gt;     D  saCharCode                   10A&lt;br /&gt;     D  siTotRcds                    10I 0&lt;br /&gt;     D  siMultiUp                    10I 0&lt;br /&gt;     D  saFrontOvl                   10A&lt;br /&gt;     D  saFrtOvlLb                   10A&lt;br /&gt;     D  snFOOffDwn                   15P 5&lt;br /&gt;     D  snFOOffAcr                   15P 5&lt;br /&gt;     D  saBackOvl                    10A&lt;br /&gt;     D  saBckOvlLb                   10A&lt;br /&gt;     D  snBOOffDwn                   15P 5&lt;br /&gt;     D  snBOOffAcr                   15P 5&lt;br /&gt;     D  saUOM                        10A&lt;br /&gt;     D  saPagDfn                     10A&lt;br /&gt;     D  saPagDfnLb                   10A&lt;br /&gt;     D  saSpacing                    10A&lt;br /&gt;     D  snPointSiz                   15P 5&lt;br /&gt;     D  snFMOffDwn                   15P 5&lt;br /&gt;     D  snFMOffAcr                   15P 5&lt;br /&gt;     D  snBMOffDwn                   15P 5&lt;br /&gt;     D  snBMOffAcr                   15P 5&lt;br /&gt;     D  snPageLen                    15P 5&lt;br /&gt;     D  snPageWdth                   15P 5&lt;br /&gt;     D  saMethod                     10A&lt;br /&gt;     D  saAFP                         1A&lt;br /&gt;     D  saChrSet                     10A&lt;br /&gt;     D  saChrSetLb                   10A&lt;br /&gt;     D  saCdePagNm                   10A&lt;br /&gt;     D  saCdePgeLb                   10A&lt;br /&gt;     D  saCdeFnt                     10A&lt;br /&gt;     D  saCdeFntLb                   10A&lt;br /&gt;     D  saDBCSFnt                    10A&lt;br /&gt;     D  saDBCSFntL                   10A&lt;br /&gt;     D  saUserDef                    10A&lt;br /&gt;     D  saReduce                     10A&lt;br /&gt;     D  saReserv1                     1A&lt;br /&gt;     D  siOutBin                     10I 0&lt;br /&gt;     D  siCCSID                      10I 0&lt;br /&gt;     D  saUserText                  100A&lt;br /&gt;     D  saSystem                      8A&lt;br /&gt;     D  saOrigId                      8A&lt;br /&gt;     D  saCreator                    10A&lt;br /&gt;&lt;br /&gt;      * Program parameter - bookmark option&lt;br /&gt;&lt;br /&gt;     D paBookmark      S              7A&lt;br /&gt;&lt;br /&gt;      * Program parameter - bookmark *POS option parameters&lt;br /&gt;&lt;br /&gt;     D BMarkPos        DS&lt;br /&gt;     D   siPosCount                   5I 0&lt;br /&gt;     D   snPosLine                    3P 0&lt;br /&gt;     D   snPosChar                    3P 0&lt;br /&gt;     D   snPosLen                     3P 0&lt;br /&gt;&lt;br /&gt;      * Program parameter - bookmark *KEY option parameters&lt;br /&gt;&lt;br /&gt;     D BMarkKey        DS&lt;br /&gt;     D   siKeyCount                   5I 0&lt;br /&gt;     D   siLen                        5I 0&lt;br /&gt;     D   saKeyStr                   378A&lt;br /&gt;     D   snKeyOccur                   3P 0&lt;br /&gt;     D   snKeyOff                     3P 0&lt;br /&gt;     D   snKeyLen                     3P 0&lt;br /&gt;&lt;br /&gt;      * PDF 'object' array&lt;br /&gt;&lt;br /&gt;     D aiObject        S             10I 0 DIM(32767)&lt;br /&gt;&lt;br /&gt;      * Start position of PDF options&lt;br /&gt;&lt;br /&gt;     D aaStart         S             10A   DIM(32767)&lt;br /&gt;&lt;br /&gt;      * Current object number&lt;br /&gt;&lt;br /&gt;     D wiObject        S             10I 0&lt;br /&gt;&lt;br /&gt;      * Current count of bytes written&lt;br /&gt;&lt;br /&gt;     D wiChrCount      S             10I 0&lt;br /&gt;&lt;br /&gt;      * Current page number&lt;br /&gt;&lt;br /&gt;     D wiPage          S             10I 0&lt;br /&gt;&lt;br /&gt;      * Start position of text&lt;br /&gt;&lt;br /&gt;     D wiStart         S             10I 0&lt;br /&gt;&lt;br /&gt;      * Bookmark text&lt;br /&gt;&lt;br /&gt;     D waBookmark      S            378A&lt;br /&gt;&lt;br /&gt;      * Count of occurrences of the bookmark key&lt;br /&gt;&lt;br /&gt;     D wiOccurs        S              5I 0&lt;br /&gt;&lt;br /&gt;      * Input spooled file data including control characters&lt;br /&gt;&lt;br /&gt;     D InputData       DS&lt;br /&gt;     D   saSkipLine                   3A&lt;br /&gt;     D   ssSkipLine                   3S 0 OVERLAY(saSkipLine:1)&lt;br /&gt;     D   saSpceLine                   1A&lt;br /&gt;     D   ssSpceLine                   1S 0 OVERLAY(saSpceLine:1)&lt;br /&gt;     D   saInput                    378A&lt;br /&gt;&lt;br /&gt;      * Output PDF-format data&lt;br /&gt;&lt;br /&gt;     D OutputData      DS&lt;br /&gt;     D   saOutput                   378A&lt;br /&gt;&lt;br /&gt;      * Procedure prototypes&lt;br /&gt;&lt;br /&gt;     D WritePDF        PR&lt;br /&gt;     D   iaOutput                   378A   CONST OPTIONS(*VARSIZE)&lt;br /&gt;&lt;br /&gt;     D AddEscape       PR           378A&lt;br /&gt;     D   iaInput                    378A&lt;br /&gt;&lt;br /&gt;     D PDFHeader       PR&lt;br /&gt;&lt;br /&gt;     D PDFPages        PR&lt;br /&gt;&lt;br /&gt;     D PDFTrailer      PR&lt;br /&gt;&lt;br /&gt;     D NewPage         PR&lt;br /&gt;&lt;br /&gt;     D EndPage         PR&lt;br /&gt;&lt;br /&gt;     D NumToText       PR            10A&lt;br /&gt;     D    iiNum                      10I 0 CONST&lt;br /&gt;&lt;br /&gt;     D NewObject       PR&lt;br /&gt;&lt;br /&gt;      * Program parameters&lt;br /&gt;&lt;br /&gt;     C     *ENTRY        PLIST&lt;br /&gt;     C                   PARM                    paTitle&lt;br /&gt;     C                   PARM                    SplInfo&lt;br /&gt;     C                   PARM                    paBookmark&lt;br /&gt;     C                   PARM                    BMarkPos&lt;br /&gt;     C                   PARM                    BMarkKey&lt;br /&gt;&lt;br /&gt;      * Output a PDF header&lt;br /&gt;&lt;br /&gt;     C                   CALLP     PDFHeader&lt;br /&gt;&lt;br /&gt;      * Create PDF page 'objects'&lt;br /&gt;&lt;br /&gt;     C                   CALLP     PDFPages&lt;br /&gt;&lt;br /&gt;      * Output a PDF trailer&lt;br /&gt;&lt;br /&gt;     C                   CALLP     PDFTrailer&lt;br /&gt;&lt;br /&gt;     C                   RETURN&lt;br /&gt;&lt;br /&gt;      **********************************************************************&lt;br /&gt;      * Procedure to create a PDF 'header'                                 *&lt;br /&gt;      **********************************************************************&lt;br /&gt;&lt;br /&gt;     P PDFHeader       B&lt;br /&gt;&lt;br /&gt;     D PDFHeader       PI&lt;br /&gt;&lt;br /&gt;     D liPage          S             10I 0&lt;br /&gt;     D liPageObj       S             10I 0&lt;br /&gt;&lt;br /&gt;      * Create catalog object&lt;br /&gt;&lt;br /&gt;     C                   CALLP     WritePDF('%PDF-1.0')&lt;br /&gt;     C                   CALLP     WritePDF('%âãÏÓ')&lt;br /&gt;     C                   CALLP     NewObject&lt;br /&gt;     C                   CALLP     WritePDF(%trim(NumToText(wiObject))+' 0 obj')&lt;br /&gt;     C                   CALLP     WritePDF('&lt;&lt;')&lt;br /&gt;     C                   CALLP     WritePDF('/Type /Catalog')&lt;br /&gt;     C                   CALLP     WritePDF('/Pages 5 0 R')&lt;br /&gt;     C                   CALLP     WritePDF('/Outlines 2 0 R')&lt;br /&gt;     C                   CALLP     WritePDF('/PageMode /UseOutlines')&lt;br /&gt;     C                   CALLP     WritePDF('&gt;&gt;')&lt;br /&gt;     C                   CALLP     WritePDF('endobj')&lt;br /&gt;&lt;br /&gt;      * Create outlines object&lt;br /&gt;&lt;br /&gt;     C                   CALLP     NewObject&lt;br /&gt;     C                   CALLP     WritePDF(%trim(NumToText(wiObject))+' 0 obj')&lt;br /&gt;     C                   CALLP     WritePDF('&lt;&lt;')&lt;br /&gt;     C                   CALLP     WritePDF('/Type /Outlines')&lt;br /&gt;     C                   CALLP     WritePDF('/Count '+%trim(NumToText(siPages)))&lt;br /&gt;     C                   CALLP     WritePDF(  '/First 9 0 R')&lt;br /&gt;     C&lt;br /&gt;     C                   CALLP     WritePDF(  '/Last  '&lt;br /&gt;     C                                      + %trim(NumToText((siPages*4)+5))&lt;br /&gt;     C                                      + ' 0 R')&lt;br /&gt;     C                   CALLP     WritePDF('&gt;&gt;')&lt;br /&gt;     C                   CALLP     WritePDF('endobj')&lt;br /&gt;&lt;br /&gt;      * Create procedures object&lt;br /&gt;&lt;br /&gt;     C                   CALLP     NewObject&lt;br /&gt;     C                   CALLP     WritePDF(%trim(NumToText(wiObject))+' 0 obj')&lt;br /&gt;     C                   CALLP     WritePDF('[/PDF /Text]')&lt;br /&gt;     C                   CALLP     WritePDF('endobj')&lt;br /&gt;&lt;br /&gt;      * Create fonts object&lt;br /&gt;&lt;br /&gt;     C                   CALLP     NewObject&lt;br /&gt;     C                   CALLP     WritePDF(%trim(NumToText(wiObject))+' 0 obj')&lt;br /&gt;     C                   CALLP     WritePDF('&lt;&lt;')&lt;br /&gt;     C                   CALLP     WritePDF ('/Type /Font')&lt;br /&gt;     C                   CALLP     WritePDF ('/Subtype /Type1')&lt;br /&gt;     C                   CALLP     WritePDF ('/Name /F1')&lt;br /&gt;     C                   CALLP     WritePDF ('/BaseFont /Courier')&lt;br /&gt;     C                   CALLP     WritePDF ('/Encoding /WinAnsiEncoding')&lt;br /&gt;     C                   CALLP     WritePDF ('&gt;&gt;')&lt;br /&gt;     C                   CALLP     WritePDF ('endobj')&lt;br /&gt;&lt;br /&gt;      * Create pages object&lt;br /&gt;&lt;br /&gt;     C                   CALLP     NewObject&lt;br /&gt;     C                   CALLP     WritePDF(%trim(NumToText(wiObject))+' 0 obj')&lt;br /&gt;     C                   CALLP     WritePDF ('&lt;&lt;')&lt;br /&gt;     C                   CALLP     WritePDF ('/Type /Pages')&lt;br /&gt;     C                   CALLP     WritePDF('/Count '+%trim(NumToText(siPages)))&lt;br /&gt;&lt;br /&gt;      * Write list of child pages&lt;br /&gt;&lt;br /&gt;     C                   EVAL      liPage    = wiObject + 1&lt;br /&gt;     C                   EVAL      liPageObj = liPage&lt;br /&gt;     C                   CALLP     WritePDF (  '/Kids ['&lt;br /&gt;     C                                       + %trim(NumToText(liPage))&lt;br /&gt;     C                                       + ' 0 R')&lt;br /&gt;&lt;br /&gt;     C                   DOW       liPage &lt; siPages + wiObject&lt;br /&gt;     C                   EVAL      liPage = liPage + 1&lt;br /&gt;     C                   EVAL      liPageObj = liPageObj + 4&lt;br /&gt;     C                   CALLP     WritePDF (  '       '&lt;br /&gt;     C                                       + %trim(NumToText(liPageObj))&lt;br /&gt;     C                                       + ' 0 R')&lt;br /&gt;     C                   ENDDO&lt;br /&gt;&lt;br /&gt;     C                   CALLP     WritePDF ('       ]')&lt;br /&gt;&lt;br /&gt;     C                   CALLP     WritePDF ('&gt;&gt;')&lt;br /&gt;     C                   CALLP     WritePDF ('endobj')&lt;br /&gt;&lt;br /&gt;     P PDFHeader       E&lt;br /&gt;&lt;br /&gt;      **********************************************************************&lt;br /&gt;      * Procedure to create PDF pages                                      *&lt;br /&gt;      **********************************************************************&lt;br /&gt;&lt;br /&gt;     P PDFPages        B&lt;br /&gt;&lt;br /&gt;     D liLine          S             10I 0&lt;br /&gt;     D liLength        S              5I 0&lt;br /&gt;     D liChar          S              5I 0&lt;br /&gt;     D liX             S              5I 0&lt;br /&gt;     D liY             S              5I 0&lt;br /&gt;&lt;br /&gt;      * Create page object for first page&lt;br /&gt;&lt;br /&gt;     C                   EVAL      wiPage = 0&lt;br /&gt;     C                   EVAL      liX = 0&lt;br /&gt;&lt;br /&gt;      * Read spooled file data from input work file&lt;br /&gt;&lt;br /&gt;     C                   READ      cvtwork02     InputData                LR&lt;br /&gt;&lt;br /&gt;     C                   DOW       *INLR = *OFF&lt;br /&gt;&lt;br /&gt;      * Skip to a line if specified, handling page throw if it occurs&lt;br /&gt;&lt;br /&gt;     C                   IF        saSkipLine &lt;&gt; *BLANKS&lt;br /&gt;     C                   IF        ssSkipLine &lt; liLine or liLine = 0&lt;br /&gt;     C                   IF        wiPage &lt;&gt; 0&lt;br /&gt;     C                   CALLP     EndPage&lt;br /&gt;     C                   ENDIF&lt;br /&gt;     C                   CALLP     NewPage&lt;br /&gt;     C                   EVAL      liLine = ssSkipLine&lt;br /&gt;     C                   EVAL        liY&lt;br /&gt;     C                             = (612/siPageLen) * (siPagelen-liLine)&lt;br /&gt;     C                   ELSE&lt;br /&gt;     C                   EVAL        liY&lt;br /&gt;     C                             = -((612/siPageLen) * (ssSkipLine-liLine))&lt;br /&gt;     C                   EVAL      liLine = ssSkipLine&lt;br /&gt;     C                   ENDIF&lt;br /&gt;     C                   ENDIF&lt;br /&gt;&lt;br /&gt;      * Space a number of lines if specified&lt;br /&gt;&lt;br /&gt;     C                   IF        saSpceLine &lt;&gt; *BLANKS&lt;br /&gt;     C                   EVAL      liLine = liLine + ssSpceLine&lt;br /&gt;     C                   EVAL        liY&lt;br /&gt;     C                             = -((612/siPageLen) * ssSpceLine)&lt;br /&gt;     C                   ENDIF&lt;br /&gt;&lt;br /&gt;      * Set up bookmark if position option specified&lt;br /&gt;&lt;br /&gt;     C                   IF        paBookmark = '*POS'&lt;br /&gt;     C                   IF        liLine = snPosLine and waBookmark = *BLANKS&lt;br /&gt;     C                   EVAL      waBookmark = %trim(%subst(saInput  :&lt;br /&gt;     C                                                       snPosChar:&lt;br /&gt;     C                                                       snPosLen ))&lt;br /&gt;     C                   ENDIF&lt;br /&gt;     C                   ENDIF&lt;br /&gt;&lt;br /&gt;      * Set up bookmark if key option specified&lt;br /&gt;&lt;br /&gt;     C                   IF        paBookmark = '*KEY'&lt;br /&gt;     C     saKeyStr:siLenSCAN      saInput:1     liChar&lt;br /&gt;     C                   IF        liChar &gt; 0&lt;br /&gt;     C                   EVAL      wiOccurs = wiOccurs + 1&lt;br /&gt;     C                   IF        wiOccurs = snKeyOccur&lt;br /&gt;     C                   EVAL      liChar = liChar + snKeyOff&lt;br /&gt;     C                   EVAL      liLength = snKeyLen&lt;br /&gt;     C                   IF        liChar + liLength &gt; siPageWdth&lt;br /&gt;     C                   EVAL      liLength = siPageWdth - liChar&lt;br /&gt;     C                   ENDIF&lt;br /&gt;     C                   IF        liChar &lt; 1&lt;br /&gt;     C                   EVAL      liChar = 1&lt;br /&gt;     C                   ENDIF&lt;br /&gt;     C                   IF        liChar + liLength &lt;= siPageWdth&lt;br /&gt;     C                   EVAL      waBookmark = %trim(%subst(saInput  :&lt;br /&gt;     C                                                       liChar   :&lt;br /&gt;     C                                                       liLength ))&lt;br /&gt;     C                   ENDIF&lt;br /&gt;     C                   ENDIF&lt;br /&gt;     C                   ENDIF&lt;br /&gt;     C                   ENDIF&lt;br /&gt;&lt;br /&gt;      * Add escape character before special characters \, ( and )&lt;br /&gt;&lt;br /&gt;     C                   EVAL      saInput = AddEscape(saInput)&lt;br /&gt;&lt;br /&gt;      * Output the line of text&lt;br /&gt;&lt;br /&gt;     C                   CALLP     WritePDF(  %trim(NumToText(liX))&lt;br /&gt;     C                                      + ' '&lt;br /&gt;     C                                      + %trim(NumToText(liY))&lt;br /&gt;     C                                      + ' Td ('&lt;br /&gt;     C                                      + %trimr(saInput)&lt;br /&gt;     C                                      + ') Tj')&lt;br /&gt;&lt;br /&gt;     C                   READ      cvtwork02     InputData                LR&lt;br /&gt;&lt;br /&gt;     C                   ENDDO&lt;br /&gt;&lt;br /&gt;     C                   CALLP     EndPage&lt;br /&gt;&lt;br /&gt;     P PDFPages        E&lt;br /&gt;&lt;br /&gt;      **********************************************************************&lt;br /&gt;      * Procedure to create a PDF trailer                                  *&lt;br /&gt;      **********************************************************************&lt;br /&gt;&lt;br /&gt;     P PDFTrailer      B&lt;br /&gt;&lt;br /&gt;     D PDFTrailer      PI&lt;br /&gt;&lt;br /&gt;     D laDateTime      S             14A&lt;br /&gt;     D i               S             10I 0&lt;br /&gt;     D liXRef          S             10I 0&lt;br /&gt;&lt;br /&gt;      * Create information object&lt;br /&gt;&lt;br /&gt;     C                   CALLP     NewObject&lt;br /&gt;     C                   CALLP     WritePDF(%trim(NumToText(wiObject))+' 0 obj')&lt;br /&gt;     C                   CALLP     WritePDF('&lt;&lt;')&lt;br /&gt;     C                   CALLP     WritePDF(  '/Creator ('&lt;br /&gt;     C                                      + %trim(saPgmLib)&lt;br /&gt;     C                                      + '/'&lt;br /&gt;     C                                      + %trim(saPgmName)&lt;br /&gt;     C                                      + ')' )&lt;br /&gt;     C                   IF        %subst(saOpenDate:1:1) = '0'&lt;br /&gt;     C                   EVAL      laDateTime = '19' + %subst(saOpenDate:2:6)&lt;br /&gt;     C                                               + saOpenTime&lt;br /&gt;     C                   ELSE&lt;br /&gt;     C                   EVAL      laDateTime = '20' + %subst(saOpenDate:2:6)&lt;br /&gt;     C                                               + saOpenTime&lt;br /&gt;     C                   ENDIF&lt;br /&gt;     C                   CALLP     WritePDF(  '/CreationDate (D:'&lt;br /&gt;     C                                      + laDateTime + ')')&lt;br /&gt;     C                   CALLP     WritePDF('/Title (' + %trim(paTitle) + ')')&lt;br /&gt;     C                   CALLP     WritePDF('/Producer (CVTSPLPDF)')&lt;br /&gt;     C                   CALLP     WritePDF('/Keywords ()')&lt;br /&gt;     C                   CALLP     WritePDF(  '/Author ('&lt;br /&gt;     C                                      + %trim(saJobNbr)&lt;br /&gt;     C                                      + '/'&lt;br /&gt;     C                                      + %trim(saUser)&lt;br /&gt;     C                                      + '/'&lt;br /&gt;     C                                      + %trim(saJobName)&lt;br /&gt;     C                                      + ')' )&lt;br /&gt;     C                   CALLP     WritePDF('&gt;&gt;')&lt;br /&gt;     C                   CALLP     WritePDF('endobj')&lt;br /&gt;&lt;br /&gt;      * Create cross-reference&lt;br /&gt;&lt;br /&gt;     C                   EVAL      liXref = wiChrCount - 1&lt;br /&gt;     C                   CALLP     WritePDF('xref 0 '&lt;br /&gt;     C                                      + %trim(NumToText(wiObject+1)) )&lt;br /&gt;     C                   CALLP     WritePDF('0000000000 65535 f')&lt;br /&gt;&lt;br /&gt;     C                   DO        wiObject      i&lt;br /&gt;     C                   CALLP     WritePDF(aaStart(i) + ' 00000 n')&lt;br /&gt;     C                   ENDDO&lt;br /&gt;&lt;br /&gt;      * Write trailer&lt;br /&gt;&lt;br /&gt;     C                   CALLP     WritePDF('trailer')&lt;br /&gt;     C                   CALLP     WritePDF('&lt;&lt;')&lt;br /&gt;     C                   CALLP     WritePDF('/Size '&lt;br /&gt;     C                                      + %trim(NumToText(wiObject+1)))&lt;br /&gt;     C                   CALLP     WritePDF('/Root 1 0 R')&lt;br /&gt;     C                   CALLP     WritePDF('/Info '&lt;br /&gt;     C                                      + %trim(NumToText(wiObject))&lt;br /&gt;     C                                      + ' 0 R')&lt;br /&gt;     C                   CALLP     WritePDF('&gt;&gt;')&lt;br /&gt;     C                   CALLP     WritePDF('startxref')&lt;br /&gt;     C                   CALLP     WritePDF(%trim(NumToText(liXref)))&lt;br /&gt;     C                   CALLP     WritePDF('%%EOF')&lt;br /&gt;&lt;br /&gt;     P PDFTrailer      E&lt;br /&gt;&lt;br /&gt;      **********************************************************************&lt;br /&gt;      * Procedure to create a new PDF 'object'                             *&lt;br /&gt;      **********************************************************************&lt;br /&gt;     P NewObject       B&lt;br /&gt;&lt;br /&gt;     D NewObject       PI&lt;br /&gt;&lt;br /&gt;     D lsDataLen       S             10S 0&lt;br /&gt;     D i               S             10I 0&lt;br /&gt;&lt;br /&gt;     C                   EVAL      wiObject = wiObject + 1&lt;br /&gt;     C                   EVAL      i = wiObject&lt;br /&gt;     C                   EVAL      lsDataLen = wiChrCount&lt;br /&gt;     C                   MOVE      lsDataLen     aaStart(i)&lt;br /&gt;&lt;br /&gt;     P NewObject       E&lt;br /&gt;&lt;br /&gt;      **********************************************************************&lt;br /&gt;      * Procedure to output PDF data&lt;br /&gt;      **********************************************************************&lt;br /&gt;&lt;br /&gt;     P WritePDF        B&lt;br /&gt;&lt;br /&gt;     D WritePDF        PI&lt;br /&gt;     D   iaOutput                   378A   CONST OPTIONS(*VARSIZE)&lt;br /&gt;&lt;br /&gt;     D liLength        S              5I 0&lt;br /&gt;&lt;br /&gt;      * Update byte count with length of data to be written&lt;br /&gt;&lt;br /&gt;     C     ' '           CHECKR    iaOutput      liLength&lt;br /&gt;     C                   EVAL      wiChrCount= wiChrCount + liLength + 2&lt;br /&gt;&lt;br /&gt;      * Output data to work file&lt;br /&gt;&lt;br /&gt;     C                   EVAL      saOutput = %trimr(iaOutput)&lt;br /&gt;     C                   WRITE     cvtwork01     OutputData&lt;br /&gt;&lt;br /&gt;     P WritePDF        E&lt;br /&gt;&lt;br /&gt;      **********************************************************************&lt;br /&gt;      * Procedure to convert a number to text                              *&lt;br /&gt;      **********************************************************************&lt;br /&gt;&lt;br /&gt;     P NumToText       B&lt;br /&gt;&lt;br /&gt;     D NumToText       PI            10A&lt;br /&gt;     D    iiNum                      10I 0 CONST&lt;br /&gt;&lt;br /&gt;     D laSign          S              1A&lt;br /&gt;     D laInput         S             10A&lt;br /&gt;     D laOutput        S             10A&lt;br /&gt;     D liIn            S              5I 0&lt;br /&gt;     D liOut           S              5I 0&lt;br /&gt;     D liNum           S             10I 0&lt;br /&gt;&lt;br /&gt;      * Set up sign if and make number positive if number is negative&lt;br /&gt;&lt;br /&gt;     C                   IF        iiNum &lt; 0&lt;br /&gt;     C                   EVAL      laSign = '-'&lt;br /&gt;     C                   EVAL      liNum = -iiNum&lt;br /&gt;     C                   ELSE&lt;br /&gt;     C                   EVAL      laSign = ' '&lt;br /&gt;     C                   EVAL      liNum = iiNum&lt;br /&gt;     C                   ENDIF&lt;br /&gt;&lt;br /&gt;      * Number number to work character variable&lt;br /&gt;&lt;br /&gt;     C                   MOVE      liNum         laInput&lt;br /&gt;&lt;br /&gt;      * Skip over leading zeros&lt;br /&gt;&lt;br /&gt;     C                   EVAL      liIn  = 1&lt;br /&gt;     C                   EVAL      liOut = 1&lt;br /&gt;     C                   DOW           liIn &lt; %size(laInput)&lt;br /&gt;     C                             and %subst(laInput:liIn:1) = '0'&lt;br /&gt;     C                   EVAL      liIn = liIn + 1&lt;br /&gt;     C                   ENDDO&lt;br /&gt;&lt;br /&gt;      * Move digits to output area&lt;br /&gt;&lt;br /&gt;     C                   DOW           liIn  &lt;= %size(laInput)&lt;br /&gt;     C                             and liOut &lt;= %size(laOutput)&lt;br /&gt;     C                   EVAL        %subst(laOutput:liOut:1)&lt;br /&gt;     C                             = %subst(laInput :liIn :1)&lt;br /&gt;     C                   EVAL      liIn  = liIn  + 1&lt;br /&gt;     C                   EVAL      liOut = liOut + 1&lt;br /&gt;     C                   ENDDO&lt;br /&gt;&lt;br /&gt;      * Add sign&lt;br /&gt;&lt;br /&gt;     C                   IF        laSign = '-'&lt;br /&gt;     C                   EVAL      laOutput = laSign + laOutput&lt;br /&gt;     C                   ENDIF&lt;br /&gt;&lt;br /&gt;      * Return number in text format&lt;br /&gt;&lt;br /&gt;     C                   RETURN    laOutput&lt;br /&gt;&lt;br /&gt;     P NumToText       E&lt;br /&gt;&lt;br /&gt;      **********************************************************************&lt;br /&gt;      * Procedure to add an escape character before special characters     *&lt;br /&gt;      **********************************************************************&lt;br /&gt;&lt;br /&gt;     P AddEscape       B&lt;br /&gt;&lt;br /&gt;     D AddEscape       PI           378A&lt;br /&gt;     D   iaInput                    378A&lt;br /&gt;&lt;br /&gt;     D laOutput        S            378A&lt;br /&gt;     D laChar          S              1A&lt;br /&gt;     D i               S              5I 0&lt;br /&gt;     D o               S              5I 0&lt;br /&gt;     D liLength        S              5I 0&lt;br /&gt;&lt;br /&gt;      * Determine length of input data&lt;br /&gt;&lt;br /&gt;     C     ' '           CHECKR    iaInput       liLength&lt;br /&gt;&lt;br /&gt;      * Work through input data and prefix special characters with escape&lt;br /&gt;&lt;br /&gt;     C                   EVAL      i = 1&lt;br /&gt;     C                   EVAL      o = 0&lt;br /&gt;     C                   DOW       i &lt;= liLength&lt;br /&gt;&lt;br /&gt;     C                   EVAL      laChar = %subst(iaInput:i:1)&lt;br /&gt;     C                   IF        laChar = '\' or laChar = '(' or laChar = ')'&lt;br /&gt;     C                   EVAL      o = o + 1&lt;br /&gt;     C                   EVAL      %subst(laOutput:o:1) = '\'&lt;br /&gt;     C                   ENDIF&lt;br /&gt;     C                   EVAL      o = o + 1&lt;br /&gt;     C                   EVAL      %subst(laOutput:o:1) = laChar&lt;br /&gt;     C                   EVAL      i = i + 1&lt;br /&gt;     C                   ENDDO&lt;br /&gt;&lt;br /&gt;     C                   RETURN    laOutput&lt;br /&gt;&lt;br /&gt;     P AddEscape       E&lt;br /&gt;&lt;br /&gt;      **********************************************************************&lt;br /&gt;      * Procedure to create a new page object                              *&lt;br /&gt;      **********************************************************************&lt;br /&gt;&lt;br /&gt;     P NewPage         B&lt;br /&gt;&lt;br /&gt;     D NewPage         PI&lt;br /&gt;&lt;br /&gt;      * Create a page object&lt;br /&gt;&lt;br /&gt;     C                   EVAL      wiPage = wiPage + 1&lt;br /&gt;     C                   CALLP     NewObject&lt;br /&gt;&lt;br /&gt;     C                   CALLP     WritePDF(%trim(NumToText(wiObject))+' 0 obj')&lt;br /&gt;     C                   CALLP     WritePDF('&lt;&lt;')&lt;br /&gt;     C                   CALLP     WritePDF('/Type /Page')&lt;br /&gt;     C                   CALLP     WritePDF('/Parent 5 0 R')&lt;br /&gt;     C                   CALLP     WritePDF(  '/Resources &lt;&lt; /Font &lt;&lt;'&lt;br /&gt;     C                                      + ' /F1 4 0 R &gt;&gt;'&lt;br /&gt;     C                                      + ' /ProcSet 3 0 R &gt;&gt;')&lt;br /&gt;     C                   CALLP     WritePDF('/MediaBox [0 0 792 612]')&lt;br /&gt;     C                   CALLP     WritePDF(  '/Contents '&lt;br /&gt;     C                                      + %trim(NumToText(wiObject+1))&lt;br /&gt;     C                                      + ' 0 R')&lt;br /&gt;     C                   CALLP     WritePDF('&gt;&gt;')&lt;br /&gt;     C                   CALLP     WritePDF('endobj')&lt;br /&gt;&lt;br /&gt;      * Set up bookmark if *PAGNBR option specified&lt;br /&gt;&lt;br /&gt;     C                   IF        paBookmark = '*PAGNBR'&lt;br /&gt;     C                   EVAL      waBookmark = 'Page '&lt;br /&gt;     C                                        + %trim(NumToText(wiPage))&lt;br /&gt;     C                   ELSE&lt;br /&gt;     C                   EVAL      waBookmark = *BLANKS&lt;br /&gt;     C                   EVAL      wiOccurs   = 0&lt;br /&gt;     C                   ENDIF&lt;br /&gt;&lt;br /&gt;      * Create a stream object&lt;br /&gt;&lt;br /&gt;     C                   CALLP     NewObject&lt;br /&gt;&lt;br /&gt;     C                   CALLP     WritePDF(%trim(NumToText(wiObject))+' 0 obj')&lt;br /&gt;     C                   CALLP     WritePDF(  '&lt;&lt; /Length '&lt;br /&gt;     C                                      + %trim(NumToText(wiObject+1))&lt;br /&gt;     C                                      + ' 0 R &gt;&gt;')&lt;br /&gt;     C                   CALLP     WritePDF('stream')&lt;br /&gt;     C                   EVAL      wiStart = wiChrCount&lt;br /&gt;     C                   CALLP     WritePDF('BT')&lt;br /&gt;&lt;br /&gt;      * Determine font size to use from Characters per inch setting&lt;br /&gt;&lt;br /&gt;     C                   SELECT&lt;br /&gt;     C                   WHEN      siCPI = 50&lt;br /&gt;     C                   CALLP     WritePDF('/F1 20 Tf')&lt;br /&gt;     C                   WHEN      siCPI = 120&lt;br /&gt;     C                   CALLP     WritePDF('/F1 9 Tf')&lt;br /&gt;     C                   WHEN      siCPI = 150&lt;br /&gt;     C                   CALLP     WritePDF('/F1 8 Tf')&lt;br /&gt;     C                   WHEN      siCPI = 167&lt;br /&gt;     C                   CALLP     WritePDF('/F1 6 Tf')&lt;br /&gt;     C                   OTHER&lt;br /&gt;     C                   CALLP     WritePDF('/F1 10 Tf')&lt;br /&gt;     C                   ENDSL&lt;br /&gt;&lt;br /&gt;     P NewPage         E&lt;br /&gt;&lt;br /&gt;      **********************************************************************&lt;br /&gt;      * Procedure to finish a page object                                  *&lt;br /&gt;      **********************************************************************&lt;br /&gt;&lt;br /&gt;     P EndPage         B&lt;br /&gt;&lt;br /&gt;     D EndPage         PI&lt;br /&gt;&lt;br /&gt;     D liLength        S             10I 0&lt;br /&gt;&lt;br /&gt;      * End text stream&lt;br /&gt;&lt;br /&gt;     C                   CALLP     WritePDF('ET')&lt;br /&gt;     C                   EVAL      liLength = wiChrCount- wiStart&lt;br /&gt;     C                   CALLP     WritePDF('endstream')&lt;br /&gt;     C                   CALLP     WritePDF('endobj')&lt;br /&gt;&lt;br /&gt;      * Create indirect length object for stream&lt;br /&gt;&lt;br /&gt;     C                   CALLP     NewObject&lt;br /&gt;     C                   CALLP     WritePDF(%trim(NumToText(wiObject))+' 0 obj')&lt;br /&gt;     C                   CALLP     WritePDF(%trim(NumToText(liLength)))&lt;br /&gt;     C                   CALLP     WritePDF('endobj')&lt;br /&gt;&lt;br /&gt;      * Create outline object&lt;br /&gt;&lt;br /&gt;     C                   EVAL      waBookmark = AddEscape(waBookMark)&lt;br /&gt;     C                   CALLP     NewObject&lt;br /&gt;     C                   CALLP     WritePDF(%trim(NumToText(wiObject))+' 0 obj')&lt;br /&gt;     C                   CALLP     WritePDF('&lt;&lt;')&lt;br /&gt;     C                   CALLP     WritePDF('/Parent 2 0 R')&lt;br /&gt;     C                   CALLP     WritePDF(  '/Title  ('&lt;br /&gt;     C                                      + %trimr(waBookmark) + ')')&lt;br /&gt;     C                   IF        wiPage &gt; 1&lt;br /&gt;     C                   CALLP     WritePDF(  '/Prev '&lt;br /&gt;     C                                      + %trim(NumToText(wiObject-4))&lt;br /&gt;     C                                      + ' 0 R')&lt;br /&gt;     C                   ENDIF&lt;br /&gt;     C                   IF        wiPage &lt; siPages&lt;br /&gt;     C                   CALLP     WritePDF(  '/Next '&lt;br /&gt;     C                                      + %trim(NumToText(wiObject+4))&lt;br /&gt;     C                                      + ' 0 R')&lt;br /&gt;     C                   ENDIF&lt;br /&gt;     C                   CALLP     WritePDF('/Dest ['&lt;br /&gt;     C                                      + %trim(NumToText(wiObject-3))&lt;br /&gt;     C                                      + ' 0 R /XYZ 0 792 0]')&lt;br /&gt;     C                   CALLP     WritePDF('&gt;&gt;')&lt;br /&gt;     C                   CALLP     WritePDF('endobj')&lt;br /&gt;&lt;br /&gt;     P EndPage         E&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8909486560224298250-7384344134771843288?l=prabhatmohapatra.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://prabhatmohapatra.blogspot.com/feeds/7384344134771843288/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://prabhatmohapatra.blogspot.com/2009/10/conversion-of-as400-reports-to-pdf.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8909486560224298250/posts/default/7384344134771843288'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8909486560224298250/posts/default/7384344134771843288'/><link rel='alternate' type='text/html' href='http://prabhatmohapatra.blogspot.com/2009/10/conversion-of-as400-reports-to-pdf.html' title='Conversion of AS400 reports to PDF files'/><author><name>Prabhat</name><uri>http://www.blogger.com/profile/14496453689733819797</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8909486560224298250.post-2792845157680175724</id><published>2009-10-09T02:47:00.000-07:00</published><updated>2009-10-09T02:52:18.015-07:00</updated><title type='text'>Converting AS400 reports to PDF</title><content type='html'>The way we can do aconversion of the  spool files to PDF filesis not at all difficult task now in AS400.&lt;br /&gt;&lt;br /&gt;Convert your spooled files to .HTML or .PDF to display on your intranet. Why put together inter-office packets of daily reports when you can email the reports to each user automatically every end-of-day in both .PDF and .HTML formats. &lt;br /&gt;  &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;******************************************************************&lt;br /&gt;     H&lt;br /&gt;&lt;br /&gt;      * Work files&lt;br /&gt;&lt;br /&gt;     Fcvtwork02 IF   F  382        DISK&lt;br /&gt;&lt;br /&gt;     Fcvtwork01 UF A F  378        DISK&lt;br /&gt;&lt;br /&gt;      * Program parameter - report title&lt;br /&gt;&lt;br /&gt;     D paTitle         S             50A&lt;br /&gt;&lt;br /&gt;      * Program parameter - spooled file information returned by API&lt;br /&gt;&lt;br /&gt;     D SplInfo         DS&lt;br /&gt;     D  saReturned                   10I 0&lt;br /&gt;     D  saAvailabl                   10I 0&lt;br /&gt;     D  saIntJobId                   16A&lt;br /&gt;     D  saSplfId                     16A&lt;br /&gt;     D  saJobName                    10A&lt;br /&gt;     D  saUser                       10A&lt;br /&gt;     D  saJobNbr                      6A&lt;br /&gt;     D  saSplFile                    10A&lt;br /&gt;     D  saSplNbr                     10I 0&lt;br /&gt;     D  saFormType                   10A&lt;br /&gt;     D  saUsrDta                     10A&lt;br /&gt;     D  saStatus                     10A&lt;br /&gt;     D  saFilAvail                   10A&lt;br /&gt;     D  saHold                       10A&lt;br /&gt;     D  saSave                       10A&lt;br /&gt;     D  siPages                      10I 0&lt;br /&gt;     D  siCurrPage                   10I 0&lt;br /&gt;     D  siFromPage                   10I 0&lt;br /&gt;     D  siToPage                     10I 0&lt;br /&gt;     D  siLastPage                   10I 0&lt;br /&gt;     D  siRestart                    10I 0&lt;br /&gt;     D  siCopies                     10I 0&lt;br /&gt;     D  siCopyRem                    10I 0&lt;br /&gt;     D  siLPI                        10I 0&lt;br /&gt;     D  siCPI                        10I 0&lt;br /&gt;     D  siOutPty                      2A&lt;br /&gt;     D  saOutq                       10A&lt;br /&gt;     D  saOutqLib                    10A&lt;br /&gt;     D  saOpenDate                    7A&lt;br /&gt;     D  saOpenTime                    6A&lt;br /&gt;     D  saPrtFile                    10A&lt;br /&gt;     D  saPrtfLib                    10A&lt;br /&gt;     D  saPgmName                    10A&lt;br /&gt;     D  saPgmLib                     10A&lt;br /&gt;     D  saAcgCode                    15A&lt;br /&gt;     D  saPrtTxt                     30A&lt;br /&gt;     D  siRcdLen                     10I 0&lt;br /&gt;     D  siMaxRcds                    10I 0&lt;br /&gt;     D  saDevType                    10A&lt;br /&gt;     D  saPrtType                    10A&lt;br /&gt;     D  saDocName                    12A&lt;br /&gt;     D  saFlrName                    64A&lt;br /&gt;     D  saS36Proc                     8A&lt;br /&gt;     D  saFidelity                   10A&lt;br /&gt;     D  saRplUnprt                    1A&lt;br /&gt;     D  saRplChar                     1A&lt;br /&gt;     D  siPageLen                    10I 0&lt;br /&gt;     D  siPageWdth                   10I 0&lt;br /&gt;     D  siSepartrs                   10I 0&lt;br /&gt;     D  siOvrFlw                     10I 0&lt;br /&gt;     D  saDBCS                       10A&lt;br /&gt;     D  saDBCSExt                    10A&lt;br /&gt;     D  saDBCSSOSI                   10A&lt;br /&gt;     D  saDBCSRotn                   10A&lt;br /&gt;     D  saDBCSCPI                    10I 0&lt;br /&gt;     D  saGraphics                   10A&lt;br /&gt;     D  saCodePage                   10A&lt;br /&gt;     D  saFormDf                     10A&lt;br /&gt;     D  saFormDfLb                   10A&lt;br /&gt;     D  siDrawer                     10I 0&lt;br /&gt;     D  saFont                       10A&lt;br /&gt;     D  saS36SplId                    6A&lt;br /&gt;     D  siRotation                   10I 0&lt;br /&gt;     D  siJustify                    10I 0&lt;br /&gt;     D  saDuplex                     10A&lt;br /&gt;     D  saFoldRcds                   10A&lt;br /&gt;     D  saCtlChar                    10A&lt;br /&gt;     D  saAlign                      10A&lt;br /&gt;     D  saPrtQlty                    10A&lt;br /&gt;     D  saFormFeed                   10A&lt;br /&gt;     D  saVolumes                    71A&lt;br /&gt;     D  saLabels                     17A&lt;br /&gt;     D  saExchange                   10A&lt;br /&gt;     D  saCharCode                   10A&lt;br /&gt;     D  siTotRcds                    10I 0&lt;br /&gt;     D  siMultiUp                    10I 0&lt;br /&gt;     D  saFrontOvl                   10A&lt;br /&gt;     D  saFrtOvlLb                   10A&lt;br /&gt;     D  snFOOffDwn                   15P 5&lt;br /&gt;     D  snFOOffAcr                   15P 5&lt;br /&gt;     D  saBackOvl                    10A&lt;br /&gt;     D  saBckOvlLb                   10A&lt;br /&gt;     D  snBOOffDwn                   15P 5&lt;br /&gt;     D  snBOOffAcr                   15P 5&lt;br /&gt;     D  saUOM                        10A&lt;br /&gt;     D  saPagDfn                     10A&lt;br /&gt;     D  saPagDfnLb                   10A&lt;br /&gt;     D  saSpacing                    10A&lt;br /&gt;     D  snPointSiz                   15P 5&lt;br /&gt;     D  snFMOffDwn                   15P 5&lt;br /&gt;     D  snFMOffAcr                   15P 5&lt;br /&gt;     D  snBMOffDwn                   15P 5&lt;br /&gt;     D  snBMOffAcr                   15P 5&lt;br /&gt;     D  snPageLen                    15P 5&lt;br /&gt;     D  snPageWdth                   15P 5&lt;br /&gt;     D  saMethod                     10A&lt;br /&gt;     D  saAFP                         1A&lt;br /&gt;     D  saChrSet                     10A&lt;br /&gt;     D  saChrSetLb                   10A&lt;br /&gt;     D  saCdePagNm                   10A&lt;br /&gt;     D  saCdePgeLb                   10A&lt;br /&gt;     D  saCdeFnt                     10A&lt;br /&gt;     D  saCdeFntLb                   10A&lt;br /&gt;     D  saDBCSFnt                    10A&lt;br /&gt;     D  saDBCSFntL                   10A&lt;br /&gt;     D  saUserDef                    10A&lt;br /&gt;     D  saReduce                     10A&lt;br /&gt;     D  saReserv1                     1A&lt;br /&gt;     D  siOutBin                     10I 0&lt;br /&gt;     D  siCCSID                      10I 0&lt;br /&gt;     D  saUserText                  100A&lt;br /&gt;     D  saSystem                      8A&lt;br /&gt;     D  saOrigId                      8A&lt;br /&gt;     D  saCreator                    10A&lt;br /&gt;&lt;br /&gt;      * Program parameter - bookmark option&lt;br /&gt;&lt;br /&gt;     D paBookmark      S              7A&lt;br /&gt;&lt;br /&gt;      * Program parameter - bookmark *POS option parameters&lt;br /&gt;&lt;br /&gt;     D BMarkPos        DS&lt;br /&gt;     D   siPosCount                   5I 0&lt;br /&gt;     D   snPosLine                    3P 0&lt;br /&gt;     D   snPosChar                    3P 0&lt;br /&gt;     D   snPosLen                     3P 0&lt;br /&gt;&lt;br /&gt;      * Program parameter - bookmark *KEY option parameters&lt;br /&gt;&lt;br /&gt;     D BMarkKey        DS&lt;br /&gt;     D   siKeyCount                   5I 0&lt;br /&gt;     D   siLen                        5I 0&lt;br /&gt;     D   saKeyStr                   378A&lt;br /&gt;     D   snKeyOccur                   3P 0&lt;br /&gt;     D   snKeyOff                     3P 0&lt;br /&gt;     D   snKeyLen                     3P 0&lt;br /&gt;&lt;br /&gt;      * PDF 'object' array&lt;br /&gt;&lt;br /&gt;     D aiObject        S             10I 0 DIM(32767)&lt;br /&gt;&lt;br /&gt;      * Start position of PDF options&lt;br /&gt;&lt;br /&gt;     D aaStart         S             10A   DIM(32767)&lt;br /&gt;&lt;br /&gt;      * Current object number&lt;br /&gt;&lt;br /&gt;     D wiObject        S             10I 0&lt;br /&gt;&lt;br /&gt;      * Current count of bytes written&lt;br /&gt;&lt;br /&gt;     D wiChrCount      S             10I 0&lt;br /&gt;&lt;br /&gt;      * Current page number&lt;br /&gt;&lt;br /&gt;     D wiPage          S             10I 0&lt;br /&gt;&lt;br /&gt;      * Start position of text&lt;br /&gt;&lt;br /&gt;     D wiStart         S             10I 0&lt;br /&gt;&lt;br /&gt;      * Bookmark text&lt;br /&gt;&lt;br /&gt;     D waBookmark      S            378A&lt;br /&gt;&lt;br /&gt;      * Count of occurrences of the bookmark key&lt;br /&gt;&lt;br /&gt;     D wiOccurs        S              5I 0&lt;br /&gt;&lt;br /&gt;      * Input spooled file data including control characters&lt;br /&gt;&lt;br /&gt;     D InputData       DS&lt;br /&gt;     D   saSkipLine                   3A&lt;br /&gt;     D   ssSkipLine                   3S 0 OVERLAY(saSkipLine:1)&lt;br /&gt;     D   saSpceLine                   1A&lt;br /&gt;     D   ssSpceLine                   1S 0 OVERLAY(saSpceLine:1)&lt;br /&gt;     D   saInput                    378A&lt;br /&gt;&lt;br /&gt;      * Output PDF-format data&lt;br /&gt;&lt;br /&gt;     D OutputData      DS&lt;br /&gt;     D   saOutput                   378A&lt;br /&gt;&lt;br /&gt;      * Procedure prototypes&lt;br /&gt;&lt;br /&gt;     D WritePDF        PR&lt;br /&gt;     D   iaOutput                   378A   CONST OPTIONS(*VARSIZE)&lt;br /&gt;&lt;br /&gt;     D AddEscape       PR           378A&lt;br /&gt;     D   iaInput                    378A&lt;br /&gt;&lt;br /&gt;     D PDFHeader       PR&lt;br /&gt;&lt;br /&gt;     D PDFPages        PR&lt;br /&gt;&lt;br /&gt;     D PDFTrailer      PR&lt;br /&gt;&lt;br /&gt;     D NewPage         PR&lt;br /&gt;&lt;br /&gt;     D EndPage         PR&lt;br /&gt;&lt;br /&gt;     D NumToText       PR            10A&lt;br /&gt;     D    iiNum                      10I 0 CONST&lt;br /&gt;&lt;br /&gt;     D NewObject       PR&lt;br /&gt;&lt;br /&gt;      * Program parameters&lt;br /&gt;&lt;br /&gt;     C     *ENTRY        PLIST&lt;br /&gt;     C                   PARM                    paTitle&lt;br /&gt;     C                   PARM                    SplInfo&lt;br /&gt;     C                   PARM                    paBookmark&lt;br /&gt;     C                   PARM                    BMarkPos&lt;br /&gt;     C                   PARM                    BMarkKey&lt;br /&gt;&lt;br /&gt;      * Output a PDF header&lt;br /&gt;&lt;br /&gt;     C                   CALLP     PDFHeader&lt;br /&gt;&lt;br /&gt;      * Create PDF page 'objects'&lt;br /&gt;&lt;br /&gt;     C                   CALLP     PDFPages&lt;br /&gt;&lt;br /&gt;      * Output a PDF trailer&lt;br /&gt;&lt;br /&gt;     C                   CALLP     PDFTrailer&lt;br /&gt;&lt;br /&gt;     C                   RETURN&lt;br /&gt;&lt;br /&gt;      **********************************************************************&lt;br /&gt;      * Procedure to create a PDF 'header'                                 *&lt;br /&gt;      **********************************************************************&lt;br /&gt;&lt;br /&gt;     P PDFHeader       B&lt;br /&gt;&lt;br /&gt;     D PDFHeader       PI&lt;br /&gt;&lt;br /&gt;     D liPage          S             10I 0&lt;br /&gt;     D liPageObj       S             10I 0&lt;br /&gt;&lt;br /&gt;      * Create catalog object&lt;br /&gt;&lt;br /&gt;     C                   CALLP     WritePDF('%PDF-1.0')&lt;br /&gt;     C                   CALLP     WritePDF('%âãÏÓ')&lt;br /&gt;     C                   CALLP     NewObject&lt;br /&gt;     C                   CALLP     WritePDF(%trim(NumToText(wiObject))+' 0 obj')&lt;br /&gt;     C                   CALLP     WritePDF('&lt;&lt;')&lt;br /&gt;     C                   CALLP     WritePDF('/Type /Catalog')&lt;br /&gt;     C                   CALLP     WritePDF('/Pages 5 0 R')&lt;br /&gt;     C                   CALLP     WritePDF('/Outlines 2 0 R')&lt;br /&gt;     C                   CALLP     WritePDF('/PageMode /UseOutlines')&lt;br /&gt;     C                   CALLP     WritePDF('&gt;&gt;')&lt;br /&gt;     C                   CALLP     WritePDF('endobj')&lt;br /&gt;&lt;br /&gt;      * Create outlines object&lt;br /&gt;&lt;br /&gt;     C                   CALLP     NewObject&lt;br /&gt;     C                   CALLP     WritePDF(%trim(NumToText(wiObject))+' 0 obj')&lt;br /&gt;     C                   CALLP     WritePDF('&lt;&lt;')&lt;br /&gt;     C                   CALLP     WritePDF('/Type /Outlines')&lt;br /&gt;     C                   CALLP     WritePDF('/Count '+%trim(NumToText(siPages)))&lt;br /&gt;     C                   CALLP     WritePDF(  '/First 9 0 R')&lt;br /&gt;     C&lt;br /&gt;     C                   CALLP     WritePDF(  '/Last  '&lt;br /&gt;     C                                      + %trim(NumToText((siPages*4)+5))&lt;br /&gt;     C                                      + ' 0 R')&lt;br /&gt;     C                   CALLP     WritePDF('&gt;&gt;')&lt;br /&gt;     C                   CALLP     WritePDF('endobj')&lt;br /&gt;&lt;br /&gt;      * Create procedures object&lt;br /&gt;&lt;br /&gt;     C                   CALLP     NewObject&lt;br /&gt;     C                   CALLP     WritePDF(%trim(NumToText(wiObject))+' 0 obj')&lt;br /&gt;     C                   CALLP     WritePDF('[/PDF /Text]')&lt;br /&gt;     C                   CALLP     WritePDF('endobj')&lt;br /&gt;&lt;br /&gt;      * Create fonts object&lt;br /&gt;&lt;br /&gt;     C                   CALLP     NewObject&lt;br /&gt;     C                   CALLP     WritePDF(%trim(NumToText(wiObject))+' 0 obj')&lt;br /&gt;     C                   CALLP     WritePDF('&lt;&lt;')&lt;br /&gt;     C                   CALLP     WritePDF ('/Type /Font')&lt;br /&gt;     C                   CALLP     WritePDF ('/Subtype /Type1')&lt;br /&gt;     C                   CALLP     WritePDF ('/Name /F1')&lt;br /&gt;     C                   CALLP     WritePDF ('/BaseFont /Courier')&lt;br /&gt;     C                   CALLP     WritePDF ('/Encoding /WinAnsiEncoding')&lt;br /&gt;     C                   CALLP     WritePDF ('&gt;&gt;')&lt;br /&gt;     C                   CALLP     WritePDF ('endobj')&lt;br /&gt;&lt;br /&gt;      * Create pages object&lt;br /&gt;&lt;br /&gt;     C                   CALLP     NewObject&lt;br /&gt;     C                   CALLP     WritePDF(%trim(NumToText(wiObject))+' 0 obj')&lt;br /&gt;     C                   CALLP     WritePDF ('&lt;&lt;')&lt;br /&gt;     C                   CALLP     WritePDF ('/Type /Pages')&lt;br /&gt;     C                   CALLP     WritePDF('/Count '+%trim(NumToText(siPages)))&lt;br /&gt;&lt;br /&gt;      * Write list of child pages&lt;br /&gt;&lt;br /&gt;     C                   EVAL      liPage    = wiObject + 1&lt;br /&gt;     C                   EVAL      liPageObj = liPage&lt;br /&gt;     C                   CALLP     WritePDF (  '/Kids ['&lt;br /&gt;     C                                       + %trim(NumToText(liPage))&lt;br /&gt;     C                                       + ' 0 R')&lt;br /&gt;&lt;br /&gt;     C                   DOW       liPage &lt; siPages + wiObject&lt;br /&gt;     C                   EVAL      liPage = liPage + 1&lt;br /&gt;     C                   EVAL      liPageObj = liPageObj + 4&lt;br /&gt;     C                   CALLP     WritePDF (  '       '&lt;br /&gt;     C                                       + %trim(NumToText(liPageObj))&lt;br /&gt;     C                                       + ' 0 R')&lt;br /&gt;     C                   ENDDO&lt;br /&gt;&lt;br /&gt;     C                   CALLP     WritePDF ('       ]')&lt;br /&gt;&lt;br /&gt;     C                   CALLP     WritePDF ('&gt;&gt;')&lt;br /&gt;     C                   CALLP     WritePDF ('endobj')&lt;br /&gt;&lt;br /&gt;     P PDFHeader       E&lt;br /&gt;&lt;br /&gt;      **********************************************************************&lt;br /&gt;      * Procedure to create PDF pages                                      *&lt;br /&gt;      **********************************************************************&lt;br /&gt;&lt;br /&gt;     P PDFPages        B&lt;br /&gt;&lt;br /&gt;     D liLine          S             10I 0&lt;br /&gt;     D liLength        S              5I 0&lt;br /&gt;     D liChar          S              5I 0&lt;br /&gt;     D liX             S              5I 0&lt;br /&gt;     D liY             S              5I 0&lt;br /&gt;&lt;br /&gt;      * Create page object for first page&lt;br /&gt;&lt;br /&gt;     C                   EVAL      wiPage = 0&lt;br /&gt;     C                   EVAL      liX = 0&lt;br /&gt;&lt;br /&gt;      * Read spooled file data from input work file&lt;br /&gt;&lt;br /&gt;     C                   READ      cvtwork02     InputData                LR&lt;br /&gt;&lt;br /&gt;     C                   DOW       *INLR = *OFF&lt;br /&gt;&lt;br /&gt;      * Skip to a line if specified, handling page throw if it occurs&lt;br /&gt;&lt;br /&gt;     C                   IF        saSkipLine &lt;&gt; *BLANKS&lt;br /&gt;     C                   IF        ssSkipLine &lt; liLine or liLine = 0&lt;br /&gt;     C                   IF        wiPage &lt;&gt; 0&lt;br /&gt;     C                   CALLP     EndPage&lt;br /&gt;     C                   ENDIF&lt;br /&gt;     C                   CALLP     NewPage&lt;br /&gt;     C                   EVAL      liLine = ssSkipLine&lt;br /&gt;     C                   EVAL        liY&lt;br /&gt;     C                             = (612/siPageLen) * (siPagelen-liLine)&lt;br /&gt;     C                   ELSE&lt;br /&gt;     C                   EVAL        liY&lt;br /&gt;     C                             = -((612/siPageLen) * (ssSkipLine-liLine))&lt;br /&gt;     C                   EVAL      liLine = ssSkipLine&lt;br /&gt;     C                   ENDIF&lt;br /&gt;     C                   ENDIF&lt;br /&gt;&lt;br /&gt;      * Space a number of lines if specified&lt;br /&gt;&lt;br /&gt;     C                   IF        saSpceLine &lt;&gt; *BLANKS&lt;br /&gt;     C                   EVAL      liLine = liLine + ssSpceLine&lt;br /&gt;     C                   EVAL        liY&lt;br /&gt;     C                             = -((612/siPageLen) * ssSpceLine)&lt;br /&gt;     C                   ENDIF&lt;br /&gt;&lt;br /&gt;      * Set up bookmark if position option specified&lt;br /&gt;&lt;br /&gt;     C                   IF        paBookmark = '*POS'&lt;br /&gt;     C                   IF        liLine = snPosLine and waBookmark = *BLANKS&lt;br /&gt;     C                   EVAL      waBookmark = %trim(%subst(saInput  :&lt;br /&gt;     C                                                       snPosChar:&lt;br /&gt;     C                                                       snPosLen ))&lt;br /&gt;     C                   ENDIF&lt;br /&gt;     C                   ENDIF&lt;br /&gt;&lt;br /&gt;      * Set up bookmark if key option specified&lt;br /&gt;&lt;br /&gt;     C                   IF        paBookmark = '*KEY'&lt;br /&gt;     C     saKeyStr:siLenSCAN      saInput:1     liChar&lt;br /&gt;     C                   IF        liChar &gt; 0&lt;br /&gt;     C                   EVAL      wiOccurs = wiOccurs + 1&lt;br /&gt;     C                   IF        wiOccurs = snKeyOccur&lt;br /&gt;     C                   EVAL      liChar = liChar + snKeyOff&lt;br /&gt;     C                   EVAL      liLength = snKeyLen&lt;br /&gt;     C                   IF        liChar + liLength &gt; siPageWdth&lt;br /&gt;     C                   EVAL      liLength = siPageWdth - liChar&lt;br /&gt;     C                   ENDIF&lt;br /&gt;     C                   IF        liChar &lt; 1&lt;br /&gt;     C                   EVAL      liChar = 1&lt;br /&gt;     C                   ENDIF&lt;br /&gt;     C                   IF        liChar + liLength &lt;= siPageWdth&lt;br /&gt;     C                   EVAL      waBookmark = %trim(%subst(saInput  :&lt;br /&gt;     C                                                       liChar   :&lt;br /&gt;     C                                                       liLength ))&lt;br /&gt;     C                   ENDIF&lt;br /&gt;     C                   ENDIF&lt;br /&gt;     C                   ENDIF&lt;br /&gt;     C                   ENDIF&lt;br /&gt;&lt;br /&gt;      * Add escape character before special characters \, ( and )&lt;br /&gt;&lt;br /&gt;     C                   EVAL      saInput = AddEscape(saInput)&lt;br /&gt;&lt;br /&gt;      * Output the line of text&lt;br /&gt;&lt;br /&gt;     C                   CALLP     WritePDF(  %trim(NumToText(liX))&lt;br /&gt;     C                                      + ' '&lt;br /&gt;     C                                      + %trim(NumToText(liY))&lt;br /&gt;     C                                      + ' Td ('&lt;br /&gt;     C                                      + %trimr(saInput)&lt;br /&gt;     C                                      + ') Tj')&lt;br /&gt;&lt;br /&gt;     C                   READ      cvtwork02     InputData                LR&lt;br /&gt;&lt;br /&gt;     C                   ENDDO&lt;br /&gt;&lt;br /&gt;     C                   CALLP     EndPage&lt;br /&gt;&lt;br /&gt;     P PDFPages        E&lt;br /&gt;&lt;br /&gt;      **********************************************************************&lt;br /&gt;      * Procedure to create a PDF trailer                                  *&lt;br /&gt;      **********************************************************************&lt;br /&gt;&lt;br /&gt;     P PDFTrailer      B&lt;br /&gt;&lt;br /&gt;     D PDFTrailer      PI&lt;br /&gt;&lt;br /&gt;     D laDateTime      S             14A&lt;br /&gt;     D i               S             10I 0&lt;br /&gt;     D liXRef          S             10I 0&lt;br /&gt;&lt;br /&gt;      * Create information object&lt;br /&gt;&lt;br /&gt;     C                   CALLP     NewObject&lt;br /&gt;     C                   CALLP     WritePDF(%trim(NumToText(wiObject))+' 0 obj')&lt;br /&gt;     C                   CALLP     WritePDF('&lt;&lt;')&lt;br /&gt;     C                   CALLP     WritePDF(  '/Creator ('&lt;br /&gt;     C                                      + %trim(saPgmLib)&lt;br /&gt;     C                                      + '/'&lt;br /&gt;     C                                      + %trim(saPgmName)&lt;br /&gt;     C                                      + ')' )&lt;br /&gt;     C                   IF        %subst(saOpenDate:1:1) = '0'&lt;br /&gt;     C                   EVAL      laDateTime = '19' + %subst(saOpenDate:2:6)&lt;br /&gt;     C                                               + saOpenTime&lt;br /&gt;     C                   ELSE&lt;br /&gt;     C                   EVAL      laDateTime = '20' + %subst(saOpenDate:2:6)&lt;br /&gt;     C                                               + saOpenTime&lt;br /&gt;     C                   ENDIF&lt;br /&gt;     C                   CALLP     WritePDF(  '/CreationDate (D:'&lt;br /&gt;     C                                      + laDateTime + ')')&lt;br /&gt;     C                   CALLP     WritePDF('/Title (' + %trim(paTitle) + ')')&lt;br /&gt;     C                   CALLP     WritePDF('/Producer (CVTSPLPDF)')&lt;br /&gt;     C                   CALLP     WritePDF('/Keywords ()')&lt;br /&gt;     C                   CALLP     WritePDF(  '/Author ('&lt;br /&gt;     C                                      + %trim(saJobNbr)&lt;br /&gt;     C                                      + '/'&lt;br /&gt;     C                                      + %trim(saUser)&lt;br /&gt;     C                                      + '/'&lt;br /&gt;     C                                      + %trim(saJobName)&lt;br /&gt;     C                                      + ')' )&lt;br /&gt;     C                   CALLP     WritePDF('&gt;&gt;')&lt;br /&gt;     C                   CALLP     WritePDF('endobj')&lt;br /&gt;&lt;br /&gt;      * Create cross-reference&lt;br /&gt;&lt;br /&gt;     C                   EVAL      liXref = wiChrCount - 1&lt;br /&gt;     C                   CALLP     WritePDF('xref 0 '&lt;br /&gt;     C                                      + %trim(NumToText(wiObject+1)) )&lt;br /&gt;     C                   CALLP     WritePDF('0000000000 65535 f')&lt;br /&gt;&lt;br /&gt;     C                   DO        wiObject      i&lt;br /&gt;     C                   CALLP     WritePDF(aaStart(i) + ' 00000 n')&lt;br /&gt;     C                   ENDDO&lt;br /&gt;&lt;br /&gt;      * Write trailer&lt;br /&gt;&lt;br /&gt;     C                   CALLP     WritePDF('trailer')&lt;br /&gt;     C                   CALLP     WritePDF('&lt;&lt;')&lt;br /&gt;     C                   CALLP     WritePDF('/Size '&lt;br /&gt;     C                                      + %trim(NumToText(wiObject+1)))&lt;br /&gt;     C                   CALLP     WritePDF('/Root 1 0 R')&lt;br /&gt;     C                   CALLP     WritePDF('/Info '&lt;br /&gt;     C                                      + %trim(NumToText(wiObject))&lt;br /&gt;     C                                      + ' 0 R')&lt;br /&gt;     C                   CALLP     WritePDF('&gt;&gt;')&lt;br /&gt;     C                   CALLP     WritePDF('startxref')&lt;br /&gt;     C                   CALLP     WritePDF(%trim(NumToText(liXref)))&lt;br /&gt;     C                   CALLP     WritePDF('%%EOF')&lt;br /&gt;&lt;br /&gt;     P PDFTrailer      E&lt;br /&gt;&lt;br /&gt;      **********************************************************************&lt;br /&gt;      * Procedure to create a new PDF 'object'                             *&lt;br /&gt;      **********************************************************************&lt;br /&gt;     P NewObject       B&lt;br /&gt;&lt;br /&gt;     D NewObject       PI&lt;br /&gt;&lt;br /&gt;     D lsDataLen       S             10S 0&lt;br /&gt;     D i               S             10I 0&lt;br /&gt;&lt;br /&gt;     C                   EVAL      wiObject = wiObject + 1&lt;br /&gt;     C                   EVAL      i = wiObject&lt;br /&gt;     C                   EVAL      lsDataLen = wiChrCount&lt;br /&gt;     C                   MOVE      lsDataLen     aaStart(i)&lt;br /&gt;&lt;br /&gt;     P NewObject       E&lt;br /&gt;&lt;br /&gt;      **********************************************************************&lt;br /&gt;      * Procedure to output PDF data&lt;br /&gt;      **********************************************************************&lt;br /&gt;&lt;br /&gt;     P WritePDF        B&lt;br /&gt;&lt;br /&gt;     D WritePDF        PI&lt;br /&gt;     D   iaOutput                   378A   CONST OPTIONS(*VARSIZE)&lt;br /&gt;&lt;br /&gt;     D liLength        S              5I 0&lt;br /&gt;&lt;br /&gt;      * Update byte count with length of data to be written&lt;br /&gt;&lt;br /&gt;     C     ' '           CHECKR    iaOutput      liLength&lt;br /&gt;     C                   EVAL      wiChrCount= wiChrCount + liLength + 2&lt;br /&gt;&lt;br /&gt;      * Output data to work file&lt;br /&gt;&lt;br /&gt;     C                   EVAL      saOutput = %trimr(iaOutput)&lt;br /&gt;     C                   WRITE     cvtwork01     OutputData&lt;br /&gt;&lt;br /&gt;     P WritePDF        E&lt;br /&gt;&lt;br /&gt;      **********************************************************************&lt;br /&gt;      * Procedure to convert a number to text                              *&lt;br /&gt;      **********************************************************************&lt;br /&gt;&lt;br /&gt;     P NumToText       B&lt;br /&gt;&lt;br /&gt;     D NumToText       PI            10A&lt;br /&gt;     D    iiNum                      10I 0 CONST&lt;br /&gt;&lt;br /&gt;     D laSign          S              1A&lt;br /&gt;     D laInput         S             10A&lt;br /&gt;     D laOutput        S             10A&lt;br /&gt;     D liIn            S              5I 0&lt;br /&gt;     D liOut           S              5I 0&lt;br /&gt;     D liNum           S             10I 0&lt;br /&gt;&lt;br /&gt;      * Set up sign if and make number positive if number is negative&lt;br /&gt;&lt;br /&gt;     C                   IF        iiNum &lt; 0&lt;br /&gt;     C                   EVAL      laSign = '-'&lt;br /&gt;     C                   EVAL      liNum = -iiNum&lt;br /&gt;     C                   ELSE&lt;br /&gt;     C                   EVAL      laSign = ' '&lt;br /&gt;     C                   EVAL      liNum = iiNum&lt;br /&gt;     C                   ENDIF&lt;br /&gt;&lt;br /&gt;      * Number number to work character variable&lt;br /&gt;&lt;br /&gt;     C                   MOVE      liNum         laInput&lt;br /&gt;&lt;br /&gt;      * Skip over leading zeros&lt;br /&gt;&lt;br /&gt;     C                   EVAL      liIn  = 1&lt;br /&gt;     C                   EVAL      liOut = 1&lt;br /&gt;     C                   DOW           liIn &lt; %size(laInput)&lt;br /&gt;     C                             and %subst(laInput:liIn:1) = '0'&lt;br /&gt;     C                   EVAL      liIn = liIn + 1&lt;br /&gt;     C                   ENDDO&lt;br /&gt;&lt;br /&gt;      * Move digits to output area&lt;br /&gt;&lt;br /&gt;     C                   DOW           liIn  &lt;= %size(laInput)&lt;br /&gt;     C                             and liOut &lt;= %size(laOutput)&lt;br /&gt;     C                   EVAL        %subst(laOutput:liOut:1)&lt;br /&gt;     C                             = %subst(laInput :liIn :1)&lt;br /&gt;     C                   EVAL      liIn  = liIn  + 1&lt;br /&gt;     C                   EVAL      liOut = liOut + 1&lt;br /&gt;     C                   ENDDO&lt;br /&gt;&lt;br /&gt;      * Add sign&lt;br /&gt;&lt;br /&gt;     C                   IF        laSign = '-'&lt;br /&gt;     C                   EVAL      laOutput = laSign + laOutput&lt;br /&gt;     C                   ENDIF&lt;br /&gt;&lt;br /&gt;      * Return number in text format&lt;br /&gt;&lt;br /&gt;     C                   RETURN    laOutput&lt;br /&gt;&lt;br /&gt;     P NumToText       E&lt;br /&gt;&lt;br /&gt;      **********************************************************************&lt;br /&gt;      * Procedure to add an escape character before special characters     *&lt;br /&gt;      **********************************************************************&lt;br /&gt;&lt;br /&gt;     P AddEscape       B&lt;br /&gt;&lt;br /&gt;     D AddEscape       PI           378A&lt;br /&gt;     D   iaInput                    378A&lt;br /&gt;&lt;br /&gt;     D laOutput        S            378A&lt;br /&gt;     D laChar          S              1A&lt;br /&gt;     D i               S              5I 0&lt;br /&gt;     D o               S              5I 0&lt;br /&gt;     D liLength        S              5I 0&lt;br /&gt;&lt;br /&gt;      * Determine length of input data&lt;br /&gt;&lt;br /&gt;     C     ' '           CHECKR    iaInput       liLength&lt;br /&gt;&lt;br /&gt;      * Work through input data and prefix special characters with escape&lt;br /&gt;&lt;br /&gt;     C                   EVAL      i = 1&lt;br /&gt;     C                   EVAL      o = 0&lt;br /&gt;     C                   DOW       i &lt;= liLength&lt;br /&gt;&lt;br /&gt;     C                   EVAL      laChar = %subst(iaInput:i:1)&lt;br /&gt;     C                   IF        laChar = '\' or laChar = '(' or laChar = ')'&lt;br /&gt;     C                   EVAL      o = o + 1&lt;br /&gt;     C                   EVAL      %subst(laOutput:o:1) = '\'&lt;br /&gt;     C                   ENDIF&lt;br /&gt;     C                   EVAL      o = o + 1&lt;br /&gt;     C                   EVAL      %subst(laOutput:o:1) = laChar&lt;br /&gt;     C                   EVAL      i = i + 1&lt;br /&gt;     C                   ENDDO&lt;br /&gt;&lt;br /&gt;     C                   RETURN    laOutput&lt;br /&gt;&lt;br /&gt;     P AddEscape       E&lt;br /&gt;&lt;br /&gt;      **********************************************************************&lt;br /&gt;      * Procedure to create a new page object                              *&lt;br /&gt;      **********************************************************************&lt;br /&gt;&lt;br /&gt;     P NewPage         B&lt;br /&gt;&lt;br /&gt;     D NewPage         PI&lt;br /&gt;&lt;br /&gt;      * Create a page object&lt;br /&gt;&lt;br /&gt;     C                   EVAL      wiPage = wiPage + 1&lt;br /&gt;     C                   CALLP     NewObject&lt;br /&gt;&lt;br /&gt;     C                   CALLP     WritePDF(%trim(NumToText(wiObject))+' 0 obj')&lt;br /&gt;     C                   CALLP     WritePDF('&lt;&lt;')&lt;br /&gt;     C                   CALLP     WritePDF('/Type /Page')&lt;br /&gt;     C                   CALLP     WritePDF('/Parent 5 0 R')&lt;br /&gt;     C                   CALLP     WritePDF(  '/Resources &lt;&lt; /Font &lt;&lt;'&lt;br /&gt;     C                                      + ' /F1 4 0 R &gt;&gt;'&lt;br /&gt;     C                                      + ' /ProcSet 3 0 R &gt;&gt;')&lt;br /&gt;     C                   CALLP     WritePDF('/MediaBox [0 0 792 612]')&lt;br /&gt;     C                   CALLP     WritePDF(  '/Contents '&lt;br /&gt;     C                                      + %trim(NumToText(wiObject+1))&lt;br /&gt;     C                                      + ' 0 R')&lt;br /&gt;     C                   CALLP     WritePDF('&gt;&gt;')&lt;br /&gt;     C                   CALLP     WritePDF('endobj')&lt;br /&gt;&lt;br /&gt;      * Set up bookmark if *PAGNBR option specified&lt;br /&gt;&lt;br /&gt;     C                   IF        paBookmark = '*PAGNBR'&lt;br /&gt;     C                   EVAL      waBookmark = 'Page '&lt;br /&gt;     C                                        + %trim(NumToText(wiPage))&lt;br /&gt;     C                   ELSE&lt;br /&gt;     C                   EVAL      waBookmark = *BLANKS&lt;br /&gt;     C                   EVAL      wiOccurs   = 0&lt;br /&gt;     C                   ENDIF&lt;br /&gt;&lt;br /&gt;      * Create a stream object&lt;br /&gt;&lt;br /&gt;     C                   CALLP     NewObject&lt;br /&gt;&lt;br /&gt;     C                   CALLP     WritePDF(%trim(NumToText(wiObject))+' 0 obj')&lt;br /&gt;     C                   CALLP     WritePDF(  '&lt;&lt; /Length '&lt;br /&gt;     C                                      + %trim(NumToText(wiObject+1))&lt;br /&gt;     C                                      + ' 0 R &gt;&gt;')&lt;br /&gt;     C                   CALLP     WritePDF('stream')&lt;br /&gt;     C                   EVAL      wiStart = wiChrCount&lt;br /&gt;     C                   CALLP     WritePDF('BT')&lt;br /&gt;&lt;br /&gt;      * Determine font size to use from Characters per inch setting&lt;br /&gt;&lt;br /&gt;     C                   SELECT&lt;br /&gt;     C                   WHEN      siCPI = 50&lt;br /&gt;     C                   CALLP     WritePDF('/F1 20 Tf')&lt;br /&gt;     C                   WHEN      siCPI = 120&lt;br /&gt;     C                   CALLP     WritePDF('/F1 9 Tf')&lt;br /&gt;     C                   WHEN      siCPI = 150&lt;br /&gt;     C                   CALLP     WritePDF('/F1 8 Tf')&lt;br /&gt;     C                   WHEN      siCPI = 167&lt;br /&gt;     C                   CALLP     WritePDF('/F1 6 Tf')&lt;br /&gt;     C                   OTHER&lt;br /&gt;     C                   CALLP     WritePDF('/F1 10 Tf')&lt;br /&gt;     C                   ENDSL&lt;br /&gt;&lt;br /&gt;     P NewPage         E&lt;br /&gt;&lt;br /&gt;      **********************************************************************&lt;br /&gt;      * Procedure to finish a page object                                  *&lt;br /&gt;      **********************************************************************&lt;br /&gt;&lt;br /&gt;     P EndPage         B&lt;br /&gt;&lt;br /&gt;     D EndPage         PI&lt;br /&gt;&lt;br /&gt;     D liLength        S             10I 0&lt;br /&gt;&lt;br /&gt;      * End text stream&lt;br /&gt;&lt;br /&gt;     C                   CALLP     WritePDF('ET')&lt;br /&gt;     C                   EVAL      liLength = wiChrCount- wiStart&lt;br /&gt;     C                   CALLP     WritePDF('endstream')&lt;br /&gt;     C                   CALLP     WritePDF('endobj')&lt;br /&gt;&lt;br /&gt;      * Create indirect length object for stream&lt;br /&gt;&lt;br /&gt;     C                   CALLP     NewObject&lt;br /&gt;     C                   CALLP     WritePDF(%trim(NumToText(wiObject))+' 0 obj')&lt;br /&gt;     C                   CALLP     WritePDF(%trim(NumToText(liLength)))&lt;br /&gt;     C                   CALLP     WritePDF('endobj')&lt;br /&gt;&lt;br /&gt;      * Create outline object&lt;br /&gt;&lt;br /&gt;     C                   EVAL      waBookmark = AddEscape(waBookMark)&lt;br /&gt;     C                   CALLP     NewObject&lt;br /&gt;     C                   CALLP     WritePDF(%trim(NumToText(wiObject))+' 0 obj')&lt;br /&gt;     C                   CALLP     WritePDF('&lt;&lt;')&lt;br /&gt;     C                   CALLP     WritePDF('/Parent 2 0 R')&lt;br /&gt;     C                   CALLP     WritePDF(  '/Title  ('&lt;br /&gt;     C                                      + %trimr(waBookmark) + ')')&lt;br /&gt;     C                   IF        wiPage &gt; 1&lt;br /&gt;     C                   CALLP     WritePDF(  '/Prev '&lt;br /&gt;     C                                      + %trim(NumToText(wiObject-4))&lt;br /&gt;     C                                      + ' 0 R')&lt;br /&gt;     C                   ENDIF&lt;br /&gt;     C                   IF        wiPage &lt; siPages&lt;br /&gt;     C                   CALLP     WritePDF(  '/Next '&lt;br /&gt;     C                                      + %trim(NumToText(wiObject+4))&lt;br /&gt;     C                                      + ' 0 R')&lt;br /&gt;     C                   ENDIF&lt;br /&gt;     C                   CALLP     WritePDF('/Dest ['&lt;br /&gt;     C                                      + %trim(NumToText(wiObject-3))&lt;br /&gt;     C                                      + ' 0 R /XYZ 0 792 0]')&lt;br /&gt;     C                   CALLP     WritePDF('&gt;&gt;')&lt;br /&gt;     C                   CALLP     WritePDF('endobj')&lt;br /&gt;&lt;br /&gt;     P EndPage         E&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8909486560224298250-2792845157680175724?l=prabhatmohapatra.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://prabhatmohapatra.blogspot.com/feeds/2792845157680175724/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://prabhatmohapatra.blogspot.com/2009/10/converting-as400-reports-to-pdf.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8909486560224298250/posts/default/2792845157680175724'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8909486560224298250/posts/default/2792845157680175724'/><link rel='alternate' type='text/html' href='http://prabhatmohapatra.blogspot.com/2009/10/converting-as400-reports-to-pdf.html' title='Converting AS400 reports to PDF'/><author><name>Prabhat</name><uri>http://www.blogger.com/profile/14496453689733819797</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8909486560224298250.post-253131046524580376</id><published>2009-10-04T20:04:00.000-07:00</published><updated>2009-10-04T20:45:57.581-07:00</updated><title type='text'>Email &amp; SMS Error Notifications from an AS/400</title><content type='html'>An RPGLE program that uses the QUSLJOB API to list any job that is in *MSGW status and then send an email with the details of the job’s error using SNDDST. The program only has the capability to send to one email address yet I wanted to send it to an email distribution list on our Exchange server as well as send a text message to my phone for after hours support. The program also sent EVERY job in *MSGW, including any printer alignment messages. With my very basic knowledge of RPG I was able to add multiple email address variables and exclude any job that runs in the QSPL subsystem from being included.&lt;br /&gt;Once the program ran to my liking I wrote a simple CL program that would call the program every 5 min and added the CL as an auto start job entry to my subsystem. I’ve had this configuration running for the past 6 months and it’s a great way to stay on top of any jobs that may be holding up QBATCH. Critical system jobs are usually fixed before end users even know something was broken.&lt;br /&gt;&lt;br /&gt;*      * CrtUsrSpc: Create User Space for OS/400 API's      *     d QUSCRTUS        pr                  extpgm('QUSCRTUS')     d   UsrSpc                      20A   const     d   ExtAttr                     10A   const     d   InitialSize                 10I 0 const     d   InitialVal                   1A   const     d   PublicAuth                  10A   const     d   Text                        50A   const     d   Replace                     10A   const     d   ErrorCode                32766A   options(*nopass: *varsize)      *      * --- Prototype for API Retrive User Space      *     d QUSRTVUS        pr                  extpgm( 'QUSRTVUS' )     d   QRtvUserSpace...     d                               20     d   QRtvStartingPosition...     d                                8b 0     d   QRtvLengthOfData...     d                                8b 0     d   QRtvReceiverVariable...     d                            32048     d   QRtvError...     d                              256&lt;br /&gt;      * --- Prototype for API Retrive List Job      *     d QUSLJOB         pr                  extpgm( 'QUSLJOB' )     d   QJobUserSpace...     d                               20     d   QJobFormatName...     d                                8     d   QJobJobName...     d                               26     d   QFldStatus...     d                               10     d   QFldError...     d                              256     d   QJobType...     d                                1     d   QNbrFldRtn...     d                                8b 0     d   QKeyFldRtn...     d                                8b 0 dim( 100 )      *     d qcmdexc         pr                  extpgm( 'QCMDEXC' )     d   os400_cmd                 2000A   options( *varsize ) const     d   cmdlength                   15P 5                     const      *      * Defined variables      *     d emailaddress    s             24    inz(&lt;a href="mailto:"&gt;'podmaster@chemicalali.com'&lt;/a&gt;)     d size            s             10I 0     d UsrSpcName      s             20    inz( 'DSPJOB    QTEMP     ' )&lt;br /&gt;      *      ******************************************************************&lt;br /&gt;     dQUSA0100         DS     d QUsrSpcOffset...     d                         1      4B 0     d QUsrSpcEntries...     d                         9     12B 0     d QUsrSpcEntrieSize...     d                        13     16B 0&lt;br /&gt;     dLJOBINPUT        ds                           qualified     d  JobName...     d                         1     10     d  UserName...     d                        11     20     d  JobNumber...     d                        21     26     d  Status...     d                        27     36     d  UserSpace...     d                        37     46     d  UserSpaceLibrary...     d                        47     56     d  Format...     d                        57     64     d  JobType...     d                        65     65     d  Reserved01...     d                        66     68     d  Reserved02...     d                        69     72B 0      *     dLJOB100          ds                           qualified     d  JobName...     d                         1     10     d  UserName...     d                        11     20     d  JobNumber...     d                        21     26     d  InternalJobId...     d                        27     42     d  Status...     d                        43     52     d  JobType...     d                        53     53     d  JobSubType...     d                        54     54     d  Reserved01...     d                        55     56      *     dLJOB200          ds                           qualified     d  JobName...     d                         1     10     d  UserName...     d                        11     20     d  JobNumber...     d                        21     26     d  InternalJobId...     d                        27     42     d  Status...     d                        43     52     d  JobType...     d                        53     53     d  JobSubType...     d                        54     54     d  Reserved01...     d                        55     56     d  JobInfoStatus...     d                        57     57     d  Reserved02...     d                        58     60     d  NumberOfFieldsReturned...     d                        61     64B 0     d  ReturnedData...     d                        65   1064      *     dLJOB200KEY       ds                           qualified     d  KeyNumber01...     d                         1      4B 0     d  NumberOfKeys...     d                         5      8B 0      *     dLJOBKEYINFO      ds                           qualified     d  LengthOfInformation...     d                         1      4b 0     d  KeyField...     d                         5      8b 0     d  TypeOfData...     d                         9      9     d  Reserved01...     d                        10     12     d  LengthOfData...     d                        13     16B 0     d  KeyData...     d                        17   1016      *      *  APIErrDef     Standard API error handling structure.                  *      *     dQUSEC            DS     d  ErrorBytesProvided...     d                         1      4B 0     d  ErrorBytesAvailble...     d                         5      8b 0     d  ErrorExceptionId...     d                         9     15     d  ErrorReserved...     d                        16     16      *     dAPIError         DS     d APIErrorProvied...     d                                     LIKE( ErrorBytesProvided )     d                                     INZ( %LEN( APIError ) )     d APIErrorAvailble...     d                                     LIKE( ErrorBytesAvailble )     d APIErrorMessageID...     d                                     LIKE( ErrorExceptionId )     d APIErrorReserved...     d                                     LIKE( ErrorReserved )     d APIErrorInformation...     d                              240A      *-----------------------------------------------------------------      * program status dataarea      *-----------------------------------------------------------------     d PgmSts         SDS     d   P1User              254    263     d   W1Program       *PROC      *--------------------------------------------------------------*      * work fields                                                  *      *--------------------------------------------------------------*     d Variables       ds     d   Q                            1    inz( '''' )     d   Count                       15  0 inz(  0   )     d   KeyCount                    15  0 inz(  0   )     d   EndPos                      15  0 inz(  0   )     d   JobbStatus                   4    inz( ' '  )     d   Subsystem                   20    inz( ' '  )     d   ReturnCode                   1    inz( ' '  )     d   FormatName                   8    inz( ' ' )     d   QualifedJobName...     d                               26    inz( ' ' )     d   JobStatus                   10    inz( ' ' )     d   JobType                      1    inz( ' ' )     d   NbrOfFldRtn                  8B 0 inz(  0  )     d   KeyFldRtn                    8B 0 inz(  0  ) dim( 100 )     d   StartingPosition...     d                                8B 0 inz(  0  )     d   LengthOfData...     d                                8B 0 inz(  0  )     d   KeyStartingPosition...     d                                8B 0 inz(  0  )     d   KeyLengthOfData...     d                                8B 0 inz(  0  )     d   ReceiverVariable...     d                            32048     d   OS400_Cmd                 2000    inz( ' '  )     d   CmdLength                   15P 5 inz( %size( OS400_Cmd ) )     d   True                         1    inz( *on  )     d   False                        1    inz( *off )      *      /free&lt;br /&gt;       //       // Create a user space       //          size = 10000;&lt;br /&gt;         // Create a user space         QUSCRTUS(UsrSpcName: 'USRSPC': size: x'00': '*ALL':          'Temp User Space for  QUSLJOB API':  '*YES': APIError);&lt;br /&gt;       exsr CheckStatusOfJob;&lt;br /&gt;       *inlr = *on;       // *************************************************************       // check status of an job       // -------------------------------------------------------------       begsr CheckStatusOfJob;&lt;br /&gt;       // run API to fill user space with information about all iSeries job&lt;br /&gt;       FormatName = 'JOBL0200';       QualifedJobName = '*ALL      ' + '*ALL      ' + '*ALL  ';       JobStatus = '*ACTIVE';       JobType = '*';       NbrOfFldRtn = 2;       KeyFldRtn( 1 ) = 0101;       KeyFldRtn( 2 ) = 1906;       callp QUSLJOB( UsrSpcName : FormatName  : QualifedJobName :                      JobStatus  : APIError    :                      JobType    : NbrOfFldRtn : KeyFldRtn         );&lt;br /&gt;        // if error message from the retrieve job API then dump program&lt;br /&gt;       if APIErrorMessageID &lt;&gt; ' ';         dump;         ReturnCode = True;         leavesr;       endif;&lt;br /&gt;       // run API to get user space attribute&lt;br /&gt;       StartingPosition = 125;       LengthOfData = 16;       callp QUSRTVUS( UsrSpcName   : StartingPosition  :                       LengthOfData : ReceiverVariable  :                       APIError                           );       QUSA0100 = ReceiverVariable;&lt;br /&gt;        // if error message from the retrieve user space API then dump program&lt;br /&gt;       if APIErrorMessageID &lt;&gt; ' ';         dump;         ReturnCode = True;         leavesr;       endif;&lt;br /&gt;       // preperation to read from user space&lt;br /&gt;       StartingPosition = QUsrSpcOffset + 1;       LengthOfData = QUsrSpcEntrieSize;&lt;br /&gt;       // read from user space&lt;br /&gt;       for count = 1 to QUsrSpcEntries;         callp QUSRTVUS( UsrSpcName   : StartingPosition  :                         LengthOfData : ReceiverVariable  :                         APIError                           );         LJOB200 = ReceiverVariable;         if APIErrorMessageID &lt;&gt; ' ';           dump;           ReturnCode = True;           leavesr;         endif;&lt;br /&gt;         // check status of job         JobbStatus = ' ';         Subsystem = ' ';         LJobKeyInfo = LJob200.ReturnedData;         KeyStartingPosition = 1;         KeyLengthOfData = LJobKeyInfo.LengthOfInformation;         for keycount = 1 to LJob200.NumberOfFieldsReturned;           LJobKeyInfo = %subst( LJob200.ReturnedData :                                 KeyStartingPosition :                                 KeyLengthOfData );           KeyLengthOfData = LJobKeyInfo.LengthOfInformation;           LJobKeyInfo = %subst( LJob200.ReturnedData :                                 KeyStartingPosition :                                 KeyLengthOfData );           Endpos = LJobKeyInfo.LengthOfData;           if     LJobKeyInfo.KeyField = 0101;              JobbStatus = %subst( LJobKeyInfo.KeyData : 1 :  Endpos );           elseif LJobKeyInfo.KeyField = 1906;              Subsystem = %subst( LJobKeyInfo.KeyData : 1 : Endpos );           endif;           KeyStartingPosition = KeyStartingPosition + KeyLengthOfData;         endfor;&lt;br /&gt;         // if job in message wait then email message to address in         // variable email address&lt;br /&gt;         if Jobbstatus = 'MSGW';            Subsystem = %trim( %subst( Subsystem : 11 : 10 ) ) + '/' +                        %trim( %subst( Subsystem :  1 : 10 ) );            os400_cmd = 'snddst type(*lmsg) ' +                        'tointnet((' + Q + %trim(EmailAddress) +                        Q + ')) dstd(' + Q    +                        'Job  is in  *MSGW'   +                        Q + ') longmsg(' + Q  +                        'Job (' +                        %trim( LJob200.JobName ) + '/' +                        %trim( LJob200.UserName ) + '/' +                        %trim( LJob200.JobNumber ) +                        ') subsystem ' + %trim( Subsystem ) +                        ' in status *MSGW' +                        Q + ')';             monitor;               qcmdexc ( os400_cmd : %size ( os400_cmd ) );               on-error;                 dump;            endmon;         endif;&lt;br /&gt;         StartingPosition = StartingPosition + LengthOfData;&lt;br /&gt;       endfor;&lt;br /&gt;       endsr;&lt;br /&gt;&lt;br /&gt;The two variables for email are ‘emailaddress’ and ‘emailaddress1'. Simply change the variables to the email addresses you would like the messages sent to and compile.&lt;br /&gt;&lt;br /&gt;The below tool that you can submit to run daily. It searches through the WRKACTJOB and looks for jobs in message wait. It then takes a user ID and use API QUSLJOB to list all jobs, then it finds all interactive device that the user is signed-on and sends him/her a message that there is an error on the system.&lt;br /&gt;&lt;br /&gt;     fTEMP      if   e             disk    usropn rename(TEMP:TEMPR)     f                                     prefix(x)      *      * Program Info      *     d PgmInfo        SDS     d  @PgmName               1     10     d  @Parms                37     39  0     d  @MsgID                40     46     d  @JobName             244    253     d  @UserId              254    263     d  @JobNumber           264    269  0      *      * constants      *     d Q               c                   const('''')      *      *  Field Definitions.      *     d EndLoop         s               n     d CmdLength       s             15  5     d CmdString       s            256     d CurrentTime     s              6  0     d EndTime         s             06  0 inz(180000)     d OutUser         s             10     d InDevice        s             10     d InUser          s             10     d Jtypes          s              1    inz('*')     d KeyI            s             10i 0     d ListFormat      s              8     d NbrKeys         s             10i 0 inz(3)     d ObjType2        s             10     d OutDevice       s             10     d SpacePtr        s               *     d StartTime       s             06  0 inz(070000)     d Status          s             10     d UserSpace       s             20    inz('GETDEVICE QTEMP')     d UseStatus       s             10    inz('*ACTIVE')     d X               s              3  0     d Y               s              3  0     d Z               s              3  0     d Dup             s             16     d Duplicate       s             16     dim(9999)     d lastStamp       s               z    dim(9999)     d TimeStamp       s               z     d Minutes         s             05  0      *     d  CrtUsrSpc      PR              *     d   CrtSpcName                  20    const      *     dKeys             DS     d Key1                          10i 0 inz(1004)     d Key2                          10i 0 inz(1501)     d Key3                          10i 0 inz(1603)&lt;br /&gt;     dQUSLH            DS     d QJobName                1     10             inz('*ALL')     d QUserName              11     20             inz('*ALL')     d QJobNumber             21     26             inz('*ALL')      *     dQUSLKF           DS      *                                             Qus Ljob Key Fields     d LenFldInfo              1      4B 0     d FieldKey                5      8B 0     d DataType                9      9     d Reserved6              10     12     d DataLength             13     16B 0      *     dQUSL020001       DS                           based(ListPoint)      *                                             Qus JOBL0200     d JobName                 1     10     d UserName               11     20     d JobNumber              21     26     d IntJobId               27     42     d JobStatus              43     52     d JobType                53     53     d JobSubType             54     54     d Reserved1              55     56     d JobInfoSts             57     57     d Reserved2              58     60     d NumFldsRet             61     64B 0     d KeyData                65    180&lt;br /&gt;     d QUSKFI          DS            16     d  QUSLFIR01                     9B 0 OVERLAY(QUSKFI  :00001)     d  QUSKF00                       9B 0 OVERLAY(QUSKFI  :00005)     d  QUSTOD01                      1    OVERLAY(QUSKFI  :00009)     d  QUSERVED33                    3    OVERLAY(QUSKFI  :00010)     d  QUSLD01                       9B 0 OVERLAY(QUSKFI  :00013)      *      *                                             Varying length     dQUSH0300         DS                  Based(GenDsPoint)      *                                             Qus Generic Header 0300     d UserArea                1     64     d SizeGenHdr             65     68B 0     d StrRelLvl              69     72     d FormatName             73     80     d ApiUsed                81     90     d TimeStampX             91    103     d InfoStatus            104    104     d SizeSpace             105    108B 0     d OffsetInpP            109    112B 0     d SizeInpPrm            113    116B 0     d OffsetHeadS           117    120B 0     d SizeHeadS             121    124B 0     d OffsetLstD            125    128B 0     d SizeLstD              129    132B 0     d Entries#              133    136B 0     d EntrySize             137    140B 0     d CCSIDEnt              141    144B 0     d CountryId             145    146     d LanguageID            147    149     d SubsetLstI            150    150     d Reserved3             151    192     d EntryPtName           193    448     d Reserved4             449    576&lt;br /&gt;      * Standard Error Code data structure     d ErrorDs         DS                  INZ     d  BytesProvd             1      4B 0     d  BytesAvail             5      8B 0     d  MessageId              9     15     d  ERR###                16     16     d  MessageDta            17    116&lt;br /&gt;&lt;br /&gt;      *==========================================================      * MAIN LINE      *==========================================================     c                   Time                    CurrentTime     c                   dow       CurrentTime &gt;= StartTime  and     c                             CurrentTime &lt;= EndTime      *     c                   exsr      Hskpg      *     c     *Start        setll     TEMP     c                   read      TEMP     c                   dow       not%eof(TEMP)      *     c                   if        %subst(XTEMP:111:04) = 'MSGW'     c                   exsr      $CheckandSend     c                   endif      *     c                   read      TEMP     c                   enddo      *      * delete the spooled file      *     c                   eval      cmdstring = 'DLTSPLF FILE(QPDSPAJB)'  +     c                                         ' SPLNBR(*LAST)'     c                   eval      cmdlength = %len(%trim(cmdstring))     c                   call(e)   'QCMDEXC'     c                   parm                    CmdString     c                   parm                    CmdLength      *      * delay job 20 seconds      *     c                   eval      cmdstring = 'DLYJOB 20'     c                   eval      cmdlength = %len(%trim(cmdstring))     c                   call(e)   'QCMDEXC'     c                   parm                    CmdString     c                   parm                    CmdLength      *     c                   Time                    CurrentTime     c                   enddo      *     c                   eval      *inlr = *on      *      *==============================================================      *    $CheckandSend - Check to see if MSGW is valid      *                    if it is send messages      *==============================================================     c     $checkandSend begsr      *      *  Get the device (*ACTIVE) for the userid and send break message      *     c                   if        %subst(XTEMP:4:10) &lt;&gt; 'MSC18#3' and     c                             %subst(XTEMP:4:10) &lt;&gt; 'MSC18#4'      *     c                   do        2             x      *     c                   select     c                   When      X = 1.     c                   Eval      OutUSer = 'FLANARY'     c                   When      X = 2.     c                   Eval      OutUSer = 'LAMB'     c                   endsl      *     c                   eval      QUserName = OutUser      *  Create user space for file list information     c                   Eval      SpacePtr = CrtUsrSpc(UserSpace)      *      *  List jobs to user space     c                   Call      'QUSLJOB'     c                   Parm                    UserSpace     c                   Parm      'JOBL0200'    ListFormat     c                   Parm                    QusLH     c                   Parm      '*ALL'        Status     c                   Parm                    ErrorDs     c                   Parm                    Jtypes     c                   Parm                    NbrKeys     c                   Parm                    Keys&lt;br /&gt;      *  Load the general data structure     c                   Eval      GenDsPoint = SpacePtr&lt;br /&gt;      *  If the list API was complete or partially complete     c                   if        InfoStatus = 'C' OR     c                             InfoStatus = 'P'      *  Load the list data structure     c                   Eval      ListPoint = GenDsPoint + OffsetLstD&lt;br /&gt;b01  c                   Do        Entries#&lt;br /&gt;     c                   If        UseStatus = *blanks OR     c                             UseStatus = JobStatus&lt;br /&gt;      * Process keys returned     c                   Eval      KeyI = 1     c                   Do        NumFldsRet     c                   Eval      QusKFI   = %subst(KeyData:KeyI:16)&lt;br /&gt;      *      * Call API to see if valid device      *      *      * Jobq info      *     c                   if        QUSKF00  = 1004  and     c                             JobType = 'I'     c                   eval      OutDevice = JobName      *      * only send the same error to user every 5 minutes.      *     c                   eval      TimeStamp = %TimeStamp()     c                   eval      Dup       = %trim(%subst(XTEMP:29:06)) +     c                                        %trim(OutDevice)     c                   eval      Y = 1     c     Dup           lookup    Duplicate(Y)                           99      *     c                   if        Not%Found or     c                             %found    and     c                             %diff(Timestamp:laststamp(Y):*Minutes) &gt; 5      *     c                   If        %diff(TimeStamp:laststamp(Y):*Minutes) &gt; 5     c                   clear                   Duplicate(Y)     c                   clear                   Laststamp(Y)     c                   endif      *     c                   eval      Z = Z + 1     c                   eval      Duplicate(Z) = Dup     c                   eval      laststamp(Z) = TimeStamp      *      * Send the message that there is an error      * SNDBRKMSG MSG('hey big-o-problem') TOMSGQ(QPADEV003M)      *     c                   eval      cmdstring = 'SNDBRKMSG MSG('            +     c                             %trim(Q)                                +     c                             %trim('Job:')                           +     c                             %trim(%subst(XTEMP:4:10)) +     c                             %trim(&lt;a href="mailto:"&gt;'@User:'&lt;/a&gt;) +     c                             %trim(%subst(XTEMP:17:10))  +     c                             %trim(&lt;a href="mailto:"&gt;'@Number:'&lt;/a&gt;)+ %subst(XTEMP:29:06) +     c                             &lt;a href="mailto:"&gt;'@Is&lt;/a&gt; in Message wait.'        +     c                             %trim(Q) + %trim(')  TOMSGQ(')          +     c                             %trim(OutDevice) + %trim(')')      *     c                   eval      CmdString =     c                             %Xlate(&lt;a href="mailto:"&gt;'@':'&lt;/a&gt; ':CmdString)      *     c                   eval      cmdlength = %len(%trim(cmdstring))     c                   call(e)   'QCMDEXC'     c                   parm                    CmdString     c                   parm                    CmdLength      *      *  End Send Message      *     c                   endif     c                   endif      *     c                   eval      KeyI = KeyI + QusLFir01     c                   enddo     c                   endif&lt;br /&gt;     c                   eval      ListPoint = ListPoint + EntrySizee01  c                   enddo     c                   endif      *     c                   enddo      *     c                   endif      *     c                   endsr      *==============================================================      *    Hskpg - One time run House keeping subroutine      *==============================================================     c     Hskpg         begsr      *      *  CLOSE the physical file      *     c                   if        %open(TEMP)     c                   close     TEMP     c                   endif      *      * Hold the wrkactjob spooled file so we can read it.      * OVRPRTF FILE(QPDSPAJB) HOLD(*YES)      *     c                   eval      cmdstring = 'OVRPRTF FILE(QPDSPAJ' +     c                             %trim('B) HOLD(*YES)')     c                   eval      cmdlength = %len(%trim(cmdstring))     c                   call(e)   'QCMDEXC'     c                   parm                    CmdString     c                   parm                    CmdLength      *      * Now print WRKACTJOB      * WRKACTJOB   SBS(QBATCH QPGMR QINTER)   OUTPUT(*PRINT) SEQ(*STS)      *     c                   eval      cmdstring = 'WRKACTJOB SBS(QBATCH QPGMR' +     c                                         ' QINTER) OUTPUT(*PRINT)' +     c                                         '  SEQ(*STS)'     c                   eval      cmdlength = %len(%trim(cmdstring))     c                   call(e)   'QCMDEXC'     c                   parm                    CmdString     c                   parm                    CmdLength      *      *  Create physical file in QTEMP to copy the spooled file to      *  CRTPF FILE(QTEMP/TEMP) RCDLEN(198)      *     c                   eval      cmdstring = 'CRTPF FILE(QTEMP/TEMP' +     c                                         %trim(') RCDLEN(198)')     c                   eval      cmdlength = %len(%trim(cmdstring))     c                   call(e)   'QCMDEXC'     c                   parm                    CmdString     c                   parm                    CmdLength      *      *  Copy the spooled file into out physical so we can read it      *  CPYSPLF FILE(QPDSPAJB) TOFILE(QTEMP/TEMP) SPLNBR(*LAST)      *     c                   eval      cmdstring = 'CPYSPLF FILE(QPDSPAJB' +     c                                         %trim(') TOFILE(QTEMP/') +     c                                         %trim('TEMP) SPLNBR(*LAST)')     c                   eval      cmdlength = %len(%trim(cmdstring))     c                   call(e)   'QCMDEXC'     c                   parm                    CmdString     c                   parm                    CmdLength      *      *  OPEN the physical file      *     c                   if        not%open(TEMP)     c                   open      TEMP     c                   endif      *     c                   endsr      *      *==============================================================      *      *  Procedure to create extendable user space, return pointer to it.      *     P  CrtUsrSpc      B                   export     d  CrtUsrSpc      PI              *     d   CrtSpcName                  20    const&lt;br /&gt;      * Local Variables     d PasSpcName      DS            20     d  SLib                  11     20     d ChgAttrDs       DS            13     d  NumberAttr                    9B 0 inz(1)     d  KeyAttr                       9B 0 inz(3)     d  DataSize                      9B 0 inz(1)     d  AttrData                      1    inz('1')     d ListPtr         S               *     d SpaceAttr       S             10    inz     d SpaceAuth       S             10    INZ('*CHANGE')     d SpaceLen        S              9B 0 INZ(4096)     d SpaceReplc      S             10    INZ('*YES')     d SpaceText       S             50     d SpaceValue      S              1&lt;br /&gt;      * Create the user space     c                   move      CrtSpcName    PasSpcName     c                   CALL      'QUSCRTUS'     c                   PARM                    PasSpcName     c                   PARM                    SpaceAttr     c                   PARM                    SpaceLen     c                   PARM                    SpaceValue     c                   PARM                    SpaceAuth     c                   PARM                    SpaceText     c                   PARM      '*YES'        SpaceReplc     c                   PARM                    ErrorDs      * Get pointer to user space     c                   CALL      'QUSPTRUS'     c                   PARM                    PasSpcName     c                   PARM                    ListPtr      * Change user space to be extendable     c                   CALL      'QUSCUSAT'     c                   PARM                    Slib     c                   PARM                    PasSpcName     c                   PARM                    ChgAttrDs     c                   PARM                    ErrorDs&lt;br /&gt;     c                   return    ListPtr     P  CrtUsrSpc      E&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Enjoy with sending Emails and SMS through AS400&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8909486560224298250-253131046524580376?l=prabhatmohapatra.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://prabhatmohapatra.blogspot.com/feeds/253131046524580376/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://prabhatmohapatra.blogspot.com/2009/10/email-sms-error-notifications-from.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8909486560224298250/posts/default/253131046524580376'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8909486560224298250/posts/default/253131046524580376'/><link rel='alternate' type='text/html' href='http://prabhatmohapatra.blogspot.com/2009/10/email-sms-error-notifications-from.html' title='Email &amp; SMS Error Notifications from an AS/400'/><author><name>Prabhat</name><uri>http://www.blogger.com/profile/14496453689733819797</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8909486560224298250.post-3726387428767701869</id><published>2009-09-21T23:13:00.001-07:00</published><updated>2009-09-21T23:23:58.136-07:00</updated><title type='text'></title><content type='html'>&lt;div align="justify"&gt;1. Use of &lt;strong&gt;SBMJOB&lt;/strong&gt; commandMost people use the OS/400 Submit Job (SBMJOB) command for batch processing.But SBMJOB has other powers that help to increase the capabilities of batch jobs.Command Example:&lt;em&gt;&lt;span style="color:#3366ff;"&gt;SBMJOB CMD(CALL PGM(PROGRAM)) JOB(TESTJOB)&lt;/span&gt;&lt;/em&gt;This way OS/400 submits the job for execution based on the configuration of the userrunning the command. The job runs under the user profile of the submitting user, ituses the job description assigned to the submitting user, it's submitted to the jobqueue associated with the assigned job description, and it uses the scheduling andoutput queue priorities assigned to its job description.There are lots of times when you need to change the defaults and modify theoperating parameters of a submitted job. For instance, you can submit your job to rununder another user profile by modifying the USER parameter of a SMBJOBstatement in the following manner:&lt;em&gt;&lt;span style="color:#3366ff;"&gt;SBMJOB CMD(CALL PGM(PROGRAM)) JOB(TEST) USER(NEWUSER)&lt;/span&gt;&lt;/em&gt;For this command to work, the submitting user must be authorized to the user profileassigned to the batch job. When submitted this way, the submitted job also uses thejob description associated with the new user profile. The job queue, run priority, andoutput priority values then take their values from the new job description.You can also submit the job to a job queue other than that associated with the jobdescription.&lt;em&gt;&lt;span style="color:#3366ff;"&gt;SBMJOB CMD(CALL PGM(PROGRAM)) JOB(TEST) JOBQ(QSYS/QSYSNOMAX)USER(NEWUSER)&lt;/span&gt;&lt;/em&gt;In addition to changing user profiles and job queues, you can set SBMJOBparameters to change the system library list for the job (the SYSLIBL parameter onthe command), the current library for the job (the CURLIB parameter), and the job'sinitial library list (INLLIBL).If you want to log all the CL commands that are executed in your batch job to theTitle of the DocumentInternal Use 3job's job log, set the Log CL program (LOGCLPGM) command parameter to *YES,like this:&lt;em&gt;&lt;span style="color:#3366ff;"&gt;SBMJOB CMD(CALL PGM(PROGRAM)) JOB(TESTJOB) LOGCLPGM(*YES) &lt;/span&gt;&lt;/em&gt;If you want to submit the job so that it is held on the job queue, use the Hold on jobqueue (HOLD) parameter:&lt;em&gt;&lt;span style="color:#3366ff;"&gt;SBMJOB CMD(CALL PGM(PROGRAM)) JOB(TESTJOB) HOLD(*YES) &lt;/span&gt;&lt;/em&gt;If you want to use SBMJOB to schedule a job to start at a certain date and time, usethe Schedule date (SCDDATE) and Schedule time (SCDTIME) parameters.&lt;em&gt;&lt;span style="color:#3366ff;"&gt;SBMJOB CMD(CALL PGM(PROGRAM)) JOB(TESTJOB)SCDDATE('11/01/03') SCDTIME('10:00:00') &lt;/span&gt;&lt;/em&gt;Another neat trick is that you can hide submitted jobs from the Work with SubmittedJobs (WRKSBMJOB) command. To do this, set the Allow Display by WRKSBMJOB(DSPSBMJOB) parameter to *NO, and submit your job in the following manner:&lt;em&gt;&lt;span style="color:#3366ff;"&gt;SBMJOB CMD(CALL PGM(PROGRAM)) JOB(TESTJOB) DSPSBMJOB(*NO) &lt;/span&gt;&lt;/em&gt;If a user tries to view the progress of this job by using the WRKSBMJOB command,he won't be able to see it. Note, however, that users can still see the running job byfinding it on the Work with Active Jobs (WRKACTJOB) command display or on theWork with Subsystem Jobs (WRKSBSJOB) command display.If you don't want operators to answer predefined inquiry messages that appearduring batch processing, you can set SBMJOB's Inquiry Message Reply(INQMSGRPY) parameter to tell the job how to answer messages. If you use thedefault, the job will use the inquiry message control value found in its correspondingjob description. However, if you want your batch job to use default reply values forinquiry messages, you can submit the job with its INQMSGRPY value set to *DFT,like this:&lt;em&gt;&lt;span style="color:#3366ff;"&gt;SBMJOB CMD(CALL PGM(PROGRAM)) JOB(TESTJOB) INQMSGRPY(*DFT) &lt;/span&gt;&lt;/em&gt;And the final SBMJOB trick is to change the message queue to which SBMJOBsends its job completion messages. You have three choices. By default, jobmessages are sent to the message queue that is specified in the user profile that thejob runs under. If you want to do it manually, you change the Message Queue(MSGQ) parameter of the SBMJOB statement, as follows:&lt;em&gt;&lt;span style="color:#3366ff;"&gt;SBMJOB CMD(CALL PGM(PROGRAM)) JOB(TESTJOB) MSGQ(*USRPRF) &lt;/span&gt;&lt;/em&gt;But if you want to change that message queue so that your messages go to themessage queue of the workstation the job was submitted from, you set MSGQ to*WRKSTN and your SBMJOB statement would look like this:&lt;em&gt;&lt;span style="color:#3366ff;"&gt;SBMJOB CMD(CALL PGM(PROGRAM)) JOB(TESTJOB) MSGQ(*WRKSTN) &lt;/span&gt;&lt;/em&gt;Title of the DocumentInternal Use And if you want to suppress the completion message altogether, change MSGQ to*NONE and the job won't send out completion messages at all:&lt;em&gt;&lt;span style="color:#3366ff;"&gt;SBMJOB CMD(CALL PGM(PROGRAM)) JOB(TESTJOB) MSGQ(*NONE) &lt;/span&gt;&lt;/em&gt;2. Job Logs and their UsefulnessA job log is invaluable in determining the cause of a problem when a job endsabnormally. If not properly managed, though, job logs can eat up huge amounts ofsystem storage. Understanding how job logs get generated is the first step tounderstanding how to managing them.The system program maintains the job log. Every job that runs on your server has anassociated job log that records its activities. A job log can contain the following:• The commands in the job• The commands in a control language (CL) program• All messages associated with that jobWhat determines when a job log will be created?There are several ways within OS/400 to specify the creation of or restrict thecreation of a job log.Job log for a Batch JobThe message logging parameters on the job description and for an active jobdetermine what kind of information will be collected:&lt;/div&gt;&lt;div align="justify"&gt;Message logging: LOGLevel . . . . . . . . . . . . 4&lt;/div&gt;&lt;div align="justify"&gt;Severity . . . . . . . . . . . 00&lt;/div&gt;&lt;div align="justify"&gt;Text . . . . . . . . . . . . . *NOLIST&lt;/div&gt;&lt;div align="justify"&gt;Log CL program commands . . . . LOGCLPGM *NO&lt;/div&gt;&lt;div align="justify"&gt;I won't go into all the specifics related to those values at this time, but if the message logging 'TEXT' parameter is set to *NOLIST, a job log will be created only if the jobends abnormally. If the job completes normally, no job log will be created. This is thesame whether the job is an interactive or batch job.If any value other than *NOLIST is specified for the message logging 'TEXT'parameter in a batch job, a job log will always be produced -- whether the job endsnormally or abnormally.Job log for a Interactive JobThis works differently for interactive jobs, though. To conserve disk space consumedby job logs, the SIGNOFF command may be defined asSign Off (SIGNOFF)Type choices, press Enter.Title of the DocumentInternal Use 5&lt;/div&gt;&lt;div align="justify"&gt;Job log . . . . . . . . . . . . LOG *NOLIST&lt;/div&gt;&lt;div align="justify"&gt;Drop line . . . . . . . . . . . DROP *DEVD&lt;/div&gt;&lt;div align="justify"&gt;End connection . . . . . . . . . ENDCNN *NO&lt;/div&gt;&lt;div align="justify"&gt;So, by default, when an interactive job is ended normally, no job log will be producedas specified by the LOG(*NOLIST) parameter. However, if an interactive job endsabnormally, a job log will be produced.This job log is usually stored in the QEZJOBLOG output queue in library QUSRSYS.You can determine where your job log output goes with this command:DSPFD FILE(QPJOBLOG)Scroll down to the Spooling Description section of the Display File Description listingto see which output queue job log output will be directed to:Spooling Description&lt;/div&gt;&lt;div align="justify"&gt;Spooled output queue . . . . . . . . . . . : OUTQ QEZJOBLOG&lt;/div&gt;&lt;div align="justify"&gt;Library . . . . . . . . . . . . . . . . . : QUSRSYS&lt;/div&gt;&lt;div align="justify"&gt;If you want to always force the creation of a job log from an interactive job, you cando it in one of two ways:1. When you sign off enter SIGNOFF LOG(*LIST) instead of using the default.2. Prior to signing off enter &lt;em&gt;&lt;span style="color:#3366ff;"&gt;DSPJOBLOG OUTPUT(*PRINT). &lt;/span&gt;&lt;/em&gt;When one of those options is used, a job log will always be created from aninteractive job.View the JoblogNow that you understand how job logs are created on the iSeries, let's look at how toview one?To view a job log that has already been created, use one of the following commands:&lt;/div&gt;&lt;div align="justify"&gt;&lt;em&gt;&lt;span style="color:#3366ff;"&gt;DSPSPLF FILE(QPJOBLOG) JOB(job_number/Usrid/Job_name)DSPJOB JOB(job_number/Usrid/Job_name) OPTION(*SPLF)&lt;/span&gt;&lt;/em&gt;&lt;/div&gt;&lt;div align="justify"&gt;To see ALL job log output on the system, use this command:WRKOUTQ OUTQ(QUSRSYS/QEZJOBLOG)For further information on how to create/display or modify job descriptions, review theHELP text associated with the following OS/400 commands:&lt;/div&gt;&lt;div align="justify"&gt;&lt;em&gt;&lt;span style="color:#3366ff;"&gt;CHGJOBD CRTJOBD DSPJOBD WRKJOBD&lt;/span&gt;&lt;/em&gt;&lt;/div&gt;&lt;div align="justify"&gt;For further information on how to view/change a jobs message logging attributes andto display a job log, review the HELP text associated with these OS/400 commands:DSPJOB&lt;/div&gt;&lt;div align="justify"&gt;CHGJOB DSPJOBLOG&lt;/div&gt;&lt;div align="justify"&gt;SQL WorkingWhen you execute an SQL command, the system determines the best way to carryout your request. That is, you concentrate on the task that needs to be done, and thesystem figures out how to do your task.Various software components are involved in this process, and for this discussion,you need to know about three of them. First is the Query Dispatcher, whose job it isto decide which of the two query optimization engines it will call on to optimize andprocess a query. The second and third software components are the two queryengines--the Classic Query Engine (CQE) and the SQL Query Engine (SQE). SQE is newer and better than CQE, but there are certain tasks that it can't carry out.You can reference four types of files in SQL statements: DDS-defined physical files,DDS-defined logical files, SQL tables, and SQL views. SQE can't handle DDSdefinedlogical files. SQL views and indexes are also implemented as logical files, butthey are not applicable to this discussion.CQE handles all non-SQL queries, such as the Open Query File (OPNQRYF) command and Query/400. CQE also handles distributed queries via DB2multisystem.If you wish to query a logical file from an SQL statement, consider querying theunderlying physical file(s) instead. If the logical file has select/omit criteria, put thecriteria in the WHERE clause. Another approach would be to create a view over thephysical file and reference that view in your SQL query&lt;/div&gt;&lt;div align="justify"&gt;AS400 ConstraintsConstraints are a function of Referential Integrity, where the database managerensures the logical consistency of data values between files and the validity of datarelationships, based on rules set by you.Impressive as that sounds, it is something you are already doing; except that you aredoing it in your application programs. For example you cannot delete the customer ifthere are dependant invoices on the invoice file, and you do not employ people underthe age of sixteen. Those constraints are implemented through logic in your RPG orCOBOL programs. As your applications expand and data becomes accessibleoutside of the traditional green screen, it becomes imperative that these rules areconsistent across all interfaces. What better way to implement them then through thedatabase manager?&lt;/div&gt;&lt;div align="justify"&gt;are defined for physical files or tables. You can define three types ofConstraint: Key, Referential and Check. How do you define constraints?You can define constraints using the Add Physical File Constraint (ADDPFCST)command. You can also use the CHGPFCST, RMVPFCST, WRKPFCST,EDTCPCST and DSPCPCST commands.You can define them in SQL using the CREATE TABLE or ALTER TABLEcommands.Key constraintsKey constraints define unique keys for a table. The end result is an access path, butthere is no corresponding logical file. Since DB2 automatically shares access paths,there is no extra overhead if there is already a logical file that defines the accesspath.There are two types of Key constraints: unique and primary. A table may have onlyone primary Key constraint but may have many unique Key constraints.The same constraint could be defined on green screen using the following command:&lt;/div&gt;&lt;div align="justify"&gt;&lt;em&gt;&lt;span style="color:#3366ff;"&gt;ADDPFCST FILE(ALLTHAT1FL/CATEGOR) TYPE(*PRIKEY)KEY(CATCOD) CST(CategoryPrimaryKey)&lt;/span&gt;&lt;/em&gt;&lt;/div&gt;&lt;div align="justify"&gt;Referential constraints : Referential constraints are where you define a constraint between two tables: aparent and a dependant. The parent file must have a primary constraint defined for it.In this example there is a dependency between the Category file and the Product file.Every product "belongs" to a category. Therefore, you should not be able to delete acategory if any products refer to it, and you should not be able to assign a nonexistentcategory to a product. Think how you would manage this in an application --a logical over the product file that you use to check for existing records in the Category maintenance program and the Product maintenance program checks the Category file to make sure the category code is valid. (But you can bypass all of thatwith DFU.)Referential Integrity is a powerful tool for us to use in our applications and provide ameans of ensuring data integrity outside of our application.Title of the DocumentInternal Use 85. Access path and Open data path for Data Access Open Data PathOpen Data Path provides a way for more than one program in the same job to share the same file status information (I/O feedback areas), file pointer positions, andstorage area. ODP's are quite useful as they can improve performance, reduce theamount of main storage needed by the job, and reduces file opens/closes.For native I/O access you can set up ODP's by specifying SHARE(*YES) on theCRTPF, CHGPF, or OVRDBF commands. However, SQL based I/O access is notinfluenced by the SHARE (*YES) setting. The DB2 SQL engine is solely responsiblefor creating and reusing ODP's for I/O performed from SQL-based interfaces (anddoes so automatically).Access PathAn access path (also known as a keyed logical file or an index in SQL terms) is datastructure that represents the order in which data will be retrieved from a file. Itprovides a quick way of locating data. Without an access path, a program would beforced to read every row in the table to find the particular rows of interest. Thistechnique (known as a full table scan), can be a lengthy process, depending on thesize of the table and how many rows are being retrieved. A scan using an accesspath tends to be more efficient than a full table scan when a small percentage ofrows are selected since the length of the access path key value is usually shorterthan the length of the table row6. Faster Query Access:Faster is better when accessing large volumes of data. There are many ways toimprove SQL performance, but here are four tips that are especially useful for highvolume, read-only database access.• Code a Set Option &lt;em&gt;&lt;span style="color:#3366ff;"&gt;AlwCpyDta = *Optimize&lt;/span&gt;&lt;/em&gt; SQL statement (or theAlwCpyDta(*Optimize) parameter on the appropriate CL command). This lets theoptimizer choose whether to create a new index or use a sort for a temporary copy ofthe data.• Note that AlwCpyDta=*Yes actually means "use a copy only when it's required toperform the query." This allows the optimizer less latitude than the *Optimize optionprovides.• Code a Set Option AlwBlk = *AllRead SQL statement (or the AlwBlk(*AllRead)parameter on the appropriate CL command). This maximizes system blocking whenpossible.• Use a CL OvrDbF (Override with Database File) command with the SeqOnly (*Yes,Title of the DocumentInternal Use 9mm) and/or the NbrRcds (nn) parameter(s) to specify system blocking for batchsequential Fetch's.Use multi-row fetches to read a set of records with each Fetch statement.7. Prototype Calls in RPGLE:A lot of RPG programmers are under the misconception that the CALLP operationmeans Call Procedure. That is because most of them come across it when they startusing sub procedures. But CALLP means Call a Prototyped Procedure or Program,and it can be used in place of the CALL operation, as well as CALLB.What's wrong with CALL and PARM?In RPG all parameters are passed by reference. That means a pointer to theparameter is passed, not the actual value of the parameter. That, in turn, means boththe passed and receiving parameter fields share the same memory location, and thatis where the potential problem lies.Prototypes are defined on the D specifications, as shown in Figure 1. The format of aprototype is very similar to a data structure, except that the type is PR as opposed toDS. You can provide your own name for the CALLP (PromptProduct). The EXTPGMkeyword indicates that this is the equivalent of a CALL operation, and it identifies thename of the called program (PRP01R). The names of the subfields in the prototypeare irrelevant, what are important are the number of subfields (i.e. parameters) andthe definition of each. In the example in Figure 1 the compiler will ensure that twoparameters are passed, that Parm1 is a 30 character field and that Parm2 is a 1character field.D PromptProduct PR ExtPgm('PRP001R')D FirstParm 30D SecondParm 1C CallP PromptProduct(Parm1:Parm2)Other features of prototype like ‘CONST’, ‘*OMIT’, ‘*NOPASS’ easy the codingprocess.8. Recursive Call in RPGLE:RPG does not allow recursive calls. Actually ILE RPG does allow recursion. Aprogram cannot call itself, but it can call a sub procedure that calls itself.The procedure call should not use the CALLP opcode; rather it should use the EVALopcode and treat the procedure as a function. For example, a procedure nameTitle of the DocumentInternal Use 10CALCS would use the following code:RETURN CALCS (value02)The sample code calculates the nth number in a Fibonacci sequence. A Fibonaccisequence is a sequence whereby any number is equal to the previous two numbersin the sequence:Nbr(n) = Nbr(n-1) + Nbr(n-2).In the sequence, the first number is 1, preceded by an implied zero so that thesecond number has an "n-2" to use.The first few elements then calculate to:1 1 2 3 5 8 13 21 34It is an interesting exercise to run this procedure in DEBUG and observe its action.The sub procedure CALCS would be called from an ILE RPG program using astatement such as:EVAL RESULT = CALCS(Nbr)Note that if the recursion proceeds through too many recursive calls, thatperformance drastically slows down. In this example, anything over 30 calls really ranslowly. If the job ends abnormally while into a deep call stack, the end job processtakes a very long time.Code* Procedure PrototypeDCALCS PR 9P 0D 9P 0* * * * * * * * * * * * * * * * * * * Procedure DefinitionP CALCS B*D CALCS PI 9P 0D NBR 9P 0** Procedure variablesD NM1 S 9P 0D NM2 S 9P 0*C SELECT* Endpoint if inbound parm = 0C WHEN NBR = 0C RETURN 1* Endpoint if inbound parm = 1C WHEN NBR = 1C RETURN 1* Endpoint if inbound parm = 2C WHEN NBR = 2C RETURN 1* Recursive callTitle of the DocumentInternal Use 11C OTHERC EVAL NM1 = NBR - 1C EVAL NM2 = NBR - 2C RETURN CALCS(NM1)+ CALCS(NM2)C ENDSL9. Handle errors in RPG like CL:Any type of exception can be captured in the RPG program by using MONITORopcode, it is like the MONMSG of CLP. You can put any code between MONITORand ENDMON opcodes, so that whatever error occurred in this range will bemonitored.See the example below:Example:Declare an array like Arr with DIM(2) Declare 3 variables A, B and C with length 2,0.The below code shows how to monitor the runtime errors.The initial value of A and C is 0, initiate value of B is 11.MONITORB DIV AArr(B) DsplyON-ERROR 0102'Div by 0' DsplyON-ERROR 0121'Index Err' DsplyON-ERROR'Error' DsplyENDMONSimilar way specific errors can be captured and handled accordingly in RPG.10. Active User Description in AS400:Have you ever wanted to see the description of an active user on the system insteadof just seeing his or her user profile?Try this:Go ManagesysOption 12F113 User descriptionsThis will show you all active users, in username order, with their names shownbeside them. If you want to send a break message to them, press F10 and this willsend a message to all active users.Title of the DocumentInternal Use 1211. Find Data in a Multi-Member file:Ever have to look through a large multimember file for a particular record?It can be a time consuming task.Key in FNDSTRPDM + F4. Options are self-explanatory.Option member allow user to key in "*ALL" and will search through all members forthe strings keyed. Allows user to display, print, and edit records when string is found.12. Date Manipulation in CLUsing the code below you'll be able to do date manipulation in a CL program, andretrieving the system date.&lt;/div&gt;&lt;div align="justify"&gt;DCL VAR(&amp;amp;SYSDATE) TYPE(*CHAR) LEN(6)&lt;/div&gt;&lt;div align="justify"&gt;DCL VAR(&amp;amp;YESTERDAY) TYPE(*DEC) LEN(8 0)&lt;/div&gt;&lt;div align="justify"&gt;DCL VAR(&amp;amp;LILIAN) TYPE(*CHAR) LEN(4)&lt;/div&gt;&lt;div align="justify"&gt;DCL VAR(&amp;amp;JUNK1) TYPE(*CHAR) LEN(8)&lt;/div&gt;&lt;div align="justify"&gt;DCL VAR(&amp;amp;JUNK2) TYPE(*CHAR) LEN(23)&lt;/div&gt;&lt;div align="justify"&gt;DCL VAR(&amp;amp;WDATE) TYPE(*CHAR) LEN(8)&lt;/div&gt;&lt;div align="justify"&gt;RTVSYSVAL SYSVAL(QDATE) RTNVAL(&amp;amp;SYSDATE)/* Get local time from system: When this call is complete, &amp;amp;LILIAN will contain thenumber of days between today and Oct 14, 1582. */&lt;/div&gt;&lt;div align="justify"&gt;CALLPRC PRC(CEELOCT) PARM(&amp;amp;LILIAN &amp;amp;JUNK1 &amp;amp;JUNK2 *OMIT)/* Subtracting 1 from &amp;amp;LILIAN will produce yesterday's date */&lt;/div&gt;&lt;div align="justify"&gt;CHGVAR VAR(%BIN(&amp;amp;LILIAN)) VALUE(%BIN(&amp;amp;LILIAN) - 1)/* Convert lillian to yyymmdd date */&lt;/div&gt;&lt;div align="justify"&gt;CALLPRC PRC(CEEDATE) PARM(&amp;amp;LILIAN 'YYYYMMDD' &amp;amp;WDATE *OMIT)&lt;/div&gt;&lt;div align="justify"&gt;CHGVAR VAR(&amp;amp;YESTERDAY) VALUE(&amp;amp;WDATE)&lt;/div&gt;&lt;div align="justify"&gt; &lt;/div&gt;&lt;div align="justify"&gt;Note: CEELOCT and CEEDATE are APIs that exist on the system; you do not needto create them. In essence, what the CL that is supplied does is:1) Use the CEELOCT API to convert the current date to lillian.2) Then you add or subtract the number of days you need from the lillian date.3) Then you use CEEDATE to convert the new lillian date back to the date formatthat you wish, in this case, we have used YYYYMMDD.Title of the DocumentInternal Use 1313. Subfile Data SortingSorting data is something RPG programs often need to do. If it's just a simple singlefield array you're sorting in order to use the much faster binary search possible with%Lookup, for example, then SORTA works well and is simple. But what if it is a morecomplex task like sorting the data in a subfile on a user-selected column? Surely youneed some more involved techniques, such as retrieving the data from the databaseagain using a different ORDER BY on an SQL SELECT statement or using adifferent logical file or you could use the qsort C function for sorting the arrayelements in the program. Something as simple as SORTA can't be used for that,right? Maybe so. The circumstances where this is effective are limited, for sure, but if yourrequirements fit, then using SORTA with a group field can be the simplest way andoften a faster alternative than other methods you may have tried.First of all, what's a group field? It's a field in a data structure that is broken down intosmaller subfields. For example, group field SflData might be made up of informationabout products (name, price, quantity) by using the Overlay keyword, such as:&lt;/div&gt;&lt;div align="justify"&gt;D SflDS Ds Inz&lt;/div&gt;&lt;div align="justify"&gt;D SflData Like(SflRecData) Dim(999)&lt;/div&gt;&lt;div align="justify"&gt;D Name Like(ProdDS)D Overlay(SflData)D Price Like(SellPr)&lt;/div&gt;&lt;div align="justify"&gt;D Overlay(SflData:*Next)D Qty Like(STOH)D Overlay(SflData:*Next)&lt;/div&gt;&lt;div align="justify"&gt;The effect is similar to nested data structures, except without the requirement to usequalified names. (Likewise, there are many limitations on group fields because of thelack of name qualification.) One additional thing that's nice about group fieldscompared to nested DSs is that we can use SORTA against any of the subfields in agroup field array.So this means if I wanted to sort the data in the SflData array by product name, Icould do that with the following statement: SortA Name;. Much simpler than any ofthose other options I mentioned above! Of course, in nearly all cases, it would requirethe use of the built-in function %SubArr (substring array) because I'm not likely tohave filled up all 999 elements of SflData. Even so, the entire bit of logic toaccomplish sorting this subfile data in the sequence of any of the three fields couldbe as simple as:If SortByName;S&lt;/div&gt;&lt;div align="justify"&gt;ortA %SubArr(Name:1:Count);ElseIf SortByQty;Title of the DocumentInternal Use 14SortA %SubArr(Qty:1:Count);ElseIf SortByPrice;SortA %SubArr(Price:1:Count);EndIf;This technique is very simple and in most cases quite a fast way to sort subfile data(or any other kind of repeating data). It does have significant limitations. For example,you can only sort on one subfield at a time. (Of course, you could group two subfieldstogether if they happen to be adjacent in the subfile record.) Also, you must be ableto retrieve and store all the data destined for the subfile into an array so that you cansort it all together. For some very large subfiles, that won't be practical. But for thoseoccasions where it works, it couldn't get much simpler.14. User Spaces:Because quite a few of IBM's system-supplied APIs use a user space to storeinformation, it is important to understand what they are and how they work.Information is stored in a user space as a "stream," similar to a stream file in the IFS.This is different than the physical files we are used to dealing with in our everydayapplications. Instead of each set of data being stored in a physical record, eachrecord is a subsection of a stream of data.When using a user space with an IBM-supplied API, data is normally sectioned byusing a data structure. This data structure defines a record of data in the stream inthe user space. For example, let's assume that our user space contains informationabout a customer. The first nine characters contain the customer number, the next 10contain the last name, and the last 10 contain the customer's first name. The datamay appear in a user space as such:000012457Stone Brad001248945Johnson Jerry045542144Anderson LouisIn order to separate out each record from this stream of data, we will use a datastructure. The data structure would appear as shown in the following RPG snippet:D CustomerInfo DSD CstNumber 9D CstLName 10D CstFName 10In order to parse the data from the user space, we need to move the data structure tothe beginning of each record. The data structure then "overlays" the data so we areable to easily access the information. In RPG, this is done with a pointer. TheCustomerInfo data structure as shown above would be defined based on a pointer.Title of the DocumentInternal Use 15We then move the position of that pointer to the beginning of each set of data inorder to populate the subfields of the data structure with each customer's information.When doing this, we will also have to know the size of each structure of data. Weknow that IBM APIs return a "header" that defines, among other things, the start ofthe data and the length of each entry in the set of data contained within the userspace.The following piece of RPG code defines a standard header that deal with IBM APIsthat store information in a user space:D GenHeader DS BASED (HeaderPtr)D OffsetHdr 117 120B 0D OffsetLst 125 128B 0D NumLstEnt 133 136B 0D EntrySize 137 140B 0As we can see, there are four subfields defined in this data structure. The first,OffsetHdr, is used to define the offset to the header information. Next is the fieldOffsetLst. This defines the offset to the start of the list information. The listinformation is the data that we are interested in parsing from the user space.Next, the NumLstEnt field is used to define the number of entries in the list. This is animportant number to know so that as we parse through the list we know when to stop.Finally, the EntrySize field is used to define the size of each entry. This is used sothat we know where to reposition our pointer on the next "record" of data in the userspace.We start reading by setting our basing pointer to the OffsetLst value, entering a loopthat executes NumLstEnt times, and, for each subsequent iteration of the loop,repositioning our pointer by adding the value stored in EntrySize to our currentpointer position.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8909486560224298250-3726387428767701869?l=prabhatmohapatra.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://prabhatmohapatra.blogspot.com/feeds/3726387428767701869/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://prabhatmohapatra.blogspot.com/2009/09/1.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8909486560224298250/posts/default/3726387428767701869'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8909486560224298250/posts/default/3726387428767701869'/><link rel='alternate' type='text/html' href='http://prabhatmohapatra.blogspot.com/2009/09/1.html' title=''/><author><name>Prabhat</name><uri>http://www.blogger.com/profile/14496453689733819797</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8909486560224298250.post-7542097489653236844</id><published>2009-09-21T22:53:00.000-07:00</published><updated>2009-09-21T22:57:16.716-07:00</updated><title type='text'>Application performance in AS400 Programming</title><content type='html'>Reduce Disk I/O: Disk I/O operations consume some CPU processing time and can cause waits on the disk while disk I/O for other jobs completes. So it is recommended to minimize unnecessary database operations within the program. For interactive transactions, consider 20 database operations as an excessive number.&lt;br /&gt; Use Odd Length Packed Fields For Numeric Data: The AS/400 system does packed decimal arithmetic. Extra SLIC instructions and extra CPU time is required to handle the extra half-byte for even-length fields. Defining numeric fields as packed decimal or moving numeric fields into a packed field within the program before calculations improves CPU utilization for frequently used fields.&lt;br /&gt; Decimal Data Performance: For ILE RPG/400 and ILE COBOL/400, use packed decimal data for best performance.Move Passed Parameters To Local Work Fields Before Use:&lt;br /&gt;This reduces compiler-generated code that must validate the parameter at each use.&lt;br /&gt;Also, if a zoned decimal value has been passed, a local packed, odd length work field is more efficient. If you must return the value of the parameter, copy the local work field into the external parameter before returning control.&lt;br /&gt; Minimize The Number Of Different Parameters Passed: If possible, place all of the data to be passed between programs into a single parameter and use only this single parameter area between programs. This becomes more important as the frequency of calls and returns between programs increases during job run time.&lt;br /&gt; Call Program Name Considerations (Non-ILE Support): For non-ILE program calls, use a constant or literal to name the program being called. This ensures the overhead for security and resolution of the system pointer to the called program incurred on the first call to that program is minimized on all subsequent calls within a run unit. This saving of an already resolved pointer to a previously called program support also applies to variables containing program names when either RPG or COBOL performs the dynamic call. When a program reference is made with a variable, the current value of a variable is compared to the value used on the previous program reference. If the value did not change, no resolve is done to the target program. If a variable name is used in languages other than RPG and COBOL even if the same program is called again and again, the overhead to establish the pointer is incurred for each call.&lt;br /&gt; Use Large Multifunction Programs (Non-ILE Support): For non-ILE applications, a larger program doing several functions uses less resource than calls to several programs. Good structured programming techniques are vital to the integrity and maintainability of large programs.&lt;br /&gt; Reduce The Number Of File Opens And Closes: Full Opens and Closes are expensive activities, not just in terms of CPU but disk activity as well. As much as possible, open the most frequently used files in a higher program invocation and use shared files (file SHARE(*YES) parameter) within the job. The possibility of using SHARE(*YES) occurs when the application uses small modular programs where the most frequently called programs perform specific functions, and returns to a primary or driver program. In many cases, the called programs repetitively use the same database files and display record formats.&lt;br /&gt;In this scenario, the primary program should open the most frequently used database files with the maximum processing possibilities (read, write, and update) with SHARE(*YES) on the files. The secondary program open file operations connect with the existing Open Data Path (ODP) those results in significant CPU savings and response time improvement.&lt;br /&gt;All of the display formats used by the primary and secondary programs can be placed into a single display file that can be opened by the primary program with SHARE(*YES). This speed up the file open by the secondary programs and can be used to permit display data to be retained across calls to several programs.&lt;br /&gt;There are some things to be aware of when using shared database and display files. The secondary programs must be written with the understanding that database file record (cursor) positioning and workstation display formatting are treated by the system as if one program were using the file. For example, program PGM1 may have positioned the file SHARE to record 107 and call program PGM2. PGM2 uses shared file SHARE and causes the file to be positioned to record 23 and returns to program PGM1. PGM1 must not assume the file SHARE is still positioned at record 107. Note that if a shared file is processed sequentially for output and the file parameter specified SEQONLY(*YES), the file must be closed or the Force End of Data (FEOD) operation used for the last buffer of added records to be written to the disk.&lt;br /&gt;Similarly, assume programs PGM1 and PGM2 both use record formats in file SHARED. Programs PGM1 and PGM2 must be written with the understanding of which formats may have been written to the display by the other program.&lt;br /&gt;In the case of shared display files, placing more than 50 record formats in a single file can result in large Process Access Group (PAG) sizes that, in turn, result in degraded performance on storage constrained systems where many jobs are using the same display file.&lt;br /&gt;If you are using the same ODP for read and update, consider using two ODPs, one for input and one for output, if you are reading the file sequentially. One ODP for input loses blocking, two allows input blocking.&lt;br /&gt;&lt;br /&gt;Increase Code Sharing: Sharing a single copy of a program by all active users is built into the AS/400 system. (All AS/400 programs are re-entrant.) Code sharing can be increased by working to ensure that as few different programs as possible are used in the system. An example of this is varying the output display or report titles for different locations within the same organization. This can be done as opposed to creating separate copies of the same program, one for each location.&lt;br /&gt;&lt;br /&gt;Group Routines By Frequency Of Use: In general, most programs are paged into main storage in 4KB blocks. Keeping active code segments together can sharply reduce paging requirements.&lt;br /&gt;&lt;br /&gt;Make Infrequently Called Routines Subroutines: Dead code can increase program paging requirements. Moving such code into subroutines can help to keep active code together in a minimum of 4KB blocks.&lt;br /&gt;&lt;br /&gt;Consider Program Observability:Using RMVOBS(*ALL) on the CHGPGM command, CHGSRVPGM command, and CHGMOD command can release a significant amount of disk space that indirectly affects performance. For ILE programs, you have additional RMVOBS options for reducing storage (*DBGDTA (remove debug data) and *CRTDTA (remove re-create data)).&lt;br /&gt;You may also use the Compress Object (CPROBJ) command to compress observability through the PGMOPT parameter (CPROBJ(*OBS)).&lt;br /&gt;&lt;br /&gt;Communicate Between Jobs With Data Areas And Data Queues: When there is a need to communicate between jobs, the application design must make a choice between using a database file, a message queue, a data area, or a data queue. Much less disk resource is required to update a data area or add an entry to a data queue than is needed to update a database record. The same type of savings is also realized when the receiving job reads the data.&lt;br /&gt;Data queues are also more efficient than message queues, but message queues provide a wider range of function.&lt;br /&gt;&lt;br /&gt;Consider The Size Of A Data Area: When defining an external data area, define it as large as needed but do not make it overly large for future use.&lt;br /&gt;&lt;br /&gt;Consider Use Of Query And Data File Utility Facilities: Understand what the various AS/400 query functions and Data File Utility can produce. Consider using them instead of writing a new program when the application is to select a subset of records from one or more files and complex logic is required. Some functions are part of OS/400 such as Open Query File (OPNQRYF).&lt;br /&gt;Look out for any generic searches and multiple format logical files because these types of queries can adversely affect performance. In general, writing a program that must individually process a small set of records is more efficient than using one of the query capabilities. Sorting to select the subset may be better yet. However, when there is a large number of records to process and selection logic is quite complex, using the query interfaces should be considered.&lt;br /&gt;Comparison of user programming versus the various query facilities is beyond the scope of this publication.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8909486560224298250-7542097489653236844?l=prabhatmohapatra.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://prabhatmohapatra.blogspot.com/feeds/7542097489653236844/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://prabhatmohapatra.blogspot.com/2009/09/application-performance-in-as400.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8909486560224298250/posts/default/7542097489653236844'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8909486560224298250/posts/default/7542097489653236844'/><link rel='alternate' type='text/html' href='http://prabhatmohapatra.blogspot.com/2009/09/application-performance-in-as400.html' title='Application performance in AS400 Programming'/><author><name>Prabhat</name><uri>http://www.blogger.com/profile/14496453689733819797</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8909486560224298250.post-3502052275262939909</id><published>2009-04-20T01:43:00.000-07:00</published><updated>2009-04-20T02:15:35.346-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Image Handling'/><title type='text'>Handling images on AS400</title><content type='html'>Being asked if it is possible to handle images on the as400. Because the guy, who asked me was in insurance company and want to store the pictures of the vehicles that his clients bring to get insurance. It is possible to do it in a green-screen environment, for example in a subfile? Or must he use websphere/hats/webfacing at all cost?&lt;br /&gt;For example he wants to search a vehicle by its id and show its picture on the as400 to avoid the personnel looking for the physical file in a big cabinet. His company has grown too big and are having problems organizing the data.&lt;br /&gt;His take is that a 5250 terminal cannot handle graphics, but he has seen some solutions that let you click on a "link" in the green screen program and it loads internet explorer.&lt;br /&gt;&lt;br /&gt;Storing them on the IFS and/or a network server will certainly work. If you are using iSeries Access for your 5250 emulation, you can choose to have the emulator recognize URL's and link directly to them.&lt;br /&gt;&lt;br /&gt;Another option is iSeries Access for Web, which runs the 5250 in a browser window, and you can do all sort of html stuff. However, I tried this and wasn't happy with the performance of the 5250 screens.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;5250 can not handle graphics but the As/400 can send a PC command down so to open a graphics file stored on the IFS or PC server. The location/file name can be stored within a field in the green screen record, then when the user requests to "view" the PC type graphics image the green screen app sends the PC a command using strpccmd to open the file from the specified location.&lt;br /&gt;&lt;br /&gt;I do just that within a document management system tying vendor/customer/item docs (pdf,word, or any other type of PC doc) to the record. Then when the greeen screen requests to view it we send a PC command down to open it using the PC default viewer (adobe reader, word, image viewer, etc)&lt;br /&gt; &lt;br /&gt;&lt;strong&gt;&lt;span style="color:#6666cc;"&gt;STRPCO PCTA(*NO)&lt;br /&gt;STRPCCMD PCCMD(NOTEPAD.EXE)&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/strong&gt;and it runs.&lt;br /&gt;&lt;br /&gt;When displaying the screen and user presses a function to display image or using a subfile selection value, then send the pc command down.&lt;br /&gt;&lt;br /&gt;The PC has default application hanlders, IE: If the user double clicks on a file with a PDF extension then the pc opens it with adobe.&lt;br /&gt;&lt;br /&gt;If I issue the following:&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3366ff;"&gt;Strpco&lt;br /&gt;strpccmd pccmd("c:\SomeDirectory\MyResume.doc")&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;The pc will use the default applications to open MyResume.doc, if it exists in the given directory.&lt;br /&gt;&lt;br /&gt;Now assuming your are on a network what would happen if I issued:&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3366ff;"&gt;strpccmd pccmd("\\Yourserver\YourShare\MyResume.doc").&lt;/span&gt; assumptions are that the windows user has the rights.&lt;br /&gt;&lt;br /&gt;Guess what it would open MyResume.doc from the given location.&lt;br /&gt;&lt;br /&gt;Try this one:&lt;br /&gt;strpccmd pccmd("\\YourAs400NetworknameorIP\AShare\Yourexpenses.xls")&lt;br /&gt;&lt;br /&gt;The PC would use the default application to open xls file.&lt;br /&gt;&lt;br /&gt;Code snippet:&lt;br /&gt;&lt;br /&gt;PHP Code:&lt;br /&gt;&lt;br /&gt; &lt;span style="color:#6600cc;"&gt;* Strpccmd pccmd("\\ToDirectory\CurrentPicName") &lt;br /&gt;c                   Eval      File = %Trim(ToDirectory) + %Trim(CurPicNam)               &lt;br /&gt;c                   Eval      Comm = StrPcCmd + %Trim(ToDirectory) +                     &lt;br /&gt;c                             %Trim(CurPicNam) + Txt6                                    &lt;br /&gt;c                   Eval      ComLgt = %Len(Comm)                                        &lt;br /&gt; *                                                                                       &lt;br /&gt;C                   CALL      'QCMDEXC'                                                  &lt;br /&gt;C                   PARM                    COMM                                         &lt;br /&gt;C                   PARM                    ComLgt &lt;br /&gt;&lt;br /&gt;&lt;/span&gt;I have even added rundll parameters to as to not show the dos box.&lt;br /&gt;__________________&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;"File" is a field name and so is "Comm". Value of Comm (aka command) when completely assembled will be like:&lt;br /&gt;&lt;br /&gt;'strpccmd pccmd(\\Server\Directory\SelectedPictureName.xxx)'&lt;br /&gt;&lt;br /&gt;"Todirectory" is a variable which contains the server and share to search for the file.&lt;br /&gt;&lt;br /&gt;CurPicNam is the variable which contains the file name associated with the selected record.&lt;br /&gt;&lt;br /&gt;Txt6 is a constant "')" (single quote and right bracket)&lt;br /&gt;&lt;br /&gt;the %Trim is RPGLE built in function.&lt;br /&gt;__________________&lt;br /&gt;To see how to connect via URL from 5250, try this&lt;br /&gt;&lt;br /&gt;GO MAIN (IBM main menu)&lt;br /&gt;11. Information Assistant&lt;br /&gt;1. Where to look for info&lt;br /&gt;Click on the IBM URL - it takes you right to the web site&lt;br /&gt;&lt;br /&gt;If it doesn't work, you need to enable URL. In the emulator, click Edit / Preferences / Hotspots / Execute URL&lt;br /&gt;&lt;br /&gt;This works with iSeries Access.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8909486560224298250-3502052275262939909?l=prabhatmohapatra.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://prabhatmohapatra.blogspot.com/feeds/3502052275262939909/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://prabhatmohapatra.blogspot.com/2009/04/handling-images-on-as400.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8909486560224298250/posts/default/3502052275262939909'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8909486560224298250/posts/default/3502052275262939909'/><link rel='alternate' type='text/html' href='http://prabhatmohapatra.blogspot.com/2009/04/handling-images-on-as400.html' title='Handling images on AS400'/><author><name>Prabhat</name><uri>http://www.blogger.com/profile/14496453689733819797</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8909486560224298250.post-2230790682433783960</id><published>2009-04-20T01:40:00.000-07:00</published><updated>2009-04-20T01:42:39.937-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Image Handling'/><title type='text'>Image Handling on AS400</title><content type='html'>When we exceute the following command to retrieve a document from the PC&lt;br /&gt;&lt;br /&gt;Strpco&lt;br /&gt;strpccmd pccmd("c:\SomeDirectory\MyResume.doc")&lt;br /&gt;&lt;br /&gt;A dos screen also pops up....&lt;br /&gt;&lt;br /&gt;This is due to the Pause(*NO)&lt;br /&gt;&lt;br /&gt;strpccmd pccmd("c:\SomeDirectory\MyResume.doc") pause(*NO)&lt;br /&gt;&lt;br /&gt;strpccmd pccmd("c:\Somedirectory\MyResume.doc"), this will always popup a dos box, whether it remains open depends on the pause(*no)&lt;br /&gt;&lt;br /&gt;If you want no dos box at all try this:&lt;br /&gt;&lt;br /&gt;strpccmd pccmd('rundll32 Shell32,ShellExec_RunDLL c:\Somedirectory\MyResume.doc') pause(*no)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The computers on German Windows and US Windows all open a DOS popup box whether the PAUSE(*NO) is used or not.&lt;br /&gt;&lt;br /&gt;The difference is that when PAUSE(*NO) is specified the Client Access session is not input inhibited and one need not "Type any key to continue" to close the popup box, this then happens automatically.&lt;br /&gt;&lt;br /&gt;You must first issue the command STRPCO.&lt;br /&gt;&lt;br /&gt;It is possible to save images to a database. The proper way is to define a field as a Binary Large Object or BLOB then you can save any binary file you like to the database. However, I don’t know what an RPG program would make of it and I don’t know if it’s possible if you’re using DDS to create your tables.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;This is not right. I’ve done some more testing and I can now access files on the local PC and they do not have to be shared.&lt;br /&gt;&lt;br /&gt;strpcCMD    (‘”/b g.txt”’)              &lt;br /&gt;strpcCMD    (‘”E:/My Documents/bg.txt”’)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;STRPCCMD works on Bosanova not on ClientAccess, few questions like this also….&lt;br /&gt;&lt;br /&gt;The following command to execute:&lt;br /&gt;&lt;br /&gt;C:\Program Files\Microsoft Office\Office10\Excel:\Lacey.xls&lt;br /&gt;&lt;br /&gt;running this with STRPCCMD works great under Bosanova 5250, but crashes under every version of Client Access we have with this error&lt;br /&gt;Message in the DOS window:&lt;br /&gt;'C:\Program' is not recognized as an internal or external command, executable program or batch file.&lt;br /&gt;&lt;br /&gt;Tried using DOS naming convention, like&lt;br /&gt;C:Progra~1\Micros~1\Office~1\Excel Y:Lacey.xls but that does not work under Client Access either.&lt;br /&gt;&lt;br /&gt;Now a question, how to make this work under Client Access?&lt;br /&gt;&lt;br /&gt;Presumably it was not the following being requests, so I would suggest to try quoting the request; optionally quote the parameter separately, e.g. if it had embedded blanks in its name:&lt;br /&gt;STRPCCMD PCCMD('"C:\Program Files\Microsoft Office\Office10\Excel" Y:\Lacey.xls') PAUSE(*NO)&lt;br /&gt;&lt;br /&gt;If the problem persists, note that the executable is probably named excel.exe versus excel, so that might make a difference as well, since the request is not a /start/ invocation. The shell for a start would look for any executable with the name, irrespective of extension. But&lt;br /&gt;processing for the PCCMD may cause the PC to look for the named file. Thus the request suggested would be:&lt;br /&gt;&lt;br /&gt;STRPCCMD PCCMD('"C:\Program Files\Microsoft&lt;br /&gt;Office\Office10\Excel.exe" Y:\Lacey.xls') PAUSE(*NO)&lt;br /&gt;&lt;br /&gt;An example and reference link:&lt;br /&gt;&lt;br /&gt;STRPCCMD PCCMD('"C:\Program Files\Internet +&lt;br /&gt;Explorer\iexplore.exe" +&lt;br /&gt;http://www.google.com')&lt;br /&gt;PAUSE(*NO)&lt;br /&gt;&lt;br /&gt;&lt;a href="http://archive.midrange.com/midrange.../msg01088.html"&gt;http://archive.midrange.com/midrange.../msg01088.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Note that calling out excel and iexplore in the above PCCMD requests forces the named application to be used, instead of allowing the default file handler application to be invoked according to the file extension.&lt;br /&gt;&lt;a href="http://archive.midrange.com/midrange.../msg01086.html"&gt;http://archive.midrange.com/midrange.../msg01086.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Per above link, a way to affect the user's choice of URL handler follows in an example and reference link:&lt;br /&gt;&lt;br /&gt;STRPCCMD PCCMD('rundll32 url.dll,FileProtocolHandler +&lt;br /&gt;http://www.mywebpage.com?&amp;amp;userid=My+Name') +&lt;br /&gt;PAUSE(*NO)&lt;br /&gt;&lt;br /&gt;&lt;a href="http://archive.midrange.com/midrange.../msg01079.html"&gt;http://archive.midrange.com/midrange.../msg01079.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;or this example and reference link:&lt;br /&gt;&lt;br /&gt;STRPCCMD PCCMD('rundll32 Shell32,ShellExec_RunDLL +&lt;br /&gt;"mysheet.xls"') PAUSE(*NO)&lt;br /&gt;&lt;br /&gt;&lt;a href="http://archive.midrange.com/rpg400-l.../msg00304.html"&gt;http://archive.midrange.com/rpg400-l.../msg00304.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="color:#ff0000;"&gt;LinkIt&lt;/span&gt;&lt;/strong&gt; is an integration tool that can link legacy systems such as System i or Mainframe with any PC application.&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#ff0000;"&gt;LinkIt&lt;/span&gt; is designed to supply a quick and easy method of integrating information based on data displayed on emulation screens.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;u&gt;LinkIt Abilities&lt;/u&gt;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3366ff;"&gt;Scan and catalog documents&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3366ff;"&gt;Retrieve and display archived documents&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#3366ff;"&gt;Export sub-file data into Excel&lt;br /&gt;&lt;br /&gt;Generate Word documents&lt;br /&gt;&lt;br /&gt; Integrate fully with Outlook&lt;br /&gt;&lt;br /&gt;Integrate any PC application&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8909486560224298250-2230790682433783960?l=prabhatmohapatra.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://prabhatmohapatra.blogspot.com/feeds/2230790682433783960/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://prabhatmohapatra.blogspot.com/2009/04/image-handling-on-as400.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8909486560224298250/posts/default/2230790682433783960'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8909486560224298250/posts/default/2230790682433783960'/><link rel='alternate' type='text/html' href='http://prabhatmohapatra.blogspot.com/2009/04/image-handling-on-as400.html' title='Image Handling on AS400'/><author><name>Prabhat</name><uri>http://www.blogger.com/profile/14496453689733819797</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8909486560224298250.post-5367870072176765762</id><published>2009-04-20T01:39:00.000-07:00</published><updated>2009-04-20T01:40:39.199-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='DDS'/><title type='text'>Declare the BINARY Data Type Using DDS</title><content type='html'>We've all heard by now that defining tables using DDS is becoming outdated and that developers need to use SQL in order to access the relatively new data types, including DATALINK and Large Objects (BLOB, CLOB, and DBCLOB).&lt;br /&gt;I recently ran into a situation where I wanted to change a field in an existing table to use the new (as of V5R3) BINARY data type for encrypting credit card data. (Recall that the BINARY data type is similar to character data tagged with a CCSID of 65535. However, data in a BINARY column will never be translated whereas the character data tagged with CCSID 65535 may still be translated depending on the environment settings.) Because it is a "new" SQL data type, I figured the BINARY data type wasn't available in DDS.&lt;br /&gt;However, because of issues with the customer's source management software, I still wanted to re-define the table using the existing DDS rather than change the table definition and related indexes to SQL. It was at this time that I did a little snooping and found that the BINARY data type is definable using DDS. The trick to getting this to work is by specifying a data type of '5' in the data type column of the field definition. Here is an example:&lt;br /&gt;&lt;br /&gt;R DATAFILER                                                &lt;br /&gt;  CHARDATA     200A         TEXT('EQUIV TO SQL CHAR(200)') &lt;br /&gt;  BINARYDATA   2005         TEXT('EQUIV TO SQL BINARY(200)')&lt;br /&gt;&lt;br /&gt;To create a VARBINARY field instead of BINARY, just add the VARLEN keyword to the field definition.&lt;br /&gt;The main stumbling block here is that this information is documented in the DDS manual but is not documented in the SEU help on V5R3 or V5R4. After checking the SEU help I almost gave up! I constantly need to remind myself to check multiple sources before giving up on a problem.&lt;br /&gt;Incidentally, as far as converting an existing field, a character field can be converted to a binary field using the CHGPF command as long as the character field is tagged with CCSID 65535. If the character field is not tagged with CCSID 65535, you'll have to change the table definition twice: once to change the CCSID of the column to 65535 and then again in order to change the field type from character to binary. In case you're like me and assumed that BINARY isn't definable with DDS, remember to use data type '5'. While it is helpful to know SQL for using the new data types, for legacy files it is handy to be able to use binary columns in existing DDS definitions.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8909486560224298250-5367870072176765762?l=prabhatmohapatra.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://prabhatmohapatra.blogspot.com/feeds/5367870072176765762/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://prabhatmohapatra.blogspot.com/2009/04/declare-binary-data-type-using-dds.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8909486560224298250/posts/default/5367870072176765762'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8909486560224298250/posts/default/5367870072176765762'/><link rel='alternate' type='text/html' href='http://prabhatmohapatra.blogspot.com/2009/04/declare-binary-data-type-using-dds.html' title='Declare the BINARY Data Type Using DDS'/><author><name>Prabhat</name><uri>http://www.blogger.com/profile/14496453689733819797</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8909486560224298250.post-8283788999122982790</id><published>2009-04-16T04:16:00.000-07:00</published><updated>2009-04-16T04:25:31.320-07:00</updated><title type='text'>Convert PF to CSV file</title><content type='html'>&lt;strong&gt;&lt;u&gt;Convert PF to CSV file&lt;br /&gt;&lt;/u&gt;&lt;/strong&gt;CL Program:&lt;br /&gt;&lt;span style="font-size:78%;"&gt;CRTPF CSVFILE RCDLEN(whatever record length you need)&lt;br /&gt;CPYTOIMPF FROMFILE(LBIFIL/ARACUST)  + TOSTMF('/myfolder/myfile.csv') STMFCODPAG(*PCASCII) + RCDDLM(*CRLF)&lt;br /&gt;OVRDBF INPUT MYLIB/MYSRC MBR(MYSCRIPT) SHARE(*YES)&lt;br /&gt;OVRDBF OUTPUT MYLIB/MYSRC MBR(MYLOG) SHARE(*YES)&lt;br /&gt;FTP XXX.XXX.XXX.XXX&lt;br /&gt;DLTOVR *ALL&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Create the empty source members for MYLIB/MYSRC&lt;br /&gt;&lt;br /&gt;Wrklnk myfolder&lt;br /&gt;&lt;br /&gt;&lt;u&gt;ftp script&lt;br /&gt;&lt;/u&gt;&lt;br /&gt;userprofile password&lt;br /&gt;put csvfile targetfile.csv&lt;br /&gt;quit&lt;br /&gt;&lt;br /&gt;FTP your.ip.addr.ess&lt;br /&gt;username password&lt;br /&gt;NAMEFMT 1&lt;br /&gt;LCD yourfolder/path/to/object&lt;br /&gt;CD to/remote/target/folder&lt;br /&gt;PUT filename.CSV&lt;br /&gt;QUIT&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Iseries To .CSV&lt;br /&gt;&lt;/u&gt;Selected field convert to CSV&lt;br /&gt;&lt;br /&gt;This utility will allow you to select specific fields for an Iseries table and convert the data to csv. It has a few examples of API usage. This program takes selections from a display panel and writes them to a dataqueue. It then submits itself to batch and receives the selected fields from the dataqueue.&lt;br /&gt;It also creates a source physical file, adds a member, writes field data to the source then complies itself.&lt;br /&gt;There may or may not be a good use for this example but it can be a building point for many other applications.&lt;br /&gt;&lt;br /&gt;API’s used&lt;br /&gt;&lt;br /&gt;QUSROBJD - Retrieve Object description&lt;br /&gt;QUSLFLD - List fields&lt;br /&gt;QUSCRTUS - Create userspace&lt;br /&gt;QSNDDTAQ - Send data to a dataqueue&lt;br /&gt;&lt;br /&gt;Display File&lt;br /&gt;---------------------&lt;br /&gt;&lt;span style="font-size:78%;"&gt;     A*%%EC&lt;br /&gt;     A                                      DSPSIZ(24 80 *DS3)&lt;br /&gt;     A                                      PRINT&lt;br /&gt;     A                                      ERRSFL&lt;br /&gt;     A                                      CF03(03 'Exit')&lt;br /&gt;     A                                      CF12(12 'Return')&lt;br /&gt;     A                                      CF05(05 'Refresh')&lt;br /&gt;     A*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-&lt;br /&gt;     A* SCRN01 : Criteria Screen&lt;br /&gt;     A*-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-&lt;br /&gt;     A          R SCRN01&lt;br /&gt;     A                                      OVERLAY&lt;br /&gt;     A                                      CF04(04 'Prompt')&lt;br /&gt;     A                                      RTNCSRLOC(&amp;amp;#REC &amp;amp;#FLD)&lt;br /&gt;     A            #REC          10A  H&lt;br /&gt;     A            #FLD          10A  H&lt;br /&gt;     A                                  1  2DATE&lt;br /&gt;     A                                      EDTWRD('0  /  /  ')&lt;br /&gt;     A                                      COLOR(BLU)&lt;br /&gt;     A                                  2  2TIME&lt;br /&gt;     A                                      COLOR(BLU)&lt;br /&gt;     A                                  1 70USER&lt;br /&gt;     A                                      COLOR(BLU)&lt;br /&gt;     A                                  2 70SYSNAME&lt;br /&gt;     A                                      COLOR(BLU)&lt;br /&gt;     A            C1CNAM        22A  O  1 30&lt;br /&gt;     A            C1DOW          3A  O  1 11COLOR(BLU)&lt;br /&gt;     A                                  2 31'Convert iSeries File'&lt;br /&gt;     A            C1PGMN        10A  O  3 70&lt;br /&gt;     A                                  5  2'Type options, press Enter.'&lt;br /&gt;     A                                      COLOR(BLU)&lt;br /&gt;     A                                  7  2'Input File:'&lt;br /&gt;     A                                  8  4'Library . . . . . . .'&lt;br /&gt;     A            C1FLIB        10A  B  8 27&lt;br /&gt;     A  30                                  DSPATR(PC)&lt;br /&gt;     A  30                                  DSPATR(RI)&lt;br /&gt;     A                                  9  4'File  . . . . . . . .'&lt;br /&gt;     A            C1FNAM        10A  B  9 27&lt;br /&gt;     A  31                                  DSPATR(PC)&lt;br /&gt;     A  31                                  DSPATR(RI)&lt;br /&gt;     A                                 11  2'Output File:'&lt;br /&gt;     A                                 12  4'IFS File  . . . . . .'&lt;br /&gt;     A            C1FLDR        30A  B 12 37&lt;br /&gt;     A  32                                  DSPATR(PC)&lt;br /&gt;     A  32                                  DSPATR(RI)&lt;br /&gt;     A                                      CHECK(LC)&lt;br /&gt;     A                                 13  4'Extension Type  . . .'&lt;br /&gt;     A            C1FTYP         1A  B 13 27&lt;br /&gt;     A  33                                  DSPATR(PC)&lt;br /&gt;     A  33                                  DSPATR(RI)&lt;br /&gt;     A                                 23  2'F3=Exit'&lt;br /&gt;     A                                      COLOR(BLU)&lt;br /&gt;     A                                 23 22'F12=Return'&lt;br /&gt;     A                                      COLOR(BLU)&lt;br /&gt;     A                                  3  2'SCRN01'&lt;br /&gt;     A                                 12 27'/code400/'&lt;br /&gt;     A                                      COLOR(WHT)&lt;br /&gt;     A                                 23 11'F4=Prompt'&lt;br /&gt;     A                                      COLOR(BLU)&lt;br /&gt;     A                                 13 31'C=CSV'&lt;br /&gt;      *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-&lt;br /&gt;      * MSGSFL : Message Subfile&lt;br /&gt;      *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-&lt;br /&gt;     A          R MSGSFL                    SFL&lt;br /&gt;     A                                      SFLMSGRCD(24)&lt;br /&gt;     A            MSGKEY                    SFLMSGKEY&lt;br /&gt;     A            PGMQ                      SFLPGMQ(10)&lt;br /&gt;      *&lt;br /&gt;     A          R MSGCTL                    SFLCTL(MSGSFL)&lt;br /&gt;     A                                      OVERLAY&lt;br /&gt;     A                                      SFLDSP&lt;br /&gt;     A                                      SFLDSPCTL&lt;br /&gt;     A                                      SFLINZ&lt;br /&gt;     A N03                                  SFLEND&lt;br /&gt;     A                                      SFLSIZ(0002)&lt;br /&gt;     A                                      SFLPAG(0001)&lt;br /&gt;     A            PGMQ                      SFLPGMQ(10)&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;RPG program&lt;br /&gt;&lt;br /&gt;      *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-&lt;br /&gt;      * Program Name:&lt;br /&gt;      * Description : Convert iSeries File to CSV format.&lt;br /&gt;      * Written By  :&lt;br /&gt;      * Written On  :&lt;br /&gt;      *&lt;br /&gt;      * Modification:&lt;br /&gt;      * ~~~~~~~~~~~~&lt;br /&gt;      * Date     Project Pgmr Description&lt;br /&gt;      * ~~~~~~~~ ~~~~~~~ ~~~~ ~~~~~~~~~~~&lt;br /&gt;      *  Must create your own message file&lt;br /&gt;      *  Must change worklibrary inz value to your library name&lt;br /&gt;      *&lt;br /&gt;      *&lt;br /&gt;      *&lt;br /&gt;      *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-&lt;br /&gt;      * Display File&lt;br /&gt;      * ~~~~~~~~~~~~&lt;br /&gt;     FCVTPF01D  cf   e             workstn usropn&lt;br /&gt;      *&lt;br /&gt;      * Work File&lt;br /&gt;      * ~~~~~~~~~&lt;br /&gt;     FCVTSRCPF  uf a e           k disk    rename(CVTSRCPF : CVTPFR)&lt;br /&gt;     F                                     usropn&lt;br /&gt;     F                                     prefix(x)&lt;br /&gt;      *&lt;br /&gt;      *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=&lt;br /&gt;      *&lt;br /&gt;      * Program Information&lt;br /&gt;      * ~~~~~~~~~~~~~~~~~~~&lt;br /&gt;     D PgmInfo        sds&lt;br /&gt;     D  @PgmName               1     10&lt;br /&gt;     D  @Parms                37     39  0&lt;br /&gt;     D  @MsgID                40     46&lt;br /&gt;     D  @JobName             244    253&lt;br /&gt;     D  @UserId              254    263&lt;br /&gt;     D  @JobNbr              264    269  0&lt;br /&gt;      *&lt;br /&gt;      * Message SFL Information&lt;br /&gt;      * ~~~~~~~~~~~~~~~~~~~~~~~&lt;br /&gt;     D                 ds                        inz&lt;br /&gt;     D STKCNT                  1      4B 0&lt;br /&gt;     D DTALEN                  5      8B 0&lt;br /&gt;     D ERRCOD                  9     12B 0&lt;br /&gt;      *&lt;br /&gt;      * Subprocedure(s)&lt;br /&gt;      * ~~~~~~~~~~~~~~~&lt;br /&gt;     D $GetDOW         pr             3a&lt;br /&gt;     D  InpDate                        d   value&lt;br /&gt;     D $RtvMbrd        pr             1a&lt;br /&gt;     D  MemberName                   20a   value&lt;br /&gt;     D $GetJobType     pr             1a&lt;br /&gt;     D $ReceiveDataQ   pr          1024a&lt;br /&gt;     D  DataQ                        20a   value&lt;br /&gt;      *&lt;br /&gt;      * Field Definitions&lt;br /&gt;      * ~~~~~~~~~~~~~~~~~&lt;br /&gt;     D @Scrn1          s              1    inz('Y')&lt;br /&gt;      *&lt;br /&gt;     D MemberError     s              1    inz('N')&lt;br /&gt;     D ScreenError     s              1    inz('N')&lt;br /&gt;      *&lt;br /&gt;     D CorpName        s             30    inz(*blanks)&lt;br /&gt;     D JobType         s              1    inz(*blanks)&lt;br /&gt;      *&lt;br /&gt;     D InputLib        s             10    inz(*blanks)&lt;br /&gt;     D InputName       s             10    inz(*blanks)&lt;br /&gt;     D DataQName       s             10    inz(*blanks)&lt;br /&gt;     D DataQLib        s             10    inz(*blanks)&lt;br /&gt;     D DataQ           s             20    inz(*blanks)&lt;br /&gt;     D InputFile       s             20    inz(*blanks)&lt;br /&gt;     D IFSFileName     s             50    inz(*blanks)&lt;br /&gt;     D FieldName       s             10    inz(*blanks)&lt;br /&gt;     D FieldDesc       s             50    inz(*blanks)&lt;br /&gt;     D DataQData       s           1024    inz(*blanks)&lt;br /&gt;     D IFSFolder       s            100    inz(*blanks)&lt;br /&gt;     D IFSFolders      s            100    inz(*blanks)&lt;br /&gt;     D WorkLibrary     s             10    inz('SOMELIB')&lt;br /&gt;      *&lt;br /&gt;     D pInputLib       s             10&lt;br /&gt;     D pInputName      s             10&lt;br /&gt;     D pFolders        s             30&lt;br /&gt;     D pIFSFileType    s              1&lt;br /&gt;     D pDataQLib       s             10&lt;br /&gt;     D pDataQName      s             10&lt;br /&gt;     D IFSFileType     s              1    inz(*blanks)&lt;br /&gt;      *&lt;br /&gt;     D CmdString       s            256    inz(*blanks)&lt;br /&gt;     D CmdLength       s             15  5 inz(0)&lt;br /&gt;      *&lt;br /&gt;     D SQLSelect       s          10000    inz(*blanks)&lt;br /&gt;     D SQLStmt         s          10000    inz(*blanks)&lt;br /&gt;     D SQLResult       s          10000    inz(*blanks)&lt;br /&gt;      *&lt;br /&gt;     D end             s              5  0 inz(0)&lt;br /&gt;     D pos             s              5  0 inz(0)&lt;br /&gt;     D str             s              5  0 inz(0)&lt;br /&gt;      *&lt;br /&gt;      *-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=&lt;br /&gt;      *  M A I N     L I N E&lt;br /&gt;      *-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=&lt;br /&gt;      *&lt;br /&gt;     C                   eval      PgmQ = @PgmName&lt;br /&gt;     C                   eval      DtaLen = 60&lt;br /&gt;      *&lt;br /&gt;     C                   eval      JobType = $GetJobType&lt;br /&gt;     C                   if        JobType = 'I' and %parms = 0&lt;br /&gt;     C                   exsr      $CreateDataQ&lt;br /&gt;     C                   exsr      $DispScrn01&lt;br /&gt;     C                   else&lt;br /&gt;     C                   exsr      $ConvertPF&lt;br /&gt;     C                   exsr      $DeleteDataQ&lt;br /&gt;     C                   endif&lt;br /&gt;      *&lt;br /&gt;     C                   eval      *inlr = *on&lt;br /&gt;     C                   return&lt;br /&gt;      *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-==-&lt;br /&gt;      * $DispScrn01 - Display Screen 1&lt;br /&gt;      *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-==-&lt;br /&gt;     C     $DispScrn01   begsr&lt;br /&gt;      *&lt;br /&gt;     C                   if        not %open(CVTPF01D)&lt;br /&gt;     C                   open      CVTPF01D&lt;br /&gt;     C                   endif&lt;br /&gt;      *&lt;br /&gt;     C                   exsr      $LoadScrn01&lt;br /&gt;     C                   exsr      $ClrMsg&lt;br /&gt;      *&lt;br /&gt;     C                   eval      @Scrn1 = 'Y'&lt;br /&gt;     C                   dow       @Scrn1 = 'Y'&lt;br /&gt;      *&lt;br /&gt;     C                   write     MSGCTL                               99&lt;br /&gt;     C                   exfmt     SCRN01&lt;br /&gt;      *&lt;br /&gt;     C                   exsr      $ClrMsg&lt;br /&gt;      *&lt;br /&gt;     C                   select&lt;br /&gt;      *&lt;br /&gt;      * F3=Exit&lt;br /&gt;      *&lt;br /&gt;     C                   when      *in03&lt;br /&gt;     C                   eval      @Scrn1 = 'N'&lt;br /&gt;      *&lt;br /&gt;      * F4=Prompt&lt;br /&gt;      *&lt;br /&gt;     C                   when      *in04&lt;br /&gt;     C                   exsr      $Process01&lt;br /&gt;      *&lt;br /&gt;      * F5=Refresh&lt;br /&gt;      *&lt;br /&gt;     C                   when      *in05&lt;br /&gt;     C                   exsr      $LoadScrn01&lt;br /&gt;      *&lt;br /&gt;      * F12=Return&lt;br /&gt;      *&lt;br /&gt;     C                   when      *in12&lt;br /&gt;     C                   eval      @Scrn1 = 'N'&lt;br /&gt;      *&lt;br /&gt;     C                   other&lt;br /&gt;     C                   exsr      $Process01&lt;br /&gt;     C                   endsl&lt;br /&gt;      *&lt;br /&gt;     C                   enddo&lt;br /&gt;      *&lt;br /&gt;     C                   if        %open(CVTPF01D)&lt;br /&gt;     C                   close     CVTPF01D&lt;br /&gt;     C                   endif&lt;br /&gt;      *&lt;br /&gt;     C                   endsr&lt;br /&gt;      *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-==-=-=-=-=-=-==-&lt;br /&gt;      * $Process01 - Process Screen 1&lt;br /&gt;      *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-==-=-=-=-=-=-==-&lt;br /&gt;     C     $Process01    begsr&lt;br /&gt;      *&lt;br /&gt;     C                   exsr      $Validation01&lt;br /&gt;      *&lt;br /&gt;     C                   if        ScreenError = 'N'&lt;br /&gt;      *&lt;br /&gt;     C                   eval      InputLib = C1FLIB&lt;br /&gt;     C                   eval      InputName = C1FNAM&lt;br /&gt;      *&lt;br /&gt;     C                   call      'SPTPFFDR'&lt;br /&gt;     C                   parm                    InputLib&lt;br /&gt;     C                   parm                    InputName&lt;br /&gt;     C                   parm                    DataQLib&lt;br /&gt;     C                   parm                    DataQName&lt;br /&gt;      *&lt;br /&gt;     C                   eval      @Scrn1 = 'N'&lt;br /&gt;     C                   eval      IFSFolders = %trim(C1FLDR)&lt;br /&gt;     C                   select&lt;br /&gt;     C                   when      C1FTYP = 'C'&lt;br /&gt;     C                   eval      pos = %scan('.csv' : %trim(IFSFolders))&lt;br /&gt;     C                   if        pos &lt;= 0&lt;br /&gt;     C                   eval      IFSFolders = %trim(IFSFolders) +&lt;br /&gt;     C                             %trim('.csv')&lt;br /&gt;     C                   endif&lt;br /&gt;     C                   endsl&lt;br /&gt;      *&lt;br /&gt;      * Submit Job&lt;br /&gt;      *&lt;br /&gt;     C                   eval      Cmdstring = %trim('SBMJOB') +&lt;br /&gt;     C                             %trim('~CMD(CALL PGM(CVTPF01R)') +&lt;br /&gt;     C                             %trim('~PARM(') + %trim('''') +&lt;br /&gt;     C                             %trim(InputLib) + %trim('''') +&lt;br /&gt;     C                             %trim('~') + %trim('''') +&lt;br /&gt;     C                             %trim(InputName) + %trim('''') +&lt;br /&gt;     C                             %trim('~') + %trim('''') +&lt;br /&gt;     C                             %trim(C1FTYP) + %trim('''') +&lt;br /&gt;     C                             %trim('~') + %trim('''') +&lt;br /&gt;     C                             %trim(DataQLib) + %trim('''') +&lt;br /&gt;     C                             %trim('~') + %trim('''') +&lt;br /&gt;     C                             %trim(DataQName) + %trim('''') +&lt;br /&gt;     C                             %trim('~') + %trim('''') +&lt;br /&gt;     C                             %trim(IFSFolders) +&lt;br /&gt;     C                             %trim('''') + %trim('))')&lt;br /&gt;     C                   eval      CmdString = %xlate('~' : ' ' : CmdString)&lt;br /&gt;     C                   eval      CmdLength = %size(CmdString)&lt;br /&gt;     C                   call      'QCMDEXC'                            99&lt;br /&gt;     C                   parm                    CmdString&lt;br /&gt;     C                   parm                    CmdLength&lt;br /&gt;      *&lt;br /&gt;     C                   endif&lt;br /&gt;      *&lt;br /&gt;     C                   endsr&lt;br /&gt;      *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-&lt;br /&gt;      * $LoadScrn01 - Load Screen 1&lt;br /&gt;      *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-==-=-=-=-=-=-==-&lt;br /&gt;     C     $LoadScrn01   begsr&lt;br /&gt;      *&lt;br /&gt;     C                   reset                   SCRN01&lt;br /&gt;      *&lt;br /&gt;     C                   eval      C1PGMN = @PgmName&lt;br /&gt;      *&lt;br /&gt;     C                   eval      C1CNAM = %trim(CorpName)&lt;br /&gt;     C                   eval      C1DOW  = $GetDOW(%date())&lt;br /&gt;      *&lt;br /&gt;     C                   eval      C1FTYP = 'C'&lt;br /&gt;      *&lt;br /&gt;     C                   endsr&lt;br /&gt;      *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=-==-&lt;br /&gt;      * $Validation01 - Validate Screen 1&lt;br /&gt;      *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--==-=-=-=-=-=-==-&lt;br /&gt;     C     $Validation01 begsr&lt;br /&gt;      *&lt;br /&gt;      * Reset Validation Variables&lt;br /&gt;      *&lt;br /&gt;     C                   eval      *in30 = *off&lt;br /&gt;     C                   eval      *in31 = *off&lt;br /&gt;     C                   eval      *in32 = *off&lt;br /&gt;     C                   eval      *in33 = *off&lt;br /&gt;     C                   eval      ScreenError = 'N'&lt;br /&gt;      *&lt;br /&gt;      * Validation&lt;br /&gt;      *&lt;br /&gt;     C                   if        C1FLIB = *blanks&lt;br /&gt;     C                   eval      *in30 = *on&lt;br /&gt;     C                   eval      ScreenError = 'Y'&lt;br /&gt;     C                   eval      MSGDTA = *blanks&lt;br /&gt;     C                   eval      MSGID = 'ROL0056'&lt;br /&gt;     C                   exsr      $SndMsg&lt;br /&gt;     C                   endif&lt;br /&gt;      *&lt;br /&gt;     C                   if        C1FNAM = *blanks&lt;br /&gt;     C                   eval      *in31 = *on&lt;br /&gt;     C                   eval      ScreenError = 'Y'&lt;br /&gt;     C                   eval      MSGDTA = *blanks&lt;br /&gt;     C                   eval      MSGID = 'ROL0057'&lt;br /&gt;     C                   exsr      $SndMsg&lt;br /&gt;     C                   endif&lt;br /&gt;      *&lt;br /&gt;     C                   eval      InputFile = C1FNAM + C1FLIB&lt;br /&gt;     C                   eval      MemberError = $RtvMbrD(InputFile)&lt;br /&gt;     C                   if        MemberError = 'Y'&lt;br /&gt;     C                   eval      *in30 = *on&lt;br /&gt;     C                   eval      *in31 = *on&lt;br /&gt;     C                   eval      ScreenError = 'Y'&lt;br /&gt;     C                   eval      MSGDTA = %trim(C1FNAM)+' in '+%trim(C1FLIB)&lt;br /&gt;     C                   eval      MSGID = 'ROL0055'&lt;br /&gt;     C                   exsr      $SndMsg&lt;br /&gt;     C                   endif&lt;br /&gt;      *&lt;br /&gt;     C                   eval      IFSFolders = *blanks&lt;br /&gt;     C                   eval      str = 1&lt;br /&gt;     C                   eval      pos = %scan('/' : %trim(C1FLDR))&lt;br /&gt;     C                   dow       pos &gt; 0&lt;br /&gt;     C                   eval      end = str&lt;br /&gt;     C                   if        pos &gt; 1&lt;br /&gt;     C                   eval      end = pos - 1&lt;br /&gt;     C                   endif&lt;br /&gt;     C                   eval      IFSFolders = %trim(IFSFolders) +&lt;br /&gt;     C                             %subst(%trim(C1FLDR) : str : end)&lt;br /&gt;     C                   eval      str = end + 2&lt;br /&gt;     C                   eval      pos = %scan('/' : %trim(C1FLDR) : str)&lt;br /&gt;     C                   enddo&lt;br /&gt;      *&lt;br /&gt;     C                   if        C1FLDR &lt;&gt; *blanks and str &gt; 0 and pos = 0&lt;br /&gt;     C                   eval      IFSFileName = %subst(%trim(C1FLDR) : str)&lt;br /&gt;     C                   endif&lt;br /&gt;     C                   select&lt;br /&gt;     C                   when      IFSFileName = *blanks&lt;br /&gt;     C                   eval      *in32 = *on&lt;br /&gt;     C                   eval      ScreenError = 'Y'&lt;br /&gt;     C                   eval      MSGDTA = *blanks&lt;br /&gt;     C                   eval      MSGID = 'ROL0051'&lt;br /&gt;     C                   exsr      $SndMsg&lt;br /&gt;     C                   when      IFSFileName &lt;&gt; *blanks&lt;br /&gt;     C                   eval      pos = %scan('.' : %trim(IFSFileName))&lt;br /&gt;     C                   if        pos &gt; 0&lt;br /&gt;     C                   eval      pos = %scan('.csv' : %trim(C1FLDR))&lt;br /&gt;     C                   if        pos &lt;= 0&lt;br /&gt;     C                   eval      *in32 = *on&lt;br /&gt;     C                   eval      ScreenError = 'Y'&lt;br /&gt;     C                   eval      MSGDTA = *blanks&lt;br /&gt;     C                   eval      MSGID = 'ROL0051'&lt;br /&gt;     C                   exsr      $SndMsg&lt;br /&gt;     C                   endif&lt;br /&gt;     C                   endif&lt;br /&gt;     C                   endsl&lt;br /&gt;      *&lt;br /&gt;     C                   if        C1FTYP &lt;&gt; 'C'&lt;br /&gt;     C                   eval      *in33 = *on&lt;br /&gt;     C                   eval      ScreenError = 'Y'&lt;br /&gt;     C                   eval      MSGDTA = *blanks&lt;br /&gt;     C                   eval      MSGID = 'ROL0009'&lt;br /&gt;     C                   exsr      $SndMsg&lt;br /&gt;     C                   endif&lt;br /&gt;      *&lt;br /&gt;     C                   endsr&lt;br /&gt;      *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-&lt;br /&gt;      * $CreateFolder - Create IFS Directory.&lt;br /&gt;      * MD DIR('/shippingdocument/test') DTAAUT(*RWX) OBJAUT(*ALL).&lt;br /&gt;      *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-&lt;br /&gt;     C     $CreateFolder begsr&lt;br /&gt;      *&lt;br /&gt;     C                   eval      IFSFolder = '/' + %trim(WorkLibrary)&lt;br /&gt;     C                   exsr      $CreateFldCmd&lt;br /&gt;     C                   eval      IFSFolder = '/' + %trim(WorkLibrary) + '/'&lt;br /&gt;      *&lt;br /&gt;     C                   eval      str = 1&lt;br /&gt;     C                   eval      pos = %scan('/' : %trim(IFSFolders))&lt;br /&gt;     C                   dow       pos &gt; 0&lt;br /&gt;     C                   eval      end = str&lt;br /&gt;     C                   if        pos &gt; 1&lt;br /&gt;     C                   eval      end = pos - 1&lt;br /&gt;     C                   endif&lt;br /&gt;     C                   eval      IFSFolder = %trim(IFSFolder) +&lt;br /&gt;     C                             %subst(%trim(IFSFolders) : str : end)&lt;br /&gt;     C                   exsr      $CreateFldCmd&lt;br /&gt;     C                   eval      str = end + 2&lt;br /&gt;     C                   eval      pos = %scan('/' : %trim(IFSFolders) : str)&lt;br /&gt;     C                   enddo&lt;br /&gt;      *&lt;br /&gt;     C                   eval      IFSFolders = '/' + %trim(WorkLibrary) + '/'+&lt;br /&gt;     C                             %trim(IFSFolders)&lt;br /&gt;      *&lt;br /&gt;     C                   endsr&lt;br /&gt;      *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-==-=-=-=-=-=-==-&lt;br /&gt;      * $CreateFldCmd - Create Directory Command&lt;br /&gt;      *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-==-&lt;br /&gt;     C     $CreateFldCmd begsr&lt;br /&gt;      *&lt;br /&gt;     C                   eval      CmdString = %trim('MD~') +&lt;br /&gt;     C                             %trim('~DIR(''') + %trim(IFSFolder) +&lt;br /&gt;     C                             %trim(''')') +&lt;br /&gt;     C                             %trim('~DTAAUT(*RWX)') +&lt;br /&gt;     C                             %trim('~OBJAUT(*ALL)')&lt;br /&gt;     C                   eval      CmdString = %xlate('~' : ' ' : CmdString)&lt;br /&gt;     C                   eval      CmdLength = %size(CmdString)&lt;br /&gt;     C                   call      'QCMDEXC'                            99&lt;br /&gt;     C                   parm                    CmdString&lt;br /&gt;     C                   parm                    CmdLength&lt;br /&gt;      *&lt;br /&gt;     C                   endsr&lt;br /&gt;      *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-==-=-=-=-=-=-==-&lt;br /&gt;      * $CloseTempPF&lt;br /&gt;      *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=-=-==-&lt;br /&gt;     C     $CloseTempPF  begsr&lt;br /&gt;      *&lt;br /&gt;      * Delete Create Physical File&lt;br /&gt;      *&lt;br /&gt;     C                   eval      CmdString = %trim('~DLTF') +&lt;br /&gt;     C                             %trim('~FILE(QTEMP/CVTSRCPFF)')&lt;br /&gt;     C                   eval      CmdString = %xlate('~' : ' ' : CmdString)&lt;br /&gt;     C                   eval      CmdLength = %size(CmdString)&lt;br /&gt;     C                   call      'QCMDEXC'                            99&lt;br /&gt;     C                   parm                    CmdString&lt;br /&gt;     C                   parm                    CmdLength&lt;br /&gt;     C                   endsr&lt;br /&gt;      *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-&lt;br /&gt;      * $ConvertPF - Convert Physical File&lt;br /&gt;      *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-==-&lt;br /&gt;     C     $ConvertPF    begsr&lt;br /&gt;      *&lt;br /&gt;     C                   eval      DataQLib = pDataQLib&lt;br /&gt;     C                   eval      DataQName = pDataQName&lt;br /&gt;     C                   eval      InputLib  = pInputLib&lt;br /&gt;     C                   eval      InputName = pInputName&lt;br /&gt;     C                   eval      IFSFolders = pFolders&lt;br /&gt;     C                   eval      IFSFileType = pIFSFileType&lt;br /&gt;     C                   eval      SQLSelect = *blanks&lt;br /&gt;      *&lt;br /&gt;     C                   exsr      $CreateFolder&lt;br /&gt;     C                   exsr      $CreateTempPF&lt;br /&gt;      *&lt;br /&gt;     C                   select&lt;br /&gt;     C                   when      IFSFileType = 'C'&lt;br /&gt;     C                   exsr      $CreateCSVF&lt;br /&gt;     C                   endsl&lt;br /&gt;      *&lt;br /&gt;     C                   exsr      $CloseTempPF&lt;br /&gt;      *&lt;br /&gt;     C                   endsr&lt;br /&gt;      *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=-&lt;br /&gt;      * Create/Copy Temporary Physical File&lt;br /&gt;      *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-&lt;br /&gt;     C     $CreateTempPF begsr&lt;br /&gt;      *&lt;br /&gt;      * Create Source Physical File&lt;br /&gt;      *&lt;br /&gt;     C                   eval      CmdString = %trim('~CRTSRCPF') +&lt;br /&gt;     C                             %trim('~FILE(QTEMP/CVTSRCPF)') +&lt;br /&gt;     C                             %trim('~RCDLEN(92)')&lt;br /&gt;     C                   eval      CmdString = %xlate('~' : ' ' : CmdString)&lt;br /&gt;     C                   eval      CmdLength = %size(CmdString)&lt;br /&gt;     C                   call      'QCMDEXC'                            99&lt;br /&gt;     C                   parm                    CmdString&lt;br /&gt;     C                   parm                    CmdLength&lt;br /&gt;      *&lt;br /&gt;      * Add Physical File Member&lt;br /&gt;      *&lt;br /&gt;     C                   eval      CmdString = %trim('~ADDPFM') +&lt;br /&gt;     C                             %trim('~FILE(QTEMP/CVTSRCPF)') +&lt;br /&gt;     C                             %trim('~MBR(CVTSRCPFF)')&lt;br /&gt;     C                   eval      CmdString = %xlate('~' : ' ' : CmdString)&lt;br /&gt;     C                   eval      CmdLength = %size(CmdString)&lt;br /&gt;     C                   call      'QCMDEXC'                            99&lt;br /&gt;     C                   parm                    CmdString&lt;br /&gt;     C                   parm                    CmdLength&lt;br /&gt;      *&lt;br /&gt;      * Clear Physical File Member&lt;br /&gt;      *&lt;br /&gt;     C                   eval      CmdString = %trim('~CLRPFM') +&lt;br /&gt;     C                             %trim('~FILE(QTEMP/CVTSRCPF)') +&lt;br /&gt;     C                             %trim('~MBR(CVTSRCPFF)')&lt;br /&gt;     C                   eval      CmdString = %xlate('~' : ' ' : CmdString)&lt;br /&gt;     C                   eval      CmdLength = %size(CmdString)&lt;br /&gt;     C                   call      'QCMDEXC'                            99&lt;br /&gt;     C                   parm                    CmdString&lt;br /&gt;     C                   parm                    CmdLength&lt;br /&gt;      *&lt;br /&gt;      * Override&lt;br /&gt;      *&lt;br /&gt;     C                   eval      CmdString = %trim('~OVRDBF') +&lt;br /&gt;     C                             %trim('~FILE(CVTSRCPF)') +&lt;br /&gt;     C                             %trim('~TOFILE(QTEMP/CVTSRCPF)') +&lt;br /&gt;     C                             %trim('~MBR(CVTSRCPFF)')&lt;br /&gt;     C                   eval      CmdString = %xlate('~' : ' ' : CmdString)&lt;br /&gt;     C                   eval      CmdLength = %size(CmdString)&lt;br /&gt;     C                   call      'QCMDEXC'                            99&lt;br /&gt;     C                   parm                    CmdString&lt;br /&gt;     C                   parm                    CmdLength&lt;br /&gt;      *&lt;br /&gt;      * Open Source Physical File&lt;br /&gt;      *&lt;br /&gt;     C                   if        not %open(CVTSRCPF)&lt;br /&gt;     C                   open      CVTSRCPF&lt;br /&gt;     C                   endif&lt;br /&gt;      *&lt;br /&gt;      * Get Data from Data Queue and Write to Source Physical File&lt;br /&gt;      *&lt;br /&gt;     C                   eval      DataQ = DataQLib + DataQName&lt;br /&gt;      *&lt;br /&gt;     C                   eval      DataQData = $ReceiveDataQ(DataQ)&lt;br /&gt;     C                   if        DataQData &lt;&gt; *blanks&lt;br /&gt;     C                   reset                   xSRCDTA&lt;br /&gt;     C                   eval      %subst(xSRCDTA : 6) = 'A'&lt;br /&gt;     C                   eval      %subst(xSRCDTA : 17) = 'R'&lt;br /&gt;     C                   eval      %subst(xSRCDTA : 19) = 'RECNAMR'&lt;br /&gt;     C                   eval      %subst(xSRCDTA : 45) =&lt;br /&gt;     C                             %trim('TEXT(''Temporary PF'')')&lt;br /&gt;     C                   write     CVTPFR&lt;br /&gt;      *&lt;br /&gt;     C                   dow       DataQData &lt;&gt; *blanks&lt;br /&gt;     C                   exsr      $WriteSrcPF&lt;br /&gt;     C                   eval      DataQData = $ReceiveDataQ(DataQ)&lt;br /&gt;     C                   enddo&lt;br /&gt;      *&lt;br /&gt;      * Close Source Physical File&lt;br /&gt;      *&lt;br /&gt;     C                   if        %open(CVTSRCPF)&lt;br /&gt;     C                   close     CVTSRCPF&lt;br /&gt;     C                   endif&lt;br /&gt;      *&lt;br /&gt;      * Create Physical File&lt;br /&gt;      *&lt;br /&gt;     C                   eval      CmdString = %trim('CRTPF') +&lt;br /&gt;     C                             %trim('~FILE(QTEMP/CVTSRCPFF)') +&lt;br /&gt;     C                             %trim('~SRCFILE(QTEMP/CVTSRCPF)') +&lt;br /&gt;     C                             %trim('~SRCMBR(CVTSRCPFF)') +&lt;br /&gt;     C                             %trim('~OPTION(*NOSRC *NOLIST)') +&lt;br /&gt;     C                             %trim('~SIZE(*NOMAX)')&lt;br /&gt;     C                   eval      CmdString = %xlate('~' : ' ' : CmdString)&lt;br /&gt;     C                   eval      CmdLength = %size(CmdString)&lt;br /&gt;     C                   call      'QCMDEXC'                            99&lt;br /&gt;     C                   parm                    CmdString&lt;br /&gt;     C                   parm                    CmdLength&lt;br /&gt;      *&lt;br /&gt;      * Copy Selected Physical File to Created Physical File                P)&lt;br /&gt;      *&lt;br /&gt;     C                   eval      CmdString = %trim('CPYF') +&lt;br /&gt;     C                             %trim('~FROMFILE(') +&lt;br /&gt;     C                             %trim(InputLib) +&lt;br /&gt;     C                             %trim('/') +&lt;br /&gt;     C                             %trim(InputName) +&lt;br /&gt;     C                             %trim(')') +&lt;br /&gt;     C                             %trim('~TOFILE(QTEMP/CVTSRCPFF)') +&lt;br /&gt;     C                             %trim('~MBROPT(*ADD)') +&lt;br /&gt;     C                             %trim('~FMTOPT(*DROP)')&lt;br /&gt;     C                   eval      CmdString = %xlate('~' : ' ' : CmdString)&lt;br /&gt;     C                   eval      CmdLength = %size(CmdString)&lt;br /&gt;     C                   call      'QCMDEXC'                            99&lt;br /&gt;     C                   parm                    CmdString&lt;br /&gt;     C                   parm                    CmdLength&lt;br /&gt;      *&lt;br /&gt;     C                   else&lt;br /&gt;      *&lt;br /&gt;     C                   eval      CmdString = %trim('CPYF') +&lt;br /&gt;     C                             %trim('~FROMFILE(') +&lt;br /&gt;     C                             %trim(InputLib) +&lt;br /&gt;     C                             %trim('/') +&lt;br /&gt;     C                             %trim(InputName) +&lt;br /&gt;     C                             %trim(')') +&lt;br /&gt;     C                             %trim('~TOFILE(QTEMP/CVTSRCPFF)') +&lt;br /&gt;     C                             %trim('~MBROPT(*ADD)') +&lt;br /&gt;     C                             %trim('~CRTFILE(*YES)')&lt;br /&gt;     C                   eval      CmdString = %xlate('~' : ' ' : CmdString)&lt;br /&gt;     C                   eval      CmdLength = %size(CmdString)&lt;br /&gt;     C                   call      'QCMDEXC'                            99&lt;br /&gt;     C                   parm                    CmdString&lt;br /&gt;     C                   parm                    CmdLength&lt;br /&gt;      *&lt;br /&gt;     C                   endif&lt;br /&gt;      *&lt;br /&gt;      * Delete Source Physical File&lt;br /&gt;      *&lt;br /&gt;     C                   eval      CmdString = %trim('~DLTF') +&lt;br /&gt;     C                             %trim('~FILE(QTEMP/CVTSRCPF)')&lt;br /&gt;     C                   eval      CmdString = %xlate('~' : ' ' : CmdString)&lt;br /&gt;     C                   eval      CmdLength = %size(CmdString)&lt;br /&gt;     C                   call      'QCMDEXC'                            99&lt;br /&gt;     C                   parm                    CmdString&lt;br /&gt;     C                   parm                    CmdLength&lt;br /&gt;      *&lt;br /&gt;     C                   endsr&lt;br /&gt;      *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-&lt;br /&gt;      * Create CSV File&lt;br /&gt;      *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-&lt;br /&gt;     C     $CreateCSVF   begsr&lt;br /&gt;      *&lt;br /&gt;      * CPYTOIMPF  FROMFILE(&amp;amp;FROMLIB/&amp;amp;FROMFILE) TOSTMF(&amp;amp;TOFILE) +&lt;br /&gt;      *            MBROPT(*ADD) STMFCODPAG(*PCASCII) +&lt;br /&gt;      *            RCDDLM(*CRLF)&lt;br /&gt;      *&lt;br /&gt;     C                   eval      CmdString = %trim('CPYTOIMPF') +&lt;br /&gt;     C                             %trim('~FROMFILE(QTEMP/CVTSRCPFF)') +&lt;br /&gt;     C                             %trim('~TOSTMF(''') + %trim(IFSFolders) +&lt;br /&gt;     C                             %trim(''')') +&lt;br /&gt;     C                             %trim('~MBROPT(*REPLACE)') +&lt;br /&gt;     C                             %trim('~STMFCODPAG(*PCASCII)') +&lt;br /&gt;     C                             %trim('~RCDDLM(*CRLF)')&lt;br /&gt;     C                   eval      CmdString = %xlate('~' : ' ' : CmdString)&lt;br /&gt;     C                   eval      CmdLength = %size(CmdString)&lt;br /&gt;     C                   call      'QCMDEXC'                            99&lt;br /&gt;     C                   parm                    CmdString&lt;br /&gt;     C                   parm                    CmdLength&lt;br /&gt;      *&lt;br /&gt;     C                   endsr&lt;br /&gt;      *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-&lt;br /&gt;      * Write Record to Source Physical File&lt;br /&gt;      *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-&lt;br /&gt;     C     $WriteSrcPF   begsr&lt;br /&gt;      *&lt;br /&gt;     C                   reset                   xSRCDTA&lt;br /&gt;     C                   eval      %subst(xSRCDTA:6) = 'A'&lt;br /&gt;     C                   eval      %subst(xSRCDTA:19) = %subst(DataQData:1:10)&lt;br /&gt;     C                   eval      %subst(xSRCDTA:30) = %subst(DataQData:11:5)&lt;br /&gt;     C                   eval      %subst(xSRCDTA:35) = %subst(DataQData:16:1)&lt;br /&gt;     C                   eval      %subst(xSRCDTA:36) = %subst(DataQData:17:2)&lt;br /&gt;     C                   eval      %subst(xSRCDTA:45) = %trim('COLHDG(''') +&lt;br /&gt;     C                             %trim(%subst(DataQData:19:20)) +&lt;br /&gt;     C                             %trim(''')')&lt;br /&gt;     C                   write     CVTPFR&lt;br /&gt;      *&lt;br /&gt;     C                   endsr&lt;br /&gt;      *-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=&lt;br /&gt;      * Create Data Queue&lt;br /&gt;      *-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=&lt;br /&gt;     C     $CreateDataQ  begsr&lt;br /&gt;      *&lt;br /&gt;     C                   eval      DataQLib = %trim(WorkLibrary)&lt;br /&gt;     C                   eval      DataQName = %trim('DTAQ') +&lt;br /&gt;     C                             %trim(%char(%time() : *iso0))&lt;br /&gt;      *&lt;br /&gt;     C                   eval      CmdString = %trim('CRTDTAQ') +&lt;br /&gt;     C                             %trim('~DTAQ(') + %trim(DataQLib) +&lt;br /&gt;     C                             %trim('/') + %trim(DataQName) + %trim(')') +&lt;br /&gt;     C                             %trim('~TYPE(*STD)') +&lt;br /&gt;     C                             %trim('~MAXLEN(1024)') +&lt;br /&gt;     C                             %trim('~SIZE(*MAX16MB)')&lt;br /&gt;     C                   eval      CmdString = %xlate('~' : ' ' : CmdString)&lt;br /&gt;     C                   eval      CmdLength = %size(CmdString)&lt;br /&gt;     C                   call      'QCMDEXC'                            99&lt;br /&gt;     C                   parm                    CmdString&lt;br /&gt;     C                   parm                    CmdLength&lt;br /&gt;      *&lt;br /&gt;     C                   endsr&lt;br /&gt;      *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-==-=-=-=-=-=-==-&lt;br /&gt;      * Delete Data Queue&lt;br /&gt;      *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-==-&lt;br /&gt;     C     $DeleteDataQ  begsr&lt;br /&gt;      *&lt;br /&gt;     C                   eval      CmdString = %trim('DLTDTAQ') +&lt;br /&gt;     C                             %trim('~DTAQ(') + %trim(DataQLib) +&lt;br /&gt;     C                             %trim('/') + %trim(DataQName) + %trim(')')&lt;br /&gt;     C                   eval      CmdString = %xlate('~' : ' ' : CmdString)&lt;br /&gt;     C                   eval      CmdLength = %size(CmdString)&lt;br /&gt;     C                   call      'QCMDEXC'                            99&lt;br /&gt;     C                   parm                    CmdString&lt;br /&gt;     C                   parm                    CmdLength&lt;br /&gt;      *&lt;br /&gt;     C                   endsr&lt;br /&gt;      *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-==-&lt;br /&gt;      * $SndMsg - Send a message to the message subfile&lt;br /&gt;      *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-==-&lt;br /&gt;     C     $SndMsg       begsr&lt;br /&gt;      *****&lt;br /&gt;     C*****              call      'QMHSNDPM'&lt;br /&gt;     C*****              parm                    MSGID&lt;br /&gt;     C*****              parm                    MSGF&lt;br /&gt;     C*****              parm                    MSGDTA&lt;br /&gt;     C*****              parm                    DTALEN&lt;br /&gt;     C*****              parm                    MSGTYP&lt;br /&gt;     C*****              parm                    PGMQ&lt;br /&gt;     C*****              parm                    STKCNT&lt;br /&gt;     C*****              parm                    MSGKEY&lt;br /&gt;     C*****              parm                    ERRCOD&lt;br /&gt;      *&lt;br /&gt;     C                   endsr&lt;br /&gt;      *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-==-&lt;br /&gt;      * $ClrMsg - clear the messages from the screen&lt;br /&gt;      *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-==-=-=-=-=-=-==-&lt;br /&gt;     C     $ClrMsg       begsr&lt;br /&gt;      *&lt;br /&gt;     C                   call      'QMHRMVPM'&lt;br /&gt;     C                   parm                    PGMQ&lt;br /&gt;     C                   parm                    STKCNT&lt;br /&gt;     C                   parm                    MSGKY&lt;br /&gt;     C                   parm                    MSGRMV&lt;br /&gt;     C                   parm                    ERRCOD&lt;br /&gt;      *&lt;br /&gt;     C                   endsr&lt;br /&gt;      *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-&lt;br /&gt;      * Initialization&lt;br /&gt;      *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-&lt;br /&gt;     C     *inzsr        begsr&lt;br /&gt;      *&lt;br /&gt;     C     *entry        plist&lt;br /&gt;     C                   parm                    pInputLib&lt;br /&gt;     C                   parm                    pInputName&lt;br /&gt;     C                   parm                    pIFSFileType&lt;br /&gt;     C                   parm                    pDataQLib&lt;br /&gt;     C                   parm                    pDataQName&lt;br /&gt;     C                   parm                    pFolders&lt;br /&gt;      *&lt;br /&gt;      * Initialize the message subfile fields&lt;br /&gt;      *&lt;br /&gt;     C                   movel     'MSGF   '     MSGF             20&lt;br /&gt;     C                   movel     '*LIBL'       MSGLIB           10&lt;br /&gt;     C                   move      'MSGLIB'      MSGF&lt;br /&gt;     C                   move      *blanks       MSGKY            04&lt;br /&gt;     C                   move      *blanks       MSGDTA           80&lt;br /&gt;     C                   movel     '*DIAG'       MSGTYP           10&lt;br /&gt;     C                   movel     '*ALL'        MSGRMV           10&lt;br /&gt;     C                   movel     *blanks       MSGID            07&lt;br /&gt;      *&lt;br /&gt;     C                   endsr&lt;br /&gt;      *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-===-=-=-=-=-=-=-=-=-&lt;br /&gt;      * $GetDOW - Get Day of Week&lt;br /&gt;      *            1=Sun, 2=Mon, etc.&lt;br /&gt;      *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-====-=-=-=-=-=-=-=-=-&lt;br /&gt;     P$GetDOW          b&lt;br /&gt;     D $GetDOW         pi             3a&lt;br /&gt;     D  InpDate                        d   value&lt;br /&gt;      *&lt;br /&gt;     D DayOfWk         s             11p 0&lt;br /&gt;     D AnySundayDate   s               d   datfmt(*iso)&lt;br /&gt;     D                                     inz(d'1998-08-01')&lt;br /&gt;     D WrkDate         s               d   datfmt(*iso)&lt;br /&gt;     D dowDesc         s              3    inz(*blanks)&lt;br /&gt;      *&lt;br /&gt;     C                   eval      WrkDate = InpDate&lt;br /&gt;     C                   eval      DayOfWk = %diff(InpDate:AnySundayDate:*days)&lt;br /&gt;     C                   div       7             DayOfWk&lt;br /&gt;     C                   mvr                     DayOfWk&lt;br /&gt;      *&lt;br /&gt;     C                   if        DayOfWk &lt;= 0&lt;br /&gt;     C                   eval      DayOfWk = (DayOfWk + 7)&lt;br /&gt;     C                   endif&lt;br /&gt;      *&lt;br /&gt;     C                   select&lt;br /&gt;     C                   when      DayOfWk = 1&lt;br /&gt;     C                   eval      dowDesc = 'Sun'&lt;br /&gt;     C                   when      DayOfWk = 2&lt;br /&gt;     C                   eval      dowDesc = 'Mon'&lt;br /&gt;     C                   when      DayOfWk = 3&lt;br /&gt;     C                   eval      dowDesc = 'Tue'&lt;br /&gt;     C                   when      DayOfWk = 4&lt;br /&gt;     C                   eval      dowDesc = 'Wed'&lt;br /&gt;     C                   when      DayOfWk = 5&lt;br /&gt;     C                   eval      dowDesc = 'Thu'&lt;br /&gt;     C                   when      DayOfWk = 6&lt;br /&gt;     C                   eval      dowDesc = 'Fri'&lt;br /&gt;     C                   when      DayOfWk = 7&lt;br /&gt;     C                   eval      dowDesc = 'Sat'&lt;br /&gt;     C                   endsl&lt;br /&gt;      *&lt;br /&gt;     C                   return    dowDesc&lt;br /&gt;      *&lt;br /&gt;     P$GetDOW          e&lt;br /&gt;      *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-===-=-=-=-=-=-=-=-=-&lt;br /&gt;      * $RtvMbrD - Retreive Member Description&lt;br /&gt;      *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--===-=-=-=-=-=-=-=-=-&lt;br /&gt;     P$RtvMbrD         b&lt;br /&gt;     D $RtvMbrD        pi             1a&lt;br /&gt;     D  InputFile                    20a   value&lt;br /&gt;      *&lt;br /&gt;      *&lt;br /&gt;      * API QUSRMBRD (Retreive Member Description)&lt;br /&gt;      * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~&lt;br /&gt;     D nBufLen         s             10i 0&lt;br /&gt;     D ErrorCode       s          32766A&lt;br /&gt;      *&lt;br /&gt;      * QUSRMBRD API return Struture&lt;br /&gt;      * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~&lt;br /&gt;     D Mbrd0100        ds                  inz&lt;br /&gt;     D  nBytesRtn                    10i 0&lt;br /&gt;     D  nBytesAval                   10i 0&lt;br /&gt;     D  FileName                     10a&lt;br /&gt;     D  LibName                      10a&lt;br /&gt;     D  MbrName                      10a&lt;br /&gt;     D  FileAttr                     10a&lt;br /&gt;     D  SrcType                      10a&lt;br /&gt;     D  dtCrtDate                    13a&lt;br /&gt;     D  dtLstChg                     13a&lt;br /&gt;     D  MbrText                      50a&lt;br /&gt;     D  bIsSource                     1a&lt;br /&gt;     D  RmtFile                       1a&lt;br /&gt;     D  LglPhyFile                    1a&lt;br /&gt;     D  ODPSharing                    1a&lt;br /&gt;     D  filler2                       2a&lt;br /&gt;     D  RecCount                     10i 0&lt;br /&gt;     D  DltRecCnt                    10i 0&lt;br /&gt;     D  DataSpaceSz                  10i 0&lt;br /&gt;     D  AccpthSz                     10i 0&lt;br /&gt;     D  NbrBasedOnMbr                10i 0&lt;br /&gt;      *&lt;br /&gt;      * Input Parameters for the QUSRMBRD API&lt;br /&gt;      * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~&lt;br /&gt;      * Format to be returned&lt;br /&gt;      *&lt;br /&gt;     D Fmt             s              8a   inz('MBRD0200')&lt;br /&gt;      *&lt;br /&gt;      * Source File Name&lt;br /&gt;      *&lt;br /&gt;     D MemberName      s             10a   inz('*FIRST')&lt;br /&gt;      *&lt;br /&gt;      * ignore overrides (0=Ignore, 1 = Apply)&lt;br /&gt;      *&lt;br /&gt;     D bOvr            s              1a   inz('0')&lt;br /&gt;      *&lt;br /&gt;     D MemberError     s              1a   inz('N')&lt;br /&gt;      *&lt;br /&gt;     C                   eval      nBufLen = %size(MbrD0100)&lt;br /&gt;      *&lt;br /&gt;     C                   call(e)   'QUSRMBRD'&lt;br /&gt;     C                   parm                    MbrD0100&lt;br /&gt;     C                   parm                    nBufLen&lt;br /&gt;     C                   parm                    Fmt&lt;br /&gt;     C                   parm                    InputFile&lt;br /&gt;     C                   parm                    MemberName&lt;br /&gt;     C                   parm                    bOvr&lt;br /&gt;     C                   parm                    ErrorCode&lt;br /&gt;      *&lt;br /&gt;     C                   if        %error or (FileAttr &lt;&gt; 'PF' and&lt;br /&gt;     C                             FileAttr &lt;&gt; 'LF')&lt;br /&gt;     C                   eval      MemberError = 'Y'&lt;br /&gt;     C                   endif&lt;br /&gt;      *&lt;br /&gt;     C                   return    MemberError&lt;br /&gt;      *&lt;br /&gt;     P$RtvMbrD         e&lt;br /&gt;      *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-===-=-=-=-=-=-=-=-=-&lt;br /&gt;      * $GetJobType - Get Job Type (I=Interactive, B=Batch)&lt;br /&gt;      *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-===-=-=-=-=-=-=-=-=-&lt;br /&gt;     P$GetJobType      b&lt;br /&gt;     D $GetJobType     pi             1a&lt;br /&gt;      *&lt;br /&gt;     D   RcvVar        s          32766A&lt;br /&gt;     D   RcvVarLen     s             10i 0&lt;br /&gt;     D   Format        s              8A&lt;br /&gt;     D   QualJob       s             26A&lt;br /&gt;     D   InternJob     s             16A&lt;br /&gt;     D   ErrorCode     s          32766A&lt;br /&gt;      *&lt;br /&gt;     D dsJob           ds&lt;br /&gt;     D  dsJobBytesRtn                10I 0&lt;br /&gt;     D  dsJobBytesAvl                10I 0&lt;br /&gt;     D  dsJobName                    10A&lt;br /&gt;     D  dsJobUser                    10A&lt;br /&gt;     D  dsJobNumber                   6A&lt;br /&gt;     D  dsJobIntern                  16A&lt;br /&gt;     D  dsJobStatus                  10A&lt;br /&gt;     D  dsJobType                     1A&lt;br /&gt;     D  dsJobSubtype                  1A&lt;br /&gt;     D  dsJobReserv1                  2A&lt;br /&gt;     D  dsJobRunPty                  10I 0&lt;br /&gt;     D  dsJobTimeSlc                 10I 0&lt;br /&gt;     D  dsJobDftWait                 10I 0&lt;br /&gt;     D  dsJobPurge                   10A&lt;br /&gt;      *&lt;br /&gt;     C                   eval      RcvVarLen = %Size(DsJob)&lt;br /&gt;      *&lt;br /&gt;     C                   call      'QUSRJOBI'&lt;br /&gt;     C                   parm                    DsJob&lt;br /&gt;     C                   parm                    RcvVarLen&lt;br /&gt;     C                   parm      'JOBI0100'    Format&lt;br /&gt;     C                   parm      '*'           QualJob&lt;br /&gt;     C                   parm      *blanks       InternJob&lt;br /&gt;      *&lt;br /&gt;     C                   return    dsJobType&lt;br /&gt;      *&lt;br /&gt;     P$GetJobType      e&lt;br /&gt;      *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-&lt;br /&gt;      * Receive Data Queue&lt;br /&gt;      *-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=&lt;br /&gt;     P$ReceiveDataQ    b&lt;br /&gt;     D $ReceiveDataQ   pi          1024a&lt;br /&gt;     D  DataQ                        20a   value&lt;br /&gt;      *&lt;br /&gt;      * DataQName      = Name of Data Queue&lt;br /&gt;      * DataQLength    = Length of Data Queue&lt;br /&gt;      * DataQWait      = Time to wait for entry (-1 = forever)&lt;br /&gt;      * DataQData      = Area to Store Retrived Data&lt;br /&gt;      *&lt;br /&gt;     D DataQLib        s             10    inz(*blanks)&lt;br /&gt;     D DataQName       s             10    inz(*blanks)&lt;br /&gt;     D DataQLength     s              5  0 inz(1024)&lt;br /&gt;     D DataQWait       s              5  0 inz(0)&lt;br /&gt;     D DataQData       s           1024    inz(*blanks)&lt;br /&gt;     D ReturnCode      s              1&lt;br /&gt;      *&lt;br /&gt;     C                   eval      DataQLib = %subst(DataQ : 1 : 10)&lt;br /&gt;     C                   eval      DataQName = %subst(DataQ : 11 : 10)&lt;br /&gt;      *&lt;br /&gt;     C                   call      'QRCVDTAQ'                           99&lt;br /&gt;     C                   parm                    DataQName&lt;br /&gt;     C                   parm                    DataQlib&lt;br /&gt;     C                   parm                    DataQLength&lt;br /&gt;     C                   parm                    DataQData&lt;br /&gt;     C                   parm                    DataQWait&lt;br /&gt;      *&lt;br /&gt;     C                   if        not %error&lt;br /&gt;     C                   return                  DataQData&lt;br /&gt;     C                   endif&lt;br /&gt;      *&lt;br /&gt;     P$ReceiveDataQ    e&lt;br /&gt;      *-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=&lt;br /&gt;&lt;br /&gt;Display File&lt;br /&gt;&lt;br /&gt;     A*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-&lt;br /&gt;     A* Select Physical File Fields&lt;br /&gt;     A* ~~~~~~~~~~~~~~~~~~~~~~~~~~~&lt;br /&gt;     A*   SUB01     - Subfile&lt;br /&gt;     A*   SUB01CTL  - Subfile Control&lt;br /&gt;     A*   FORMAT1   - Window Format fo SUB01&lt;br /&gt;     A*&lt;br /&gt;     A*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-&lt;br /&gt;     A*%%EC&lt;br /&gt;     A                                      DSPSIZ(24 80 *DS3)&lt;br /&gt;     A                                      PRINT&lt;br /&gt;     A                                      ERRSFL&lt;br /&gt;     A                                      CF03(03 'Exit')&lt;br /&gt;     A                                      CF12(12 'Return')&lt;br /&gt;     A*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-&lt;br /&gt;     A* SUB01 - Subfile&lt;br /&gt;     A*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-&lt;br /&gt;     A          R SUB01                     SFL&lt;br /&gt;     A*%%TS&lt;br /&gt;     A            S1FLD         10A  O  8  7&lt;br /&gt;     A            S1DESC        30A  O  8 18&lt;br /&gt;     A            S1OPTN         1A  B  8  4&lt;br /&gt;     A            H1TYPE         1   H&lt;br /&gt;     A            H1LEN          5  0H&lt;br /&gt;     A            H1DEC          2  0H&lt;br /&gt;     A*&lt;br /&gt;     A          R SUB01CTL                  SFLCTL(SUB01)&lt;br /&gt;     A*%%TS  SD  20030926  112141  REYNOOM     REL-V5R1M0  5722-WDS&lt;br /&gt;     A                                      RTNCSRLOC(&amp;amp;#REC &amp;amp;#FLD)&lt;br /&gt;     A                                      OVERLAY&lt;br /&gt;     A                                      SFLCSRRRN(&amp;amp;WHERE)&lt;br /&gt;     A  50                                  SFLDSP&lt;br /&gt;     A  51                                  SFLDSPCTL&lt;br /&gt;     A  52                                  SFLCLR&lt;br /&gt;     A  89                                  SFLEND(*MORE)&lt;br /&gt;     A                                      SFLSIZ(0011)&lt;br /&gt;     A                                      SFLPAG(0010)&lt;br /&gt;     A                                      WINDOW(FMT1)&lt;br /&gt;     A            SCRRN          4S 0H      SFLRCDNBR&lt;br /&gt;     A            #REC          10A  H&lt;br /&gt;     A            #FLD          10A  H&lt;br /&gt;     A            WHERE          5S 0H&lt;br /&gt;     A                                  1 18'Fields Selection'&lt;br /&gt;     A                                      DSPATR(HI)&lt;br /&gt;     A                                  7  3'Opt'&lt;br /&gt;     A                                      DSPATR(HI)&lt;br /&gt;     A                                      DSPATR(UL)&lt;br /&gt;     A                                  7  7'Field     '&lt;br /&gt;     A                                      DSPATR(HI)&lt;br /&gt;     A                                      DSPATR(UL)&lt;br /&gt;     A                                  7 18'Description                   '&lt;br /&gt;     A                                      DSPATR(HI)&lt;br /&gt;     A                                      DSPATR(UL)&lt;br /&gt;     A            C1FILE        21A  O  5  9COLOR(WHT)&lt;br /&gt;     A                                  3  2'Type options, press Enter.'&lt;br /&gt;     A                                      COLOR(BLU)&lt;br /&gt;     A                                  5  3'File'&lt;br /&gt;     A*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-&lt;br /&gt;     A* FMT1&lt;br /&gt;     A*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-&lt;br /&gt;     A          R FMT1&lt;br /&gt;     A*%%TS  SD  20030926  112141  REYNOOM     REL-V5R1M0  5722-WDS&lt;br /&gt;     A                                      OVERLAY&lt;br /&gt;     A                                      WINDOW(*DFT 20 49)&lt;br /&gt;     A                                      WDWBORDER((*COLOR BLU))&lt;br /&gt;     A                                 19  2'F3=Exit'&lt;br /&gt;     A                                      COLOR(BLU)&lt;br /&gt;     A                                 19 11'F12=Return'&lt;br /&gt;     A                                      COLOR(BLU)&lt;br /&gt;      *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=&lt;br /&gt;      * DUMMY: Dummy Record&lt;br /&gt;      *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=&lt;br /&gt;     A          R DUMMY&lt;br /&gt;     A*%%TS&lt;br /&gt;     A                                      ASSUME&lt;br /&gt;     A                                  1  3' '&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Select Fields from Physical file – RPG Program&lt;br /&gt;&lt;br /&gt;      *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-&lt;br /&gt;     H dftactgrp(*no) option(*srcstmt : *nodebugio)&lt;br /&gt;      *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-&lt;br /&gt;      * Program Name: SLTPFFDR&lt;br /&gt;      * Description : Select Fields from Specific Physical File.&lt;br /&gt;      * Written By  :&lt;br /&gt;      * Written On  :&lt;br /&gt;      *&lt;br /&gt;     &lt;br /&gt;      * Display File&lt;br /&gt;      * ~~~~~~~~~~~~&lt;br /&gt;     FSPTPFFDD  CF   E             WORKSTN&lt;br /&gt;     F                                     SFILE(SUB01 : RRn)&lt;br /&gt;      *&lt;br /&gt;      *-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-&lt;br /&gt;      *&lt;br /&gt;      * Field Definitions&lt;br /&gt;      * ~~~~~~~~~~~~~~~~~&lt;br /&gt;     D AR              S              1    DIM(9999)&lt;br /&gt;     D AKEY            S             10    DIM(9999)&lt;br /&gt;     D AK#             S              2  0 DIM(9999)&lt;br /&gt;     D J               S              2  0&lt;br /&gt;     D JJ              S              2  0&lt;br /&gt;     D I               S              7  0&lt;br /&gt;     D S               S              7  0&lt;br /&gt;     D RelRecNbr       S              4  0&lt;br /&gt;     D XX              S              7  0&lt;br /&gt;     D I1              S              1&lt;br /&gt;     D I2              S              2&lt;br /&gt;     D pDataQLib       s             10&lt;br /&gt;     D pDataQName      s             10&lt;br /&gt;     D pFileLib        S             20&lt;br /&gt;     D FileLib         s             20    inz(*blanks)&lt;br /&gt;     D pInputLib       s             10&lt;br /&gt;     D pInputName      s             10&lt;br /&gt;     D InputLib        s             10    inz(*blanks)&lt;br /&gt;     D InputName       s             10    inz(*blanks)&lt;br /&gt;     D InFormat        S             10&lt;br /&gt;     D EntryFmt        S             10    inz('*FIRST')&lt;br /&gt;     D SFLRcdCnt       S             04  0&lt;br /&gt;     D RRn             S             04  0&lt;br /&gt;     D SavRRn          S             04  0&lt;br /&gt;     D NbrofField      S             04  0&lt;br /&gt;     D OutField        S             10&lt;br /&gt;     D OutSize         S             15  5&lt;br /&gt;     D OutDecimal      S             01&lt;br /&gt;     D OutType2        S             01&lt;br /&gt;     D @Scrn1          S             01&lt;br /&gt;      *&lt;br /&gt;     D GENDS           DS&lt;br /&gt;     D  OffsetHdr            117    120B 0&lt;br /&gt;     D  SizeHeader           121    124B 0&lt;br /&gt;     D  OffsetList           125    128B 0&lt;br /&gt;     D  NbrInList            133    136B 0&lt;br /&gt;     D  SizeEntry            137    140B 0&lt;br /&gt;     D HeaderDs        DS&lt;br /&gt;     D  OutFileNam             1     10&lt;br /&gt;     D  OutLibName            11     20&lt;br /&gt;     D  OutType               21     25&lt;br /&gt;     D  OutFormat             31     40&lt;br /&gt;     D  RecordLen             41     44B 0&lt;br /&gt;     D InputDs         DS&lt;br /&gt;     D  UserSpace              1     20&lt;br /&gt;     D  SpaceName              1     10&lt;br /&gt;     D  SpaceLib              11     20&lt;br /&gt;     D  InpFileLib            29     48&lt;br /&gt;     D  InpFFilNam            29     38&lt;br /&gt;     D  InpFFilLib            39     48&lt;br /&gt;     D  InpRcdFmt             49     58&lt;br /&gt;     D ListDs          DS&lt;br /&gt;     D  FieldName              1     10&lt;br /&gt;     D  FieldType             11     11&lt;br /&gt;     D  BufferOut             13     16B 0&lt;br /&gt;     D  FieldLen              21     24B 0&lt;br /&gt;     D  Digits                25     28B 0&lt;br /&gt;     D  Decimals              29     32B 0&lt;br /&gt;     D  FieldDesc             33     82&lt;br /&gt;     D ErrorDs         DS                  INZ&lt;br /&gt;     D  BytesPrv               1      4B 0&lt;br /&gt;     D  BytesAvl               5      8B 0&lt;br /&gt;     D  MessageId              9     15&lt;br /&gt;     D  ERR###                16     16&lt;br /&gt;     D  MessageDta            17    116&lt;br /&gt;     D ReceiveVr2      S            100&lt;br /&gt;     D ReceiveVar      DS          4096&lt;br /&gt;     D  NbrOfFmts             62     63B 0&lt;br /&gt;     D  DBFileOff            317    320B 0&lt;br /&gt;     D FindSelDs       DS           150&lt;br /&gt;     D  NbrOfKeys            117    118B 0&lt;br /&gt;     D  KeyOffset            136    139B 0&lt;br /&gt;     D KeyDataDs       DS&lt;br /&gt;     D  DependKey              1     10&lt;br /&gt;     D                 DS&lt;br /&gt;     D  StartPosit             1      4B 0&lt;br /&gt;     D  StartLen               5      8B 0&lt;br /&gt;     D  SpaceLen               9     12B 0&lt;br /&gt;     D  ReceiveLen            13     16B 0&lt;br /&gt;     D  MessageKey            17     20B 0&lt;br /&gt;     D  MsgDtaLen             21     24B 0&lt;br /&gt;     D  MsgQueNbr             25     28B 0&lt;br /&gt;     DGenSpcPtr                        *&lt;br /&gt;     DLstSpcPtr                        *&lt;br /&gt;     DHdrPtr                           *&lt;br /&gt;      *&lt;br /&gt;      * API&lt;br /&gt;      * ~~~&lt;br /&gt;      * Send Data Queue API&lt;br /&gt;      * ~~~~~~~~~~~~~~~~~~~&lt;br /&gt;      * DataQName    = Name of Data Queue&lt;br /&gt;      * DataQLength  = Length of Data Queue&lt;br /&gt;      * DataQData    = Data to be placed onto DataQ&lt;br /&gt;      *&lt;br /&gt;     D  DataQName      s             10    inz('SAVFLDDTAQ')&lt;br /&gt;     D  DataQLib       s             10    inz('CODE400')&lt;br /&gt;     D  DataQLength    s              5  0 inz(512)&lt;br /&gt;     D  DataQData      s           1024    inz(*blanks)&lt;br /&gt;      *&lt;br /&gt;     D ReturnCode      s              1&lt;br /&gt;      *&lt;br /&gt;      * Fields Definition&lt;br /&gt;      * ~~~~~~~~~~~~~~~~~&lt;br /&gt;     D CmdString       s            500    inz(*blanks)&lt;br /&gt;     D CmdLength       s             15  5 inz(0)&lt;br /&gt;      *&lt;br /&gt;     D LengthField     s              5  0 inz(0)&lt;br /&gt;     D DecimalField    s              2  0 inz(0)&lt;br /&gt;      *&lt;br /&gt;      *-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=&lt;br /&gt;      *    M A I N    L I N E&lt;br /&gt;      *-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=&lt;br /&gt;      *&lt;br /&gt;     C                   eval      SpaceName  = 'FFDSPC'&lt;br /&gt;     C                   eval      SpaceLib   = 'QTEMP'&lt;br /&gt;     C                   eval      InpFFilNam = InputName&lt;br /&gt;     C                   eval      InpFFilLib = InputLib&lt;br /&gt;     C                   eval      C1FILE = %trim(InpFFilLib) + '/' +&lt;br /&gt;     C                             %trim(InpFFilNam)&lt;br /&gt;      *&lt;br /&gt;      * Create the user space&lt;br /&gt;      *&lt;br /&gt;     C                   call      'QUSCRTUS'&lt;br /&gt;     C                   parm                    UserSpace&lt;br /&gt;     C                   parm      *BLANKS       SpaceAttr        10&lt;br /&gt;     C                   parm      4096          SpaceLen&lt;br /&gt;     C                   parm      *BLANKS       Spaceval          1&lt;br /&gt;     C                   parm      '*CHANGE'     SpaceAuth        10&lt;br /&gt;     C                   parm      *BLANKS       SpaceText        50&lt;br /&gt;     C                   parm      '*YES'        SpaceRepl        10&lt;br /&gt;     C                   parm                    ErrorDs&lt;br /&gt;      *&lt;br /&gt;      * Attemp to retrieve object description&lt;br /&gt;      *&lt;br /&gt;     C                   call      'QUSROBJD'                           99&lt;br /&gt;     C                   parm                    ReceiveVr2&lt;br /&gt;     C                   parm      100           ReceiveLen&lt;br /&gt;     C                   parm      'OBJD0100'    FileFormat        8&lt;br /&gt;     C                   parm                    FileLib&lt;br /&gt;     C                   parm      '*FILE'       ObjectType       10&lt;br /&gt;     C                   parm                    ErrorDs&lt;br /&gt;      *&lt;br /&gt;     C                   if        *in99 = *off&lt;br /&gt;      *&lt;br /&gt;      *  List fields to user space&lt;br /&gt;      *&lt;br /&gt;     C                   call      'QUSLFLD'&lt;br /&gt;     C                   parm                    UserSpace&lt;br /&gt;     C                   parm      'FLDL0100'    ListFormat        8&lt;br /&gt;     C                   parm                    InpFileLib&lt;br /&gt;     C                   parm      EntryFmt      InpRcdFmt&lt;br /&gt;     C                   parm      '1'           OverRide          1&lt;br /&gt;     C                   eval      StartPosit = 1&lt;br /&gt;     C                   eval      StartLen = 140&lt;br /&gt;      *&lt;br /&gt;     C                   call      'QUSRTVUS'&lt;br /&gt;     C                   parm                    UserSpace&lt;br /&gt;     C                   parm                    StartPosit&lt;br /&gt;     C                   parm                    StartLen&lt;br /&gt;     C                   parm                    GENDS&lt;br /&gt;     C                   eval      StartPosit = OffsetHdr + 1&lt;br /&gt;     C                   eval      StartLen = SizeHeader&lt;br /&gt;      *&lt;br /&gt;     C                   call      'QUSRTVUS'&lt;br /&gt;     C                   parm                    UserSpace&lt;br /&gt;     C                   parm                    StartPosit&lt;br /&gt;     C                   parm                    StartLen&lt;br /&gt;     C                   parm                    HeaderDs&lt;br /&gt;      *&lt;br /&gt;     C                   eval      StartPosit = OffsetList + 1&lt;br /&gt;     C                   eval      StartLen = SizeEntry&lt;br /&gt;     C                   eval      SpaceName  = 'FFDSPC'&lt;br /&gt;     C                   eval      SpaceLib   = 'QTEMP'&lt;br /&gt;      *&lt;br /&gt;      * Load Subfile&lt;br /&gt;      *&lt;br /&gt;     C                   do        NbrInList     NbrOfField&lt;br /&gt;     C                   call      'QUSRTVUS'&lt;br /&gt;     C                   parm                    UserSpace&lt;br /&gt;     C                   parm                    StartPosit&lt;br /&gt;     C                   parm                    StartLen&lt;br /&gt;     C                   parm                    ListDs&lt;br /&gt;     C                   exsr      $LoadSFL&lt;br /&gt;     C                   eval      StartPosit = StartPosit + SizeEntry&lt;br /&gt;     C                   enddo&lt;br /&gt;      *&lt;br /&gt;      * Display Subfile&lt;br /&gt;      *&lt;br /&gt;     C                   exsr      $DispSFL&lt;br /&gt;      *&lt;br /&gt;     C                   endif&lt;br /&gt;      *&lt;br /&gt;     C                   eval      *inlr = *on&lt;br /&gt;     C                   return&lt;br /&gt;      *-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=&lt;br /&gt;      *  $DispSFL - Display Fields to screen&lt;br /&gt;      *-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=&lt;br /&gt;     C     $DispSFL      begsr&lt;br /&gt;      *&lt;br /&gt;     C                   eval      @Scrn1 = 'Y'&lt;br /&gt;     C                   dow       @Scrn1 = 'Y'&lt;br /&gt;      *&lt;br /&gt;     C                   exfmt     SUB01CTL&lt;br /&gt;      *&lt;br /&gt;     C                   select&lt;br /&gt;      *&lt;br /&gt;     C                   when      *in03 Or *in12&lt;br /&gt;     C                   eval      @Scrn1  = 'N'&lt;br /&gt;      *&lt;br /&gt;     C                   other&lt;br /&gt;      *&lt;br /&gt;     C                   do        SavRRn        SFLRcdCnt&lt;br /&gt;     C     SFLRcdCnt     chain     SUB01&lt;br /&gt;     C                   if        %found and S1OPTN &lt;&gt; *blanks&lt;br /&gt;     C                   eval      %subst(DataQData : 1) =  S1FLD&lt;br /&gt;     C                   eval      %subst(DataQData : 11) =&lt;br /&gt;     C                             %editw(H1LEN : '     ')&lt;br /&gt;     C                   eval      %subst(DataQData : 16) = H1TYPE&lt;br /&gt;     C                   if        H1TYPE &lt;&gt; 'A'&lt;br /&gt;     C                   eval      %subst(DataQData : 17) = %editw(H1DEC : '0 ')&lt;br /&gt;     C                   endif&lt;br /&gt;     C                   eval      %subst(DataQData : 19) = S1DESC&lt;br /&gt;     C                   exsr      $SendDataQ&lt;br /&gt;     C                   eval      S1OPTN = *blanks&lt;br /&gt;     C                   update    SUB01&lt;br /&gt;     C                   eval      @Scrn1  = 'N'&lt;br /&gt;     C                   endif&lt;br /&gt;     C                   enddo&lt;br /&gt;      *&lt;br /&gt;     C                   endsl&lt;br /&gt;      *&lt;br /&gt;     C                   enddo&lt;br /&gt;      *&lt;br /&gt;     C                   endsr&lt;br /&gt;      *-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=-=-=-=&lt;br /&gt;      *  $LoadSFL - write Fields to screen&lt;br /&gt;      *-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=&lt;br /&gt;     C     $LoadSFL      begsr&lt;br /&gt;      *&lt;br /&gt;     C                   eval      S1FLD = FieldName&lt;br /&gt;     C                   eval      S1DESC = FieldDesc&lt;br /&gt;     C                   eval      H1TYPE = FieldType&lt;br /&gt;     C                   if        FieldType = 'A'&lt;br /&gt;     C                   eval      H1LEN  = FieldLen&lt;br /&gt;     C                   else&lt;br /&gt;     C                   eval      H1LEN  = Digits&lt;br /&gt;     C                   endif&lt;br /&gt;     C                   eval      H1DEC  = Decimals&lt;br /&gt;      *&lt;br /&gt;     C                   eval      RRn = (RRn + 1)&lt;br /&gt;     C                   eval      SavRRn = RRn&lt;br /&gt;     C                   write     SUB01&lt;br /&gt;      *&lt;br /&gt;     C                   if        NbrOfField = NbrInList&lt;br /&gt;     C                   eval      *in89 = *on&lt;br /&gt;     C                   endif&lt;br /&gt;      *&lt;br /&gt;     C                   endsr&lt;br /&gt;      *&lt;br /&gt;      *-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=-=-=&lt;br /&gt;      * $ClearSFL - clear the Subfile&lt;br /&gt;      *-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=&lt;br /&gt;     C     $ClearSFL     begsr&lt;br /&gt;      *&lt;br /&gt;     C                   eval      *in50 = *off&lt;br /&gt;     C                   eval      *in51 = *off&lt;br /&gt;     C                   eval      *in52 = *on&lt;br /&gt;     C                   write     FMT1&lt;br /&gt;     C                   write     SUB01CTL&lt;br /&gt;     C                   eval      *in50 = *on&lt;br /&gt;     C                   eval      *in51 = *on&lt;br /&gt;     C                   eval      *in52 = *off&lt;br /&gt;      *&lt;br /&gt;     C                   eval      SavRRn = 0&lt;br /&gt;     C                   eval      SCRRn = 1&lt;br /&gt;     C                   eval      RRn = 0&lt;br /&gt;      *&lt;br /&gt;     C                   endsr&lt;br /&gt;      *-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=&lt;br /&gt;      * Send Data Queue&lt;br /&gt;      *-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=&lt;br /&gt;     C     $SendDataQ    begsr&lt;br /&gt;      *&lt;br /&gt;     C                   eval      DataQLength = 1024&lt;br /&gt;      *&lt;br /&gt;     C                   call      'QSNDDTAQ'&lt;br /&gt;     C                   parm                    DataQName&lt;br /&gt;     C                   parm                    DataQLib&lt;br /&gt;     C                   parm                    DataQLength&lt;br /&gt;     C                   parm                    DataQData&lt;br /&gt;      *&lt;br /&gt;     C                   endsr&lt;br /&gt;      *-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=&lt;br /&gt;      * Create Data Queue&lt;br /&gt;      *-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=&lt;br /&gt;     C     $CreateDataQ  begsr&lt;br /&gt;      *&lt;br /&gt;     C                   eval      CmdString = %trim('CRTDTAQ') +&lt;br /&gt;     C                             %trim('~DTAQ(') + %trim(DataQLib) +&lt;br /&gt;     C                             %trim('/') + %trim(DataQName) +&lt;br /&gt;     C                             %trim(')') +&lt;br /&gt;     C                             %trim('~TYPE(*STD)') +&lt;br /&gt;     C                             %trim('~MAXLEN(1024)') +&lt;br /&gt;     C                             %trim('~SIZE(*MAX16MB)')&lt;br /&gt;     C                   eval      CmdString = %xlate('~' : ' ' : CmdString)&lt;br /&gt;     C                   eval      CmdLength = %size(CmdString)&lt;br /&gt;     C                   call      'QCMDEXC'                            99&lt;br /&gt;     C                   parm                    CmdString&lt;br /&gt;     C                   parm                    CmdLength&lt;br /&gt;      *&lt;br /&gt;     C                   endsr&lt;br /&gt;      *-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=&lt;br /&gt;      * Check Data Queue&lt;br /&gt;      *-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=&lt;br /&gt;     C     $CheckDataQ   begsr&lt;br /&gt;      * CHKOBJ OBJ(QTEMP/&amp;amp;DTAQ) OBJTYPE(*DTAQ)&lt;br /&gt;     C                   eval      CmdString = %trim('CHKOBJ') +&lt;br /&gt;     C                             %trim('~OBJ(') + %trim(DataQLib) +&lt;br /&gt;     C                             %trim('/') + %trim(DataQName) +&lt;br /&gt;     C                             %trim(')') +&lt;br /&gt;     C                             %trim('~OBJTYPE(*DTAQ)')&lt;br /&gt;     C                   eval      CmdString = %xlate('~' : ' ' : CmdString)&lt;br /&gt;     C                   eval      CmdLength = %size(CmdString)&lt;br /&gt;     C                   call      'QCMDEXC'                            99&lt;br /&gt;     C                   parm                    CmdString&lt;br /&gt;     C                   parm                    CmdLength&lt;br /&gt;      *&lt;br /&gt;     C                   if        *in99&lt;br /&gt;     C                   exsr      $CreateDataQ&lt;br /&gt;     C                   endif&lt;br /&gt;     C                   exsr      $ClearDataQ&lt;br /&gt;      *&lt;br /&gt;     C                   endsr&lt;br /&gt;      *-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=-=&lt;br /&gt;      * Clear Data Queue&lt;br /&gt;      *-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=&lt;br /&gt;     C     $ClearDataQ   begsr&lt;br /&gt;      *&lt;br /&gt;     C*****&gt;             call      'QCLRDTAQ'&lt;br /&gt;     C*****&gt; NO NEED!    parm                    DataQName&lt;br /&gt;     C*****&gt;             parm                    DataQLib&lt;br /&gt;      *&lt;br /&gt;     C                   endsr&lt;br /&gt;      *-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=-=-=&lt;br /&gt;      * *inzsr - Initial one time run subroutine&lt;br /&gt;      *-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=-=-=-=-=-=-=-=&lt;br /&gt;     C     *inzsr        begsr&lt;br /&gt;      *&lt;br /&gt;     C     *entry        plist&lt;br /&gt;     C                   parm                    pInputLib&lt;br /&gt;     C                   parm                    pInputName&lt;br /&gt;     C                   parm                    pDataQLib&lt;br /&gt;     C                   parm                    pDataQName&lt;br /&gt;      *&lt;br /&gt;     C                   eval      InputLib = pInputLib&lt;br /&gt;     C                   eval      InputName = pInputName&lt;br /&gt;     C                   eval      FileLib = pInputName + pInputLib&lt;br /&gt;     C                   eval      DataQLib = pDataQLib&lt;br /&gt;     C                   eval      DataQName = pDataQName&lt;br /&gt;     C                   exsr      $CheckDataQ&lt;br /&gt;     C                   exsr      $ClearSFL&lt;br /&gt;      *&lt;br /&gt;     C                   endsr&lt;br /&gt;      *-=-=-=--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8909486560224298250-8283788999122982790?l=prabhatmohapatra.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://prabhatmohapatra.blogspot.com/feeds/8283788999122982790/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://prabhatmohapatra.blogspot.com/2009/04/convert-pf-to-csv-file.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8909486560224298250/posts/default/8283788999122982790'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8909486560224298250/posts/default/8283788999122982790'/><link rel='alternate' type='text/html' href='http://prabhatmohapatra.blogspot.com/2009/04/convert-pf-to-csv-file.html' title='Convert PF to CSV file'/><author><name>Prabhat</name><uri>http://www.blogger.com/profile/14496453689733819797</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8909486560224298250.post-4114018212593726161</id><published>2009-04-16T02:44:00.000-07:00</published><updated>2009-04-16T02:45:52.321-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='XML in RPG'/><title type='text'>RPG &amp; XML - RPGs XML Support</title><content type='html'>Got an XML file and want to read and process it in AS400 through RPG&lt;br /&gt;&lt;br /&gt;The simple thing is to create a data structure in your RPG program that maps to the XML schema. Then use the XML-INTO operation code to load the XML file into the data structure.&lt;br /&gt;&lt;br /&gt;Mapping XML Attributes to RPG Data Structures&lt;br /&gt;&lt;br /&gt;A brief review of the basics is in order. The following is a basic example; it demonstrated the parsing of a simple document similar to this:&lt;br /&gt;&lt;br /&gt;&lt;customers&gt;&lt;br /&gt;     &lt;company&gt;Phones R Us&lt;/company&gt;&lt;br /&gt;     &lt;company&gt;Company 2&lt;/company&gt;&lt;br /&gt;     &lt;company&gt;Last One&lt;/company&gt;&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;Both the data definition and processing is quite straight forward and can essentially be handled by the following RPG code:&lt;br /&gt;&lt;br /&gt;d customers     DS&lt;br /&gt;d   company         32a Dim(999)&lt;br /&gt;&lt;br /&gt;/Free&lt;br /&gt;    XML-INTO company %XML( XML_Input : 'case=any');&lt;br /&gt;&lt;br /&gt;When we are able to use the above approach, we can even take advantage of the fact that the XML parser will supply a count of the number of company elements found and place it in xmlElements, an 8-byte integer (20i) at offset 372 in the program status data structure (PSDS).&lt;br /&gt;&lt;br /&gt;&lt;customers&gt;&lt;br /&gt;     &lt;otherinfo location="25"&gt;&lt;br /&gt;     &lt;company&gt;Phones R Us&lt;/company&gt;&lt;br /&gt;     &lt;company&gt;Company 2&lt;/company&gt;&lt;br /&gt;     &lt;company&gt;Last One&lt;/company&gt;&lt;br /&gt;    …&lt;br /&gt;&lt;br /&gt;The concern is how to handle the Location attribute of the Other Info element. The simple answer is that an attribute of an element is considered to be at the same hierarchical level as a child of that element.&lt;br /&gt;&lt;br /&gt;&lt;otherinfo location="25"&gt;&lt;br /&gt;&lt;br /&gt;And this:&lt;br /&gt;&lt;br /&gt;&lt;otherinfo&gt;&lt;br /&gt;   &lt;location&gt;25&lt;/location&gt;&lt;br /&gt;&lt;/otherinfo&gt;&lt;br /&gt;&lt;br /&gt;are effectively the same thing and therefore we code for the first version the same way as if the XML looked like the second version. Look at the code sample below and you’ll see what we mean. otherInfo is coded as a nested data structure using the LikeDS keyword, and the location attribute is coded as a subfield of that DS.&lt;br /&gt;&lt;br /&gt;d customers      DS                 qualified&lt;br /&gt;d   otherInfo              LikeDS(otherInfo)&lt;br /&gt;d   company             32a Dim(999)&lt;br /&gt;&lt;br /&gt;d otherInfo     DS&lt;br /&gt;d location             2a&lt;br /&gt;&lt;br /&gt;  /Free&lt;br /&gt;    XML-INTO customers %XML( XML_Input : 'case=any');&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Handling Nested Arrays and Other XML Issues&lt;br /&gt;However, introducing another level into the DS causes a lot of problems. For one, the XML-INTO as shown above may not work. Also, because the array definition isn’t at the top level of the INTO target, the parser can’t populate the xmlElements value in the PSDS, so we won’t have an easy way to determine how many elements were retrieved. The reason is that there could be multiple groups of repeating elements in the XML document and therefore multiple arrays in the DS. The parser wouldn’t know which count we wanted it to place in the PDS.&lt;br /&gt;&lt;br /&gt;The program as coded will only run to successful completion if there are exactly 999 customer elements present in the XML. If there are fewer than 999 elements, the program will fail with the error message RNQ0353 “XML document does not match RPG variable.” Since this message is issued under many circumstances, you’d need to drill down to the earlier messages in the job log to discover the real cause. In this case, it’ll be message RNX0353 “The XML document does not match the RPG variable; reason code 2.” The reason code identifies the problem as being too few elements to fill the array.&lt;br /&gt;&lt;br /&gt;To handle this we would need to add the option "allowmissing=yes" to our %XML BIF--so our XML-INTO would look like this:&lt;br /&gt;&lt;br /&gt;XML-INTO customers %XML( XML_Input : 'case=any allowmissing=yes');&lt;br /&gt;&lt;br /&gt;This lets the program run, but how do we know how many customer elements we actually have? The easiest way to handle this is to initialize the entire data structure to a known value. Our personal preference is *HiVal since this value should never appear in the XML document. See Code Sample 1 for a demonstration. This processes the XML document shown in Code Sample 2. We initialize the DS at (A). Then in the FOR loop that processes the extracted data, we test for *HIVal in the customer ID entry (B) and exit the loop if it’s encountered (C).&lt;br /&gt;&lt;br /&gt;allowmissing=yes = Danger!&lt;br /&gt;The danger with specifying this option is it offers no way to specify what’s allowed to be missing. Once you’ve said that it’s OK for elements to be omitted you’ve opened the door for any element to be omitted from the document--and you’d have no warning if this were to occur. To deal with this, we can use the same approach that we used earlier to test for the end of the list. To demonstrate, we’ve included a test to determine if the contact information was present (D), and to handle the situation appropriately in the event that it wasn’t supplied.&lt;br /&gt;&lt;br /&gt;How to deal with the handling of numeric data within an XML document. While XML-INTO supports the direct parsing of elements into numeric fields, it’s not a recommended practice unless you originated the XML document and can be certain that only valid numeric data is contained within the element. The reason for this is that if the XML parser encounters an invalid numeric value during the conversion, it’ll abort the XML-INTO process. A simple error in a (supposedly) numeric field can cause the whole operation to fail. IBM’s recommendation is that rather than define your fields as numeric in the target DS, you should define them as character and then manually convert them to numeric as part of your validation process. Depending on the type of data, you can then use %Dec or %Int wrapped up in a MONITOR group so any errors can be detected and handled. You can see an example of this at (E) in the program. Another advantage of having XML-INTO handle such fields as character data is that we can incorporate the value in any error messages.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8909486560224298250-4114018212593726161?l=prabhatmohapatra.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://prabhatmohapatra.blogspot.com/feeds/4114018212593726161/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://prabhatmohapatra.blogspot.com/2009/04/rpg-xml-rpgs-xml-support.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8909486560224298250/posts/default/4114018212593726161'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8909486560224298250/posts/default/4114018212593726161'/><link rel='alternate' type='text/html' href='http://prabhatmohapatra.blogspot.com/2009/04/rpg-xml-rpgs-xml-support.html' title='RPG &amp;amp; XML - RPGs XML Support'/><author><name>Prabhat</name><uri>http://www.blogger.com/profile/14496453689733819797</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8909486560224298250.post-735710752276621072</id><published>2009-04-16T01:47:00.000-07:00</published><updated>2009-04-16T01:56:02.945-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='IFS Folder'/><title type='text'>RPG programs to the IFS (AS400)</title><content type='html'>&lt;span style="font-family:courier new;"&gt;OK here we go for the benefit of IFS Files...........&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;There are lot of questions like....Question: Does anyone have a method to save a number of RPG programs to the IFS so can copy them over to CD for reference. &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;"&gt;Answer is yes, there is a way we can do this.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;"&gt;By using the foloowing command&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;"&gt;&lt;/span&gt;&lt;br /&gt;QSH CMD('cat qsys.lib/mylib.lib/qrpgsrc.file/mysource.mbr &gt; /myifsdir/myrpg.txt')&lt;br /&gt;Or......&lt;br /&gt;&lt;br /&gt;You can write a CL program to do this&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;DCLF       FILE(qtemp/MBRLIST) RCDFMT(QWHFDML) &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;CLRPFM   qtemp/MBRLIST &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;MONMSG     CPF0000      &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;DSPFD      FILE(mylib/mysource) TYPE(*MBRLIST) OUTPUT(*OUTFILE) OUTFILE(Qtemp/MBRLIST) NXTFIL:     RCVF          RCDFMT(QWHFDML)                                       &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;MONMSG     MSGID(CPF0864) EXEC(GOTO CMDLBL(ENDIT))                                                                                  &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;OVRDBF     FILE(mysource) TOFILE(mylib/mysource) MBR(&amp;amp;MLname)  &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;/*   &amp;amp;MLname now contains the member name to be moved via */ &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;/*     ftp/cpytopcd/qsh etc */             &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;GOTO CMDLBL(NXTFIL)                                                                                                  endit:   DLTOVR *ALL    &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;endpgm&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Also............You can share out source files to the network via Netserver. Then you merely open the share, drag and drop the folder to your desktop (or where ever), and all the source members in the folder become .txt files. Takes a while to run though, if your source file is big.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;"&gt;&lt;/span&gt;&lt;br /&gt;Another option is to use FTP. With a simple DOS batch file, you can pull down all of the members in a Source Physical File and drop them onto your hard drive individually (into a directory of your choice).&lt;br /&gt;&lt;br /&gt;ANOTHER WAY OUT...............&lt;br /&gt;FTP them from iSeries to your PC. In text mode the QRPGLESRC will ftp down the text only. I do it all the time and have tons of source on my notebook. I can even ftp from the iSieries to my ftp server on the web. I usr Seagull FTP Client does nicely attaching to iSeries FTP.just do a mget on the library/qrpglesrc *.* and the members will be named QRPGLESRC.yoursorucemembername.Then when you want to upload to iSeries do a put.Works like a charm.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8909486560224298250-735710752276621072?l=prabhatmohapatra.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://prabhatmohapatra.blogspot.com/feeds/735710752276621072/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://prabhatmohapatra.blogspot.com/2009/04/rpg-programs-to-ifs-as400.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8909486560224298250/posts/default/735710752276621072'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8909486560224298250/posts/default/735710752276621072'/><link rel='alternate' type='text/html' href='http://prabhatmohapatra.blogspot.com/2009/04/rpg-programs-to-ifs-as400.html' title='RPG programs to the IFS (AS400)'/><author><name>Prabhat</name><uri>http://www.blogger.com/profile/14496453689733819797</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8909486560224298250.post-2481338828317014386</id><published>2009-04-16T01:24:00.000-07:00</published><updated>2009-04-16T01:37:03.458-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='IFS Folder'/><title type='text'>IFS Folder</title><content type='html'>&lt;strong&gt;&lt;u&gt;Check object existence using IFS API&lt;/u&gt;&lt;/strong&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-family:courier new;"&gt;There is a simpler method to discover if your file, folder or other IFS object exists in the IFS, without getting into custom commands and system API's.&lt;br /&gt;A more practical method to discover if your file, folder or other IFS object exists is to use the RENAME command. This is the same old DOS or UNIX command we used in the 1980's where you can rename the object to the same name it already has.&lt;br /&gt;Typically, once you have navigated down the folder path of the IFS to the actual folder using the WRKLNK command -- like WRKLNK OBJ( '/folderA/folderB' ) or in batch work -- you would be using the CHGCURDIR or the shortcut commands CHDIR or CD, and then you can rename your object to the same name. &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;u&gt;Read an IFS file&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;How to read an ifs file and populate a table on the iseries.You wont be able to use it directly cause of some specifics in our environment, but I have included all the "stuff" you will need to test. Debug !!!! so .........&lt;/p&gt;&lt;p&gt;1) create the file &amp;amp; logical ... &lt;/p&gt;&lt;p&gt;2) create a folder on the IFS under root called sigmanest.&lt;/p&gt;&lt;p&gt;3) compile the program and put in debug....&lt;/p&gt;&lt;p&gt;The format of the file extracted from a drawing program (sigmanest) as a .csv which is what makes it interesting it created without commas..... &lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8909486560224298250-2481338828317014386?l=prabhatmohapatra.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://prabhatmohapatra.blogspot.com/feeds/2481338828317014386/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://prabhatmohapatra.blogspot.com/2009/04/ifs-folder.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8909486560224298250/posts/default/2481338828317014386'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8909486560224298250/posts/default/2481338828317014386'/><link rel='alternate' type='text/html' href='http://prabhatmohapatra.blogspot.com/2009/04/ifs-folder.html' title='IFS Folder'/><author><name>Prabhat</name><uri>http://www.blogger.com/profile/14496453689733819797</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
