× The internal search function is temporarily non-functional. The current search engine is no longer viable and we are researching alternatives.
As a stop gap measure, we are using Google's custom search engine service.
If you know of an easy to use, open source, search engine ... please contact support@midrange.com.



sounds too simple...just might work LOL

Thanks,
Tommy Holden


-----Original Message-----
From: Scott Klement [mailto:rpg400-l@xxxxxxxxxxxxxxxx]
Sent: Thursday, February 17, 2005 11:32 AM
To: RPG programming on the AS400 / iSeries
Subject: Re: Procedure names vs. production support



Hi Rick,

> I'm trying to advance development in our shop to using procedures for 
> specific business logic and combining them into service programs.  The 
> issue I'm coming up against involves how to name the procedures.  If an 
> error occurs in a production run the message will identify the procedure 
> receiving the error, which may or may not be the name of the source 
> member, causing confusion and delaying problem resolution.  I have 
> listed the options I have come up with so far.

What I do is used by srvpgm name as a prefix for each subprocedure, and 
not just subprocedures, but anything else that my srvpgm makes available 
to callers.

For example, if I'm writing an order inquiry program:

a) I'll use the prefix ORDINQ to identify this srvpgm.

b) The SRVPGM itself will be named ORDINQR4 and the entry module for that 
srvpgm will also be named ORDINQR4 (R4 = RPG IV)

c) The /copy member that will contain all of the prototypes for this 
srvpgm will be named ORDINQ_H

d) In the /copy member will usually be data structure templates, 
prototypes and error codes. All of these start with ORDINQ so that I know 
which service program they belong to, and so that my code won't conflict 
with definitions in another srvpgm, which makes the code more reusable.

My /copy member will look something like this (abbreviated)

       /if defined(ORDINQ_H_DEFINED)
       /eof
       /endif
       /define ORDINQ_H_DEFINED

       /if not defined(SUCCESS_AND_FAIL)
      D SUCCESS         c                   const(*ON)
      D FAIL            c                   const(*OFF)
       /define SUCCESS_AND_FAIL
       /endif

       *********************************************************
       * ORDINQ_HEADER: Data structure containing order
       *                header-level info
       *
       *   <explain fields here>
       *********************************************************
      D ORDINQ_HEADER   DS                  qualified
      D                                     based(Template)
      D   Order                        5A
      D   Cust                         4P 0
      D   ShipTo                      25A   dim(5)
      D   BillTo                      25A   dim(5)
      D   OrderDate                     D
      D   Terms                        1A
      D   DelivDate                     D
      D   ShipDate                      D

       *********************************************************
       * ORDINQ_LINE_ITEM: Info about a given line item
       *
       *   <explain fields here>
       *********************************************************
      D ORDINQ_LINE_ITEM...
      D                 DS                  qualified
      D                                     based(Template)
      D   ItemNo                       5P 0
      D   ItemDesc                    25A
      D   QtyOrd                       9P 2
      D   QtyShp                       9P 2
      D   UomOrd                       1A
      D   Price                        7P 2
      D   QtyInv                       9P 2
      D   UomInv                       1A


       *++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       * ORDINQ_open():  Open an order for inquiry
       *
       *      peOrder = (input) Order number to open
       *      peCust  = (input) Customer number of order
       *       peHdr  = (output) Order header information
       *
       * returns SUCCESS or FAIL
       *++++++++++++++++++++++++++++++++++++++++++++++++++++++++
      D ORDINQ_open     PR             1N
      D   peOrder                      5A   const
      D   peCust                       4P 0 value
      D   peHdr                             likeds(ORDINQ_HEADER)


       *++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       * ORDINQ_read():  Read next line item from the last
       *                 order opened
       *
       *      peLine  = (output) Line item information
       *
       * returns SUCCESS or FAIL
       *++++++++++++++++++++++++++++++++++++++++++++++++++++++++
      D ORDINQ_read     PR             1N
      D   peLine                            likeds(ORDINQ_LINE_ITEM)


       *++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       * ORDINQ_error(): Get info about last error that occurred
       *
       *   Note: Call this after receiving a FAIL response to
       *         see what the problem was.
       *
       *      peErrno = (optional/output) error number
       *                corresponds to the ORDINQ_ERROR_xxx
       *                constants, below
       *
       * Returns the error message, or *blanks if no error
       *++++++++++++++++++++++++++++++++++++++++++++++++++++++++
      D ORDINQ_error    PR            80A
      D   peErrno                     10I 0 options(*nopass)


       *********************************************************
       * Error codes... values that can be retrieved with
       *   the ORDINQ_error routine
       *********************************************************
      D ORDINQ_ERROR_NOTFOUND...
      D                 c                   const(2001)
      D ORDINQ_ERROR_CANTOPEN...
      D                 c                   const(2002)
      D ORDINQ_ERROR_NOACCESS...
      D                 c                   const(2003)

e) I will have a binding directory also named ORDINQ that will only bind 
to this service program.  When a program wants to use it, it'll do the 
following:

      H DFTACTGRP(*NO) BNDDIR('ORDINQ')

       /copy qrpglesrc,ordinq_h

      D Hdr             ds                  likeds(ORDINQ_HEADER)
      D Item            ds                  likeds(ORDINQ_LINE_ITEM)

       /free

          . . .

          if (ORDINQ_open(myOrdNo : myCustNo : Hdr) = FAIL);
              errmsg = ORDINQ_error();
              // display error to user.
          endif;

          // move fields from data structure to
          // subfile control record, here.

          . . .

          dow ORDINQ_read( Item ) <> FAIL;
             // move fields from data structure to
             // subfile record here.
             RRN = RRN + 1;
             write SFLREC;
          enddo;

If there's a serious error, causing the srvpgm to crash or whatever, I can 
see what procedure the error occurred in, and since the procedure name 
starts with ORDINQ I know that it's from the ORDINQ service program.

I typically only have one module per service program, so if I know the 
service program name, I'll also know the source member name and the module 
name...

I haven't yet developed a standard for what I do when I've got multiple 
modules in a service program. That's so rare for me right now, I haven't 
really thought about it.

But, I guess I'd change my current "SRVPGM_PROCNAME" scheme to be 
something like "SRVPGM_MODULE_PROCNAME"

Anyway, hope that gives you some food for thought...
-- 
This is the RPG programming on the AS400 / iSeries (RPG400-L) mailing list
To post a message email: RPG400-L@xxxxxxxxxxxx
To subscribe, unsubscribe, or change list options,
visit: http://lists.midrange.com/mailman/listinfo/rpg400-l
or email: RPG400-L-request@xxxxxxxxxxxx
Before posting, please take a moment to review the archives
at http://archive.midrange.com/rpg400-l.

As an Amazon Associate we earn from qualifying purchases.

This thread ...


Follow On AppleNews
Return to Archive home page | Return to MIDRANGE.COM home page

This mailing list archive is Copyright 1997-2024 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].

Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.