Tim,
You could try the EXCCLPDM utility that I wrote back in 2006 (you can
download the code at
http://www2.systeminetwork.com/code/index.cfm?fuseaction=ShowAllIssueCode&IssueYear=2006&IssueMonth=07)
to run FNDSTRPDM without needing to write a separate CL to handle errors.
The article is at
http://iprodeveloper.com/rpg-programming/generic-pdm-user-defined-option -
I've attached a copy here, in case you don't have membership. If you can't
even download the code, let me know and I can try to get that also.
Who knows, you might find it useful for other stuff as well :)
Rory
On Sat, Jan 16, 2016 at 1:06 PM, tim <iseriesstuff@xxxxxxxxx> wrote:
yeah. i started with fndstrpdm, but i have to build a cl for it to handles
errors and such. i was hoping for a 1 stop shop.
it also seems grep doesnt like relational db's. when i run it over a flat
file, it works fine. running it over PF with fields give me "not supported"
message.
oh well, was worth a shot.
On 1/16/2016 2:35 PM, John Yeung wrote:
On Sat, Jan 16, 2016 at 1:56 PM, tim <iseriesstuff@xxxxxxxxx> wrote:
i have gotten this so far, but its not returning the information i know
exists:
DSPFD FILE(datalibray*ALL)
TYPE(*MBRLIST)
OUTPUT(*OUTFILE)
OUTFILE(TIM/ALLFILES)
db2 "SELECT '/QSYS.LIB/' || trim(MLLIB) || '.LIB/' || trim(MLFILE) ||
'.FILE/' || trim(MLNAME) || '.MBR' FROM tim.allfiles
WHERE MLSEU=' ' and MLFTYP='P'"
| grep 'JUDY'
Even supposing grep is the proper tool for this, you wouldn't want to
pipe a list of the file names to it, you would want to just issue the
grep command directly, with a wildcard in the file name parameter
(second positional parameter). It's designed to work with multiple
files in a directory as its "natural" workflow.
But as you're searching physical files rather than stream files, I
think the more appropriate tool is FNDSTRPDM. You can either issue
that as a CL command, preferably as part of a SBMJOB if you're looking
through a lot of files, or interactively in PDM.
John Y.
--
This is the RPG programming on the IBM i (AS/400 and 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.
Please contact support@xxxxxxxxxxxx for any subscription related
questions.
Link: [1]Search search for iPro Developer (search)
[2]print | [3]close
[4]iPro Developer
--------------------------------------------------------------------------
A Generic PDM User-Defined Option
[5]System iNEWS Magazine
[6]Rory Hewitt
Rory Hewitt
Sat, 2006-07-01 (All day)
+---------------------------------+
|[7]Click here to download the |
|code bundle. To report code |
|errors, e-mail |
|[8]utilities@xxxxxxxxxxxxxxxxxx |
+---------------------------------+
Here, I share a utility I wrote that combines two useful features of
green-screen development -- PDM user-defined options and CL source
commands -- to ease the development cycle, automate error-handling, and
generally make life easier.
About User-Defined Options
If you've spent some time in Programming Development Manager (PDM) working
with lists of libraries, objects, and members, you've probably used (and
possibly have created) user-defined options (UDOs). A UDO links a
two-character option code to a specific OS/400 command and is a simple way
to abbreviate commands you want to perform against a PDM list item. You
invoke UDOs by specifying them in the Option subfile selector field on the
three PDM list screens (WRKLIBPDM, WRKOBJPDM, or WRKMBRPDM).
IBM reserves numeric PDM options for standard functionality (such as
2=Change, 14=Compile), but aside from that, the only limitation is that
your two-character UDO name must be a valid system name. Depending on how
you have your development environments set up, all users can share a
common set of UDOs, each user can have his own UDO, or you can have a
combination. A set of default UDOs is shipped in member QAUOOPT in file
QGPL/QAUOOPT.
I use UDOs extensively when I'm building product libraries because it's a
quick and easy way to duplicate processing for multiple related objects.
For example, here are two of my UDOs:
DO DSPOBJD OBJ(&L/&N)
OBJTYPE(&T)
DETAIL(*SERVICE)
RA RVKOBJAUT OBJ(&N)
OBJTYPE(&T)
USER(BUILDER)
AUT(*ALL)
As in these two examples, UDOs can contain certain substitution variables,
which PDM will replace with the relevant value for the list item before it
executes the command.
When used with the Repeat (F13) command key available in PDM, UDOs are a
godsend. It's obviously much easier to do a WRKOBJPDM, take option RA
against the first object in the list, press F13, and click Enter than it
is to manually specify the RVKOBJAUT command on a command line against
each object.
However, UDOs have one major drawback. If the command specified in the UDO
fails for any reason, the PDM screen is redisplayed with the Option
subfile selector field for the item highlighted in reverse-image. To
continue, you must blank out the Option field for that list entry.
Now if you're just taking a UDO against one or two objects, this isn't a
problem. You simply clear the Option field, and you're done. However, if
you have specified your UDO against multiple list entries (perhaps by
using the F13=Repeat command key), this can be a hassle. If several list
entries cause the command to fail, you have to blank out entries
repeatedly to get the thing to work. This means that unless you know that
the UDO command will be successful for every entry in the list, you can't
run a UDO over multiple entries as a start-and-forget process.
So given my previous example UDOs, if you take option RA against multiple
objects, and user BUILDER doesn't currently have authority to one or more
of them, then the RVKOBJAUT command will return a CPD2241 (Authority not
revoked) error message, requiring you to blank out the Option field for
that list item. This can be even worse when the UDO command is a
long-running command, because you're forced to hang around to ensure that
the command completes successfully for each list entry.
Another limitation of traditional UDOs is that if you want to run more
than one command against a list entry, you have two different options,
each with its own drawback:
* Define two separate UDOs and run them one after another (which still
leaves you open to the previous problem, as well as forcing you to
hang around until the first option has completed so you can execute
the second option).
* Write a program that specifies all the commands (which can mean that
you're left with a program that might never be needed again) and call
that program with a single UDO.
So what to do? Well, if you're like me, you write a utility to overcome
these problems (and more).
The EXCCLPDM Command
Essentially, I have written a generic UDO that you can use to execute any
specified series of commands (which are stored in a CL source member). It
also contains its own error handling, which you can set up to ignore
certain errors.
My utility is invoked by a command called Execute CL as PDM option
(EXCCLPDM), which should be specified as a UDO. When you execute a UDO to
invoke EXCCLPDM, you specify the name of the source member that contains
the commands that should be executed (each of which can contain
substitution variables). Alternatively, you can specify commands on the
fly in a separate CMD parameter to the EXCCLPDM command, rather than
coding them into a source member, which can be useful when you have only a
single command to run and you simply want to take advantage of the error
handling in EXCCLPDM.
Whether you execute commands in a source member or in the CMD parameter,
using EXCCLPDM, you have the following options:
* You can prompt each command before it is run (but after its
substitution variables have been filled in). At this point, you can
simply run the command, change the command and then run it, or press
F3 or F12 to cancel the command. (If you cancel the command, then
EXCCLPDM will prompt the next command.)
* You can specify the number of command errors that you will allow. This
gets you around the problem of an individual command returning an
error and causing a global error.
* You can specify whether you want the commands to be logged to the job
log (or whether you want only commands that return errors to be
logged).
Additionally, if you are running commands from a source member (as opposed
to specifying commands in the CMD parameter), you have the following
functionality:
* You can specify for individual commands whether they should be
prompted.
* You can specify for individual commands whether they should be allowed
to return an error and still allow subsequent commands to be
processed.
* You can specify for individual commands whether they should cause the
processor to stop processing any more commands for that list entry.
* You can edit the source member before it is processed.
For instance, by changing my RA example from directly invoking the
RVKOBJAUT command
RVKOBJAUT OBJ(&N)
OBJTYPE(&T)
USER(BUILDER)
AUT(*ALL)
to invoking the RVKOBJAUT command via the CMD parameter of the EXCCLPDM
command
EXCCLPDM SRCMBR(*CMD)
CMD('RVKOBJAUT OBJ(&N)
OBJTYPE(&T) USER(BUILDER)
AUT(*ALL)') ERRLVL(*NOMAX)
I can run the RA UDO against multiple objects and not worry about handling
errors. They will still be written to the job log, but they won't require
me to do anything. Control will not return to me until all the selected
objects have been processed.
As you will see from the code, this is all simple stuff. However, it lets
you simplify your life when it comes to doing those mundane tasks.
Setting Up EXCCLPDM
First, compile the EXCCLPDM command, the EXCCLPDMH help text, and the
EXCCLPDMR program into a "common" library. (I use QGPL, both for the
EXCCLPDM* objects and for the QCLSRC source file where I store my UDO
command members.)
Next, create a "generic" UDO (in this example, I use XX as the option
value) with the following command value:
EXCCLPDM SRCFILE(
QGPL/QCLSRC)
ATTR('&A')
LISTTYPE(&B) OPTION(&C)
CHGDATE('&D') BATCH(&E)
FILE(&F) JOBDLIB(&G)
JOBD(&H) LIBRARY(&L)
ITEM(&N) OBJLIB(&O)
REPLACE(&R) TYPE1(&S)
TYPE(&T) TEXT(&X)
Because you haven't specified a value for the SRCMBR parameter, when you
take option XX against a list entry, you can either press F4 to prompt the
EXCCLPDM command or specify a value for SRCMBR in the command line on the
"Work with" PDM screen.
Finally, start creating members in QGPL/QCLSRC. Because you must be able
to include variables in the commands, you should create the members with
an attribute of CLP, even though you will never actually compile these
members into program objects.
Within the commands in your source members, you can include the
substitution variables in [9]Figure 1 (most of which are standard PDM
substitution variables); these are passed via the EXCCLPDM command
interface. You can also include the EXCCLPDM substitution variables in
[10]Figure 2 (which are not passed as parameters of the EXCCLPDM command).
Within the source member being processed, the user can also include
special handlers to provide command-level overrides of the behavior that
would result from the values specified for the ERRLVL and PROMPT parameter
to the EXCCLPDM command.
You should include these handlers within a comment for the command being
run, for example:
CHGJOB /* **PROMPT */
The available handlers are
* **ALWERR allows errors on the command and still processes subsequent
commands, even if the value specified in the ERRLVL parameter on the
EXCCLPDM command has been reached.
* **NOALWERR specifies to quit if the command returns an error, even if
the value in the ERRLVL parameter on the EXCCLPDM command has not been
reached.
* **PROMPT prompts the command, even if PROMPT (*NO) was specified for
the EXCCLPDM command.
* **NOPROMPT specifies not to prompt the command, even if PROMPT(*YES)
was specified for the EXCCLPDM command.
Some example members that I use are
* SAVELIB -- Use this member against a library (on the WRKLIBPDM screen)
to save the library to a save file (with the same name) in QTEMP,
setting the ownership/authorities correctly and ensuring that the save
file text is the same as the library text. In [11]Figure 3, notice the
use of the **ALWERR handler to ignore errors if the save file already
exists.
* CHGOWN -- Use this member against a library (on the WRKLIBPDM screen)
to set various authorities on an object ( [12]Figure 4).
I hope these examples give you an idea of the sorts of things you can do
with EXCCLPDM!
Rory Hewitt is a software developer in San Francisco, California. He has
been working on the iSeries since 1994, specializing in tools development
in RPG, Cobol, PL/I, and MI. You can reach him at
[13]rory.hewitt@xxxxxxxxx.
No
Publication Info
--------------------------------------------------------------------------
Source URL:
[14]
http://iprodeveloper.com/rpg-programming/generic-pdm-user-defined-option
[15][IMG]
IFrame: [16]DivShim
Sponsored Introduction [17]Continue on to (or wait seconds) [18]�
References
Visible links
1.
http://iprodeveloper.com/opensearch/apachesolr_search
2. javascript:window.print();
3. javascript:window.close()
5.
http://iprodeveloper.com/system-inews-magazine
6.
http://iprodeveloper.com/author/rory-hewitt
7.
http://www2.systeminetwork.com/code/index.cfm?fuseaction=ShowAllIssueCode&IssueYear=2006&IssueMonth=07
8. mailto:utilities@xxxxxxxxxxxxxxxxxx
9.
http://iprodeveloper.com/artarchiveimages/2006/jul/20593-fig1.gif
10.
http://iprodeveloper.com/artarchiveimages/2006/jul/20593-fig2.gif
11.
http://iprodeveloper.com/artarchiveimages/2006/jul/20593-fig3.html
12.
http://iprodeveloper.com/artarchiveimages/2006/jul/20593-fig4.html
13. mailto:rory.hewitt@xxxxxxxxx
14.
http://iprodeveloper.com/rpg-programming/generic-pdm-user-defined-option
15.
http://www.omniture.com/
16.
http://iprodeveloper.com/sites/all/modules/custom/pm_doubleclick/blankIframe.html
17. javascript:void(0);
18.
http://iprodeveloper.com/rpg-programming/generic-pdm-user-defined-option#
As an Amazon Associate we earn from qualifying purchases.