Flat file or Physical file in as/400?

370 pts.
AS/400 Subfiles
Flat files
Physical File
How to know whether a file is physical file or flat file in CL/400?

Software/Hardware used:

Answer Wiki

Thanks. We'll let you know when a new response is added.

First of all, a FLAT file is a Physical file.
I’m thinking your question is really “How do I know if a file is externally defined?”
Using RTVMBRD, you can determine if it is a PF or LF.
To deteremine if the file is externally defined, you could to do a DSPFFD to a work file in QTEMP. Then do a RTVMBRD of that workfile and check for number of records. If move than one, it would have an external definition (whick would be in the workfile).
There is an exception to this and that is if the file is a PF-SRC. Then it would have 3 fields.


It can depend on what you mean by “flat file”. There are generally three possible meanings of the term for AS/400 developers. One meaning relates to a type of mainframe file that would only be of interest to AS/400 developers who also work with mainframe functions, so we’ll ignore that one.

On an AS/400, a “flat file” could be either a “program-described” file or a streamfile. Since streamfiles are fundamentally different and clearly recognizable, we can probably assume that you mean a “program-described” file.

Generally, a “program-described” file is a physical file (PF) that was created without DDS (and without SQL DDL). Such a file has a record format with a single field. You can create one with a command such as:


Here is an example ILE CL program that returns an indication that QTEMP/FLAT is a “program-described” file:


dcl &qfile *char 20

dcl &file *char 10 value( 'FLAT ' )
dcl &lib *char 10 value( 'QTEMP ' )

dcl &fd *char 512
dcl &lfd *int value( 512 )

dcl &pgmdBits *char 1

dcl &pdBit *uint value( 7 )
dcl &pdTyp *int value( -1 )

chgvar &qfile ( &file *cat &lib )

call QDBRTVFD ( +
&fd +
&lfd +
' ' +
'FILD0100' +
&qfile +
'*FIRST ' +
'0' +
'*LCL ' +
'*EXT ' +
x'0000000000000000' +

chgvar &pgmdBits %sst( &fd 61 1 )

callprc '_TSTBTS' ( +
&pgmdBits +
( &pdBit *byval ) +
) +
rtnval( &pdTyp )




The program takes the file name and library and creates a qualified file name. It passes that to the Retrieve Database File Description (QDBRTVFD) API and asks for the File definition template (format FILD0100) to be returned.

At position 61 of the File definition template there is a bit field called Qaaf (Additional attribute flags). Bit 7 of that bit field is Qdbfpgmd (Program described file indicator).

Generally, you can test that byte to see if it’s equal to x’01’. If it is, then you have a program-described file. If the value is x’00’, then it’s an externally-described file.

However, the example program uses the Test Bit in String (TSTBTS) MI builtin function to test bit 7 (the value from &pdBit) to get an on/off indication. The indication is returned in &pdTyp . The program tests the bit directly because IBM has the first bits of that bit field as ‘reserved’ — their values may change without prior notice to you. (They haven’t changed in maybe 20 years, but it’s better to expect changes.)

You should be able to compile the ILE CL example program. Paste it into a source member of type CLLE in PDM and compile with option 14. (Or just run CRTBNDCL over the member.) Then run the CRTPF command from above for QTEMP/FLAT and call the program in that job. The dump created by the program should show that &pdTyp returns the value 1.

If you change the values of &file and &lib to point to some file that you know is externally-described, the dump should show that &pdTyp returns the value 0.


Discuss This Question: 3  Replies

There was an error processing your information. Please try again later.
Thanks. We'll let you know when a new response is added.
Send me notifications when members answer or reply to this question.
  • Alicsc
    Thanks Tom. Good example.
    370 pointsBadges:
  • TomLiotta
    The length of &fd is DCLed at 512, though it can be smaller. I haven't experimented with enough lengths to see what the minimum is even though the documentation says it can be as small as *CHAR (8). I do know that if you set it for example for *CHAR (128) on at least some releases, you won't get data in the template structure -- you will only get the bytes-returned and bytes-available values. Also, the example is coded for a minimum V5R3. For earlier releases, the &lfd variable would have to be *CHAR (4) and the value would need to be specified in hex. A 4-byte hex literal could also be directly supplied for the parm value. Finally, the error code parameter is not really proper for a production call to an API. It really ought to be a structure that's large enough to receive any error indications so that you won't have to use MONMSG to monitor after the CALL. But decent error code handling should be a thread by itself. Tom
    125,585 pointsBadges:
  • TomLiotta
    And also note that CharlieBrowne's example is perfectly valid. It's likely that most CL programmers would choose that method rather than my example. Mine is just an alternative that might avoid some complexities while introducing others. An API call avoids needing to open a file in CL, but it also requires paying very close attention to some documentation that won't be familiar. Tom
    125,585 pointsBadges:

Forgot Password

No problem! Submit your e-mail address below. We'll send you an e-mail containing your password.

Your password has been sent to:

To follow this tag...

There was an error processing your information. Please try again later.

Thanks! We'll email you when relevant content is added and updated.


Share this item with your network: