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



I'm probably about to make a stupid comment, but... you're doing far more than is necessary to make this into a service program.

Alot of what you're changing is done because you're converting this from a main procedure into a subprocedure. That's technically not necessary to make it into a service program. You can still use *ENTRY PLIST with a service program. You can still use the cycle to open/close files and call *INZSR with a service program.

Granted, what you're doing is a good idea... and is a best practice.




On 1/6/2014 4:38 PM, Buck Calabro wrote:
On 1/6/2014 2:49 PM, Booth Martin wrote:
I wish I understood service programs better. There is one application I
believe would be an excellent service program but I do not know how to
do it.

http://martinvt.com/Code_Samples/Pop-up_Calendar/pop-up_calendar.html

It is a pop-up calendar. Its not my code but I have shown it on my web
site and I have modified it and C. Wilt fixed it up a couple of years
ago. It just seems to me that it would be a desirable service program.

My response is hopefully broad enough to be on topic. Specifically, I
will write about how to organise the various pieces and parts so that
there is a minimum amount of work needed to find and modify them in the
future.

ILE is complicated. On purpose. The idea is to be incredibly flexible
so that an application designer has many options available. That sounds
like bad news, but the good news is that with a tiny bit of work, most
of the complexity of ILE goes away. We need to talk about ILE because
we need to be out of the default activation group when using
sub-procedures. So here goes.

Using Booth's calendar as the example, I'd create a member in QRPGLESRC
called DATEUTIL. In that source member, I will have the source for
every date utility I will ever write, including this function which I'll
call POPCAL. Copy all of the source from UTLCALR into
QRPGLESRC(POPCAL). We'll come back to it.

Create another source member in QPROTOSRC. This is where your
prototypes will go. The new member will be called DATEUTIL - the same
name as the RPG source member you're working on. Copy the PR specs from
UTLCALR and rename the procedure POPCAL. Remove the EXTPGM() parameter.
Save it.

Go back to the QRPGLESRC member. Extract out the H specs for dftactgrp
and actgrp and add one for nomain. Add d/copy qprotosrc,dateutil
Change the name on the pi to POPCAL. Add a P POPCAL B...E pair. Put
EXPORT on the P POPCAL B. CRTRPGMOD on it (SEU option 15). There
should be two errors at this point:
1) The display file never gets closed.
2) *INZSR is not allowed.

Closing the display file is easy. Make the file USROPN. Before the
screen size check, add open popcalfm; Before the return (just before
the subroutines) add close popcalfm; (Yeah, I renamed that too.)

*INZSR is a little trickier, but not by much. What is that code doing?
Setting up a default parameter. That can be moved immediately above,
under the PI (just before the open popcalfm.)

Let's take a moment to sum up what's been done, structurally.
1) Created QRPGLESRC(DATEUTIL). This will contain every subprocedure
relating to date manipulation. For now, there's only one - POPCAL.
2) Created QPROTOSRC(DATEUTIL). This will contain prototypes and
'standard' date constants that every caller of the date utilities will
want. Right now, there's only the prototype for POPCAL.
3) Created a *MODULE called DATEUTIL.

Before we create the service program, let's do the tiny bit of work that
will make it easy to consume these date utility procedures. Create a
source file, QSRVSRC. Add a member called DATEUTIL. (Yes, all the
source members have the same name because it makes it easier to work on
next year when you've forgot where all the pieces are.) Make an export
block:

strpgmexp pgmlvl(*current) signature('Date utilities')
export symbol(popcal)
endpgmexp

Yes, I now advise using a programmer-named signature. You'll be adding
new exports to the end of the block anyway, so why bother with *PRV?

Create the service program: CRTSRVPGM SRVPGM(DATEUTIL) EXPORT(*SRCFILE)

Create a binding directory (CRTBNDDIR DATEUTIL).
ADDBNDDIRE BNDDIR(DATEUTIL) OBJ((DATEUTIL)) to put your service program
in it.

You now have all the constituent parts in a service program, ready for
someone to use. Let's do.

h dftactgrp(*no) actgrp('MYCOMPANY')
h bnddir('DATEUTIL')
d/copy qprotosrc,dateutil
d date s d inz(*loval)
popcal(date);
dsply date;
*inlr = *on;

Compile with CRTRPGMOD (SEU option 14) and call it. Up pops your
display file and when you pick a date, it gets displayed in the job log.

If you want to tinker the service program, CRTRPGMOD, then either
CRTSRVPGM again or UPDSRVPGM. Remember to export(*SRCFILE).

Lessons learnt:
1) Use one source member per service program.
2) Put multiple, related sub-procedures in that source member.
3) Name all the source members the same. In the future, when you go
looking (didn't I write a date utility that does...) you'll go to
QPROTOSRC, eyeball the list of members (there won't be that many), find
DATEUTIL and search there. Everything you need to know about the
procedure is right there in QPROTOSRC: the name, the binding directory,
the /copy - everything.
a) QRPGLESRC
b) QPROTOSRC
c) QSRVSRC
4) Use a binding directory so your colleagues can make changes and
recompile without needing a ouija board to work out how the pieces /
parts were assembled.
5) It doesn't take that long to do all this stuff. I assembled a
working service program while typing this up in under an hour.

--buck


As an Amazon Associate we earn from qualifying purchases.

This thread ...

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.