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



Perhaps a matter of preference, but I prefer to use the QLGSORT API, which
does provide for in place sorts along with data type awareness, national
language collation, etc. Here is an example of using QLGSORT to sort, in
place, the results returned by QUSLJOB.

h dftactgrp(*no) bnddir('APILIB')

fFIG13_3 cf e workstn sfile(JobRcd :RelRcdNbr)

d/copy qsysinc/qrpglesrc,qusgen
d/copy qsysinc/qrpglesrc,qusljob
d/copy qsysinc/qrpglesrc,qlgsort
d/copy qsysinc/qrpglesrc,qusec

dFig16_4 pr extpgm('FIG16_4')
d UserParm 10 const
d StatusParm 10 const

dFig16_4 pi
d UserParm 10 const
d StatusParm 10 const

dExists pr 1 extproc('Exists')
d ObjectName 10 const
d ObjectType 10 const
d ObjectLib 10 const options(*nopass)

dRtvSpcPtr pr extpgm('QUSPTRUS')
d SpcName 20 const
d UsrSpcPtr *
d USEC likeds(QUSEC) options(*nopass)

dCrtUsrSpc pr * extproc('CrtUsrSpc')
d SpcName 20 const

dListJob pr extpgm('QUSLJOB')
d SpcName 20 const
d Format 8 const
d JobName 26 const
d Status 10 const
d QUSEC likeds(QUSEC) options(*nopass)
d JobType 1 const options(*nopass)
d NbrKeyFlds 10i 0 const options(*nopass)
d KeyFlds likeds(KeyFlds) options(*nopass)
d ContinHdl 48 const options(*nopass)

dSndPgmMsg pr extpgm('QMHSNDPM')
d MsgID 7 const
d QualMsgF 20 const
d MsgDta 65535 const options(*varsize)
d LenMsgDta 10i 0 const
d MsgType 10 const
d CallStackEntry 65535 const options(*varsize)
d CallStackCntr 10i 0 const
d MsgKey 4
d QUSEC likeds(QUSEC)
d LenCSE 10i 0 const options(*nopass)
d CSEQual 20 const options(*nopass)
d DSPWaitTime 10i 0 const options(*nopass)
d CSEType 10 const options(*nopass)
d CCSID 10i 0 const options(*nopass)

dSort pr extpgm('QLGSORT')
d ReqControl 65535 const options(*varsize)
d Input 65535 options(*varsize)
d Output 1 options(*varsize)
d LengthOutput 10i 0 const
d LengthReturn 10i 0
d QUSEC likeds(QUSEC)
d RtnRcdFeedback 1 options(*varsize :*nopass)
d LengthRtnFB 10i 0 options(*nopass)

d* list API generic header
dGenHdr ds likeds(QUSH0100)
d based(GenHdrPtr)

d* List Job API (QUSLJOB) format JOBL0200
dLstEntry ds likeds(QUSL020001)
d based(LstPtr)

dAttrEntry ds likeds(QUSLKF)
d based(AttrPtr)

dSpcName ds
d SName 10 inz('JOBLIST')
d SLib 10 inz('QTEMP')

dKeyFlds ds
d KeyValues 10i 0 dim(25)

dFullJobName ds
d 10 inz('*ALL')
d SelUser 10 inz('*ALL')
d 6 inz('*ALL')

dQualMsgF ds
d MsgF 10 inz('MSGS')
d MsgL 10 inz('SOMELIB')

dNbrJobsDS ds
d NbrJobs 10i 0

dReqControl ds qualified
d SCB likeds(QLGSCB)
d SKL likeds(QLGSKL) dim(5)

dSelSts s 10 inz('*ALL')
dAtrValue s 10 based(AtrValPtr)
dNbrKeyFlds s 10i 0
dLstCount s 10i 0
dAttrCount s 10i 0
dRelRcdNbr s 4 0
dMsgKey s 4
dLenRtnDta s 10i 0

/free
QUSBPRV = 0;

// Let the user know we're working on it
SndPgmMsg( 'MSG0004' :QualMsgF :' ' :0
:'*STATUS' :'*EXT' :0 :MsgKey :QUSEC);

// If needed, create the user space for the list of jobs
if (Exists( SName :'*USRSPC' :SLib)) = 'N';
GenHdrPtr = CrtUsrSpc(SpcName);
else;
RtvSpcPtr( SpcName :GenHdrPtr :QUSEC);
endif;

// Get the list of jobs
if (%parms > 0);
SelUser = UserParm;
if (%parms > 1);
SelSts = StatusParm;
endif;
endif;

// Set the attribute key values
KeyValues(1) = 1004; // Job queue name
KeyValues(2) = 1501; // Output queue name
KeyValues(3) = 1603; // Printer device name
NbrKeyFlds = 3;

ListJob( SpcName :'JOBL0200' :FullJobName :SelSts :QUSEC
:'*' :NbrKeyFlds :KeyFlds);

// Check to see if the list is complete
if (GenHdr.QUSIS = 'C') or (GenHdr.QUSIS = 'P');
NbrJobs = GenHdr.QUSNBRLE;
SndPgmMsg( 'MSG0005' :QualMsgF :NbrJobsDS :4
:'*STATUS' :'*EXT' :0 :MsgKey :QUSEC);

// Get to the first list entry and process the list
LstPtr = GenHdrPtr + GenHdr.QUSOLD;

// Sort the results
ReqControl = *loval;
ReqControl.SCB.QLGLB = %size(ReqControl);
ReqControl.SCB.QLGRT = 5; // Use buffers
ReqControl.SCB.QLGRL = GenHdr.QUSSEE; // Size of record
ReqControl.SCB.QLGRC = GenHdr.QUSNBRLE; // Number of records
ReqControl.SCB.QLGOKL = // Set offset to sort keys
%addr(ReqControl.SKL(1)) - %addr(ReqControl);
ReqControl.SCB.QLGNBRK = 2; // Two keys
ReqControl.SCB.QLGLKE = %size(QLGSKL); // Size of one key entry
ReqControl.SKL(1).QLGSP = 1; // First key is job name
ReqControl.SKL(1).QLGSS = 10; // Key is 10 bytes long
ReqControl.SKL(1).QLGDT = 6; // Key is character
ReqControl.SKL(1).QLGSO = 1; // Ascending order
ReqControl.SKL(2).QLGSP = 11; // Second key is user name
ReqControl.SKL(2).QLGSS = 10; // Key is 10 bytes long
ReqControl.SKL(2).QLGDT = 6; // Key is character
ReqControl.SKL(2).QLGSO = 1; // Ascending order

Sort(ReqControl :LstEntry :LstEntry
:(GenHdr.QUSSEE * GenHdr.QUSNBRLE) :LenRtnDta :QUSEC);

for LstCount = 1 to GenHdr.QUSNBRLE;
JobName = LstEntry.QUSJNU00;
JobUser = LstEntry.QUSUNU00;
JobSts = LstEntry.QUSTATUS01;

// Get first attribute and process all returned
if LstEntry.QUSJIS = ' ';
AttrPtr = LstPtr + %size(QUSL020001);
for AttrCount = 1 to LstEntry.QUSNBRFR;
AtrValPtr = AttrPtr + %size(QUSLKF);
select;
when AttrEntry.QUSKF = 1004;
Jobq = AtrValue;
when AttrEntry.QUSKF = 1501;
Outq = AtrValue;
when AttrEntry.QUSKF = 1603;
Printer = AtrValue;
endsl;
AttrPtr = AttrPtr + AttrEntry.QUSLFIR;
endfor;
else;
JobQ = *ALL'*';
Outq = *ALL'*';
Printer = *ALL'*';
endif;

RelRcdNbr += 1;
write JobRcd;
LstPtr = LstPtr + GenHdr.QUSSEE;
if LstCount > 500;
leave;
endif;
endfor;

if RelRcdNbr > 0;
*in21 = *on;
*in24 = *on;
exfmt JobCtl;
endif;
else;
dsply 'List Object API did not return valid data';
endif;
*inlr = *on;
Return;

/end-free

this approach, Figure 4 of Chapter 16, when used in conjunction with the
earlier Figure 16 example of using a SFLSiz=SFLPag subfile and direct
access to each list entry should perform quite well and avoid the overhead
of going through a data queue.

Bruce Vining




"Cassidy, Alan" <CassidyA@xxxxxxxxxx>
Sent by: rpg400-l-bounces@xxxxxxxxxxxx
05/16/2007 10:39 AM
Please respond to
RPG programming on the AS400 / iSeries <rpg400-l@xxxxxxxxxxxx>


To
"RPG programming on the AS400 / iSeries" <rpg400-l@xxxxxxxxxxxx>
cc

Subject
RE: today's how-best-to question...






for position to you would have to "crawl" through the user space
entries... Thanks,

==>..(I "think") I would want to either sort the entries in place (why
not), using the retrieve-user-space-pointer QUSPTRUS API, and then
qsort(), since in this cases the returned formats are all fixed length
(IIRC).

My second choice would be single-page subfiles, driven by keyed data
queues, with a technique described by Kevin Vandever in his excellent
article, where he makes it easy:

http://www.itjungle.com/mpo/mpo052302-story05.html

His examples relate to file maintenance, but they can be adapted to this
situation by copying the object list to a "base" data queue, then
pretending that this "base queue" takes the place of the database file.

With the keyed data queues, you can data-structure the entries however you
want. and the keys, give the user multiple sort possibilites, etc.

<<________________________________________>>

I think that's very telling! Most people don't even know about the
1000 record limit in Google because they never page down that far. If
that's the case, what are the odds that they'll page down to the bottom of
a 9999 record subfile?

___What I do with Google (or Altavista, which is the one I'm using
nowadays more) is to try to think of more words to narrow it down to what
I really want, and that's why I think we should let them use "filters" on
the fly, pretty much, too, besides also the position-to...

--Alan


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.