Midrange News for the IBM i Community


Posted by: Chris Proctor
Programmer Analyst
Columbia Sports Company
Portland, OR
CL command to return number of members of a file?
has no ratings.
Published: 11 Sep 2012
Revised: 23 Jan 2013 - 4083 days ago
Last viewed on: 29 Mar 2024 (15683 views) 

Using IBM i? Need to create Excel, CSV, HTML, JSON, PDF, SPOOL reports? Learn more about the fastest and least expensive tool for the job: SQL iQuery.

CL command to return number of members of a file? Published by: Chris Proctor on 11 Sep 2012 view comments(9)

Good afternoon! I always thought that RTVMBRD would return the number of members for a physical file, but apparently it always returns 0. I need a CL command that I can include in a CLP that will return the number of members for a physical file.

Can anyone help me out?

Thanks!

Return to midrangenews.com home page.
Sort Ascend | Descend

COMMENTS

(Sign in to Post a Comment)
Posted by: neilrh
Premium member *
Jackson, MI
Comment on: CL command to return number of members of a file?
Posted: 11 years 6 months 17 days 17 hours 37 minutes ago

I think the RTVMBRD returned value you're looking at is this one:

Specifies the name of a variable used to retrieve the number of data file members for this logical file member.  In CL programs, this should be a 2-position decimal variable.  If the member is a physical file member, a value of 0 is returned.

The API QDBRTVFD returns the data that you need.

Posted by: chrisp
Premium member *
Portland, OR
Comment on: CL command to return number of members of a file?
Posted: 11 years 6 months 17 days 17 hours 29 minutes ago

I was looking thru APIs and didn't see the one you mentioned, Neil. I'll check it out. Thanks!

Chris

Posted by: JOHND1
Premium member *
Milford, Ma
Comment on: CL command to return number of members of a file?
Posted: 11 years 6 months 17 days 17 hours 28 minutes ago

here is something I found on line,  hope it helps

 

RTVMBRD: Retrieve Member De!--script--ion. Specify a file (and optionally a member) and you can find out more about that file.

  • RTNLIB: This value will tell you the library where the file resides. Like RTVOBJD, this parameter is especially useful if you specify *LIBL for the file name and need to determine the library.
  • RTNMBR: Just like the previous parameter, if you didn't specify a member by name, this value will contain that member name.
  • SRCTYPE: If the file is a source file, this value will contain the source type of the specified member.
  • TEXT: This is the text used when the member was created.
  • NBRCURRCD: This is perhaps my favorite parameter from all of the RTV commands. Many times I only need to perform actions if a file actually has data in it. This value contains the current number of data records in the file and member specified.

Here's an example of the RTVMBRD command.

RTVMBRD FILE(your-library/your-file)
   MBR(*FIRSTMBR)
   RTNLIB(&RTNLIB)
   RTNMBR(&RTNMBR)
   SRCTYPE(&SRCTYPE)
   TEXT(&TEXT)
   NBRCURRCD(&NBRCURRCD)

The RTVMBRD command can be used in a loop to process all members of a multi-member file (physical or source). On the first execution of the command specify the MBR parameter as MBR(*FIRST *SAME) (to process in creation-date order) or MBR(*FIRSTMBR *SAME) (to process in alphabetical-name order). On subsequent executions of the command, specify MBR(&RTNMBR *NEXT). Be sure to specify parameter RTNMBR each time you execute the command so that you'll have the value for the next iteration. Alternatively you can specify MBR(*LAST *SAME) or MBR(*LASTMBR *SAME) followed by MBR(&RTNMBR *PRV) to read through the members in reverse order.

The following short example illustrates how to process all members of a file in alphabetical order.

Pgm                                                                     
                                                                        
   Dcl  &Member    *char   10                                           
   Dcl  &Position  *char   10                                           
   Dcl  &CurUser   *char   10                                           
   Dcl  &RtnMbr    *char   10                                           
                                                                        
   RtvJobA   curuser(&CurUser)                                          
                                                                        
   /* process members in alphabetical order */
   ChgVar    &Member     *FIRSTMBR                                      
   ChgVar    &Position   *SAME                                          
                                                                        
NextMember:                                                             
   RtvMbrD   file(SomeFile) mbr(&Member &Position) rtnmbr(&RtnMbr)
   MonMsg    cpf3049 exec(goto EndOfFile)                               
                                                                        
   /* place commands to process &RtnMbr here */
   SndMsg msg('Processing member' *bcat &RtnMbr *tcat '.') +            
             tousr(&CurUser)                                            
                                                                        
   /* move to the next member */
   ChgVar    &Member     &RtnMbr
   ChgVar    &Position   *NEXT 
   goto NextMember             
                               
EndOfFile:                     
                               
Posted by: DaleB
Premium member *
Reading, PA
Comment on: CL command to return number of members of a file?
Posted: 11 years 6 months 17 days 17 hours 21 minutes ago
Edited: Tue, 11 Sep, 2012 at 15:35:13 (4217 days ago)

You'd need like a RTVFD, but there isn't one. [As previously noted, help for RTVMBRD says NBRDTAMBRS is for LF's, and that for PF's it always returns 0. I think it tells you how many PF members are "based on" by the current LF member name.]

I don't have access to a system right now. Try DSPFD to *OUTFILE with *ATR and *PF. If that doesn't have number of members, you can get it from *MBRLIST. In QAFDMBRL, field &MLNOMB has the number of members (so you only need to read the first record - you don't need a loop). If there are no members, you still get one record with a 0 for &MLNOMB.

If it's pure CL, the DSPFD is probably good enough. But you can also use the QUSLMBR API. MBRI0100 returns just member names. I'm not sure what you get if there are no members, so you'd have to test that. Either the number of list entries (in the header) will be zero (and you don't need to look at the list), or it will be one, and you'll need to read that first list entry to determine if it's a real member name or some special value. Of course, if the number of list entries is greater than one, then you also won't need to process the list.

Posted by: bobcozzi
Site Admin ****
Chicagoland
Comment on: CL command to return number of members of a file?
Posted: 11 years 6 months 17 days 15 hours 53 minutes ago
Edited: Tue, 11 Sep, 2012 at 17:03:28 (4217 days ago)

I wrote a quick and dirty little RTVFD command for you. It will return the member count. You have to be on at least v5r4 to have it work for you. here's the source:

 

 RTVFD:      CMD        PROMPT('Retrieve File De!--script--ion Info') +
                          ALLOW(*IPGM *BPGM *IMOD *BMOD)
             PARM       KWD(FILE) TYPE(QUAL1) MIN(1) PROMPT('File +
                          name')
 QUAL1:      QUAL       TYPE(*NAME) LEN(10) EXPR(*YES)
             QUAL       TYPE(*NAME) LEN(10) DFT(*LIBL) +
                          SPCVAL((*LIBL) (*CURLIB)) EXPR(*YES) +
                          PROMPT('Library')
             PARM       KWD(RTNMBRS) TYPE(*DEC) LEN(5 0) +
                          RTNVAL(*YES) MIN(1) CHOICE('Type(*DEC) +
                          Len(5 0)') PROMPT('CL var for member count') 

 The program I wrote is in CL, so here's the CPP for the above command:

 The program calls the QDBxxx API and returns the member count. For debug purposes, I included the cozTools CLEDIT command that converts the returned value to text and then I send the message with the member count to *PRV. You can strip out that part if you want.

 RTVFD:      PGM        PARM(&FILE &RTNMBRCNT)
             DCL        VAR(&RTNMBRCNT) TYPE(*DEC) LEN(5)
             DCL        VAR(&MBRCOUNT) TYPE(*CHAR) LEN(10)
             DCL        VAR(&FILD0100) TYPE(*CHAR) LEN(400)
             DCL        VAR(&DBFHMXM ) TYPE(*INT) STG(*DEFINED) +
                          LEN(2) DEFVAR(&FILD0100 42)
             DCL        VAR(&DBFHMNUM) TYPE(*INT) STG(*DEFINED) +
                          LEN(2) DEFVAR(&FILD0100 48)
             DCL        VAR(&DBFmxfnum) TYPE(*INT)  STG(*DEFINED) +
                          LEN(2) DEFVAR(&FILD0100 207)
             DCL        VAR(&DBFmxrl) TYPE(*INT)  STG(*DEFINED) +
                          LEN(2) DEFVAR(&FILD0100 305)
             DCL        VAR(&DBFgkct) TYPE(*INT)  STG(*DEFINED) +
                          LEN(2) DEFVAR(&FILD0100 315)
             DCL        VAR(&DBFpact) TYPE(*CHAR) STG(*DEFINED) +
                          LEN(2) DEFVAR(&FILD0100 337)
             DCL        VAR(&DBFHRIS) TYPE(*CHAR) STG(*DEFINED) +
                          LEN(6) DEFVAR(&FILD0100 339)
             DCL        VAR(&RTNLEN) TYPE(*INT) LEN(4) VALUE(400)
             DCL        VAR(&RTNFILE) TYPE(*CHAR) LEN(20)
             DCL        VAR(&FILE) TYPE(*CHAR) LEN(20)
             DCL        VAR(&APIERROR) TYPE(*CHAR) LEN(16) VALUE(X'0000000000000000')
             MONMSG     MSGID(CPF0000)
             CALL       PGM(QDBRTVFD) PARM(&FILD0100 &RTNLEN +
                          &RTNFILE 'FILD0100' &FILE '*FIRST' '0' +
                          '*FILETYPE' '*EXT' &APIERROR)
             CHGVAR     VAR(&RTNMBRCNT) VALUE(&DBFHMNUM)

       /* Extra cozTools-enabled stuff */
             CLEDIT     RTNVAR(&MBRCOUNT) VALUE(&DBFHMNUM)
             SNDPGMMSG  MSGID(CPF9897) MSGF(QCPFMSG) MSGDTA('File' +
                          *BCAT %SST(&FILE 1 10) *BCAT 'in' *BCAT +
                          %SST(&FILE 11 10) *BCAT 'contains' *BCAT +
                          &MBRCOUNT *BCAT 'members.') MSGTYPE(*COMP)
 ENDPGM:     ENDPGM 

 

Then I wrote a little test program to "prove" it'll work, that is listed below:

 

TESTRTVFD:   PGM
             DCL        VAR(&MBRS) TYPE(*DEC) LEN(5 0)
             DCL        VAR(&MBRA) TYPE(*CHAR) LEN(5)
             MONMSG     MSGID(CPF0000)
             RTVFD      FILE(COZTOOLS/QRPGLESRC) RTNMBRS(&MBRS)
             CHGVAR     VAR(&MBRA) VALUE(&MBRS)
             SNDPGMMSG  MSGID(CPF9897) MSGF(QCPFMSG) MSGDTA('Member +
                          count' *BCAT &MBRA)
 ENDPGM:     ENDPGM 

 

Posted by: neilrh
Premium member *
Jackson, MI
Comment on: CL command to return number of members of a file?
Posted: 11 years 6 months 17 days 1 hours 7 minutes ago

You could also use the List Members API, but for that you need to create a UsrSpc, before you create the list. Also you don't actually need the list, you just need to read the header bit of the Data Extract for Number of Elements. But also if the list is too large to be contained in the User Space, the Number of Elements might be a inaccurate - there's a status code in the header which is set to a certain value if the list is complete, other values indicate incomlete or error.

Posted by: Ringer
Premium member *
Comment on: CL command to return number of members of a file?
Posted: 11 years 6 months 17 days 37 minutes ago

Another option... wrap this in a Callable CL Pgm.

DLTF QTEMP/TMPMBRCNT

MONMSG CPF2105

DSPFD FILE(&YOURLIB/&YOURFILE) TYPE(*MBR) OUTPUT(*OUTFILE)
FILEATR(*PF) OUTFILE(QTEMP/TMPMBRCNT) OUTMBR(*FIRST *REPLACE) 

Then RCVF file QAFDMBR Format QWHFDMBR in CL and return field MBNOMB.

Ringer

Posted by: DaleB
Premium member *
Reading, PA
Comment on: CL command to return number of members of a file?
Posted: 11 years 6 months 16 days 23 hours 51 minutes ago

Thanks Bob! That API is nightmarish, but I missed that number of members is in the header.

Posted by: bobcozzi
Site Admin ****
Chicagoland
Comment on: CL command to return number of members of a file?
Posted: 11 years 6 months 16 days 22 hours 41 minutes ago

Dale, like most of the APIs, this one is documented poorly and is very misleading. I sometimes leave these goofy APIs alone for years, and then revisit them only to look at it with different eyes. Then I usually have success with them. But the docs are horrible.