A basic question about workfiles and type checking...

I have forgotten something very basic.

When reading a flat file as a workfile, there are two ways this can be handled.

The first method causes Natural to perform automatic type checking. If, for example, the third field in the workfile is defined as N7, and the contents of this field on a record on the flat file are

Check the documentation for more detail (http://techcommunity.softwareag.com/ecosystem/documentation/natural/nat425mf/sm/readwork.htm), but here’s the short version.

Start with some data definitions.

DEFINE DATA LOCAL 
1 #FIELDS 
  2 #NAME (A25) 
  2 #ADDRESS (A25) 
  2 #SALARY (P9.2) 
  2 #AGE (N2) 
                   1 REDEFINE #FIELDS 
  2 #BLOCK (A58) 
1 #OTHER 
  2 #AMOUNT (P7.2) 
  2 #ALPHA (A10) 
END-DEFINE

The “vast majority” of examples that you see should be either

R1. 
READ WORK 1 RECORD #FIELDS 
END-WORK

or

R2. 
READ WORK 1        #BLOCK 
END-WORK

In the R1 loop, a list of fields is read. The RECORD option tells Natural not to verify the contents of numeric fields, so this will execute faster than with the default SELECT clause. (How much faster is dependent on the number of numeric fields.)

In the R2 loop, a single alpha field is read, so the negative effect of the SELECT clause on execution time will be minimal (likely unnoticeable, even for large files). Adding the RECORD clause would help, but not much.

At compile time, the group name #FIELDS is translated into a list of contiguous fields. If the fields are not contiguous in memory, the SELECT clause must be used.

R3. 
READ WORK 1        #NAME 
                   #AGE 
                   #AMOUNT 
END-WORK 
* 
R4. 
READ WORK 1 RECORD #NAME 
                   #AGE 
                   #AMOUNT 
END-WORK

R3 will execute, but R4 will not even compile.

The documentation for READ WORK FILE has always been a bit misleading.

For example,

"If RECORD is specified, all fields in each record read are made available for processing. An operand list (operand1) corresponding to the layout of the record must be provided. "

The above statement seems to indicate that the operand list for the RWF must be the same as for the WWF that created the record (and I have found this interpretation at a large percentage of the shops where I have taught Natural). That this is not true can be seen below:

DEFINE DATA LOCAL
1 #REC
2 #A (A3)
2 #B (A6)
2 #C (A5)
*
1 #RECORD (A14) INIT <‘AAAAABBBBBBBCC’>
*
1 #AA (A4) INIT <‘AAAA’>
1 #BB (A3) INIT <‘BBB’>
1 #CC (A5) INIT <‘CCCCC’>
END-DEFINE
*
INCLUDE AASETCR
INCLUDE AATITLER
*
WRITE WORK FILE 1 #AA #BB #CC
*
READ WORK FILE 1 RECORD #REC /* #A #B #C OR #AA #BB #CC
WRITE 5T ‘=’ #AA ‘=’ #BB ‘=’ #CC // 5T ‘=’ #REC //
5T ‘=’ #A ‘=’ #B ‘=’ #C
LOOP
*
END

PAGE #   1                    DATE:    JAN 20, 2009
PROGRAM: RWF01                LIBRARY: INSIDE

#AA: AAAA #BB: BBB #CC: CCCCC

#REC: AAA ABBBCC CCC

#A: AAA #B: ABBBCC #C: CCC

You do not even need the same number of fields in the list for RWF; as shown below

DEFINE DATA LOCAL
1 #REC
2 #A (A3)
2 #B (A6)
2 #C (A5)
1 #RECORD (A14) INIT <‘AAAAABBBBBBBCC’>
*
1 #AA (A4) INIT <‘AAAA’>
1 #BB (A3) INIT <‘BBB’>
1 #CC (A5) INIT <‘CCCCC’>
END-DEFINE
*
INCLUDE AASETCR
INCLUDE AATITLER
*
WRITE WORK FILE 1 #AA #BB #CC
*
READ WORK FILE 1 RECORD #REC /
#A #B #C OR #AA #BB #CC
WRITE 5T ‘=’ #AA ‘=’ #BB ‘=’ #CC // 5T ‘=’ #REC //
5T ‘=’ #A ‘=’ #B /
‘=’ #C
LOOP
*
END
PAGE # 1 DATE: Jan 20, 2009
PROGRAM: RWF02 LIBRARY: INSIDE

#AA: AAAA #BB: BBB #CC: CCCCC

#REC: AAA ABBBCC

#A: AAA #B: ABBBCC

Now for some fun. Go back to the first program, RWF01 and change the RWF statement as shown below:

READ WORK FILE 1 RECORD #A #B #C /*OR #AA #BB #CC

This will not compile, even though #REC is the Group Name for the three fields #A #B and #C.

This is the one place in Natural (so far as I know) where a Group Name is not an abbreviation for several field names. In version 1 of Natural and I seem to recall 2.1 a well, you could not have a group name in a RWF RECORD. The reason is quite simple. RWF RECORD does not “pay attention” to fields. At compile time it basically looks at the argument (single variable or group name) to figure out a starting address and a length. At execution time it picks up the appropriate number of characters from a record and “plops” it down at the start address. I guess that many users wanted to be able to have a RWF and a WWF with the same Group name, hence the syntax change was made. In the WWF the group name is indeed an abbreviation, in RWF RECORD the group name plays a role at compile time, but not at execution time.

This can get very confusing when Group Arrays are involved. Thus:

1 #group (3)
2 #a (a3)
2 #b (a3)
2 #c (a3)

WWF #group () followed later by RWF RECORD #group () will not do what you might expect it would.

Later today I will post an article from Inside Natural, on the Natural Basics - Inside Natural thread, that describes what happens.

steve