× 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.




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...

As an Amazon Associate we earn from qualifying purchases.

This thread ...

Follow-Ups:
Replies:

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.