DYNAMIC question

I have a question on DYNAMIC.
I receive files from different departments and i do not know the file lengths, so i defined it as dynamic like this:

DEFINE DATA
LOCAL
1 #RECORD (A) DYNAMIC
1 #LENGTH (I4)
1 #KEY (A10)
END-DEFINE
*
READ WORK FILE 1 #RECORD GIVING LENGTH #LENGTH
DISPLAY #LENGTH
END-WORK
END

the above program gives me the length of each record read as 1467.

BUT, when I change the program a bit I have problems.

READ WORK FILE 1 #RECORD
MOVE SUBSTRING(#RECORD,1,10) TO #KEY
DISPLAY #KEY
END-WORK
END

This gives me the error NAT1326 RANGE SPECIFIED IN SUBSTRING OPTION IS OUTSIDE FIELD.

How can i specify the record to be dynamic since i do not know its length and then use that record for manipulation?

Any suggestions are appreciated!!

Thanks!

Obviously, #record is shorter than 10 bytes sometimes.

But anyway: Why don’t you use a simple move.

MOVE #record to #key

if #key is 10 bytes long, you’ll always get the first ten bytes of #record. And you’ll get no error if #record is shorter than 10 bytes.

Sorry Matthias, the record length depends on which department is sending me the file. All the records sent by each depeartment will be FB.

I have to process the file depending on how long the record is. for example,

if the record length is 8 then perform A
if the record length is 3 then perform B
otherwise perform C

I was only accessing the first 10 bytes as an example.

I am just not able to access any data in the record and I was wondering what I was doing wrong.

Sanjay

Hmmm. Another question: Do you know the system variable *Length? Maybe you can use the following code:

decide on first value of *LENGTH(#record)
value 8
perform A
value 3
perform B
none value
perform C
end-decide

That is the weird part.

READ WORK FILE 1 #RECORD GIVING LENGTH #LENGTH
DISPLAY #LENGTH

when I run this, I get the display for #length as 1467

IF I run this:

READ WORK FILE 1 #RECORD
DISPLAY *LENGTH(#RECORD)

then the display for *LENGTH(#RECORD) is 0… zero, this is why I am not able to access any data.

I read and re-read the natural manual but am unable to figure out what is wrong.

If *LENGTH(#RECORD) is ZERO then it is almost like there is no data in the record but GIVING LENGTH displays 1467. aaarrrgggghhhh.

I am almost at my wits end on this one.

Here is the actual program and the display from it.

0010 DEFINE DATA
0020 LOCAL
0030 1 #RECORD (A) DYNAMIC
0040 1 #LENGTH (I4)
0050 1 #TEMP (A20)
0060 END-DEFINE
0070 READ WORK FILE 1 #RECORD GIVING LENGTH #LENGTH
0080 DISPLAY #LENGTH *LENGTH(#RECORD)
0090 END-WORK
0100 END

OUTPUT

Page 1
#LENGTH LENGTH


   1467           0
   1467           0
   1467           0
   1467           0
   1467           0
   1467           0
   1467           0
   1467           0
   1467           0
   1467           0

I believe that “1467” is your logical record length (LRECL). I can duplicate your results if I read a file of blank records; I suggest that you check your JCL, especially the DD for CMWKF01. Also, try changing your DISPLAY statement to

PRINT #LENGTH *LENGTH(#RECORD) #RECORD

to verify the contents of the record.

Now I understand your problem. But this seems to me like mainframe-specific stuff. Because your code doesn’t run on my testing system (Windows).
Sorry, I hope Ralph Zbrog can help you…

Hi Sanjay;

As noted by Ralph, GIVING LENGTH is pretty silly unless you have TYPE UNFORMATTED, which is basically just a character string. Otherwise, you just get the lrecl.

As to why *length is zero… that is another matter. Are you sure you have the workfile defined correctly?

steve

Sanjay, what results do you receive, if you change from dynamic to fixed length #RECORD (e.g. (A10)). If the record read is longer, it does not matter for this testing, if the record is smaller, ir does not matter for this testing, too.

What is displayed in #RECORD then? All blanks or reliable value? If all blanks, check your jcl, if reliable value: I don’t know :?

From the NATURAL documentation:

"[i]Large and Dynamic Variables can be written into work files or read from work files using the two work file types PORTABLE and UNFORMATTED. For these types, there is no size restriction for dynamic variables. However, large variables may not exceed a maximum field/record length of 32766 bytes.

Reading a dynamic variable from a PORTABLE work file leads to resizing to the stored length.[/i]"

… which is from the NATURAL OpenSystems documentation and doesn’t help here :wink:

This one is kinda hard to work out from the documentation…the dynamic variable has to be set BEFORE the read. This trick works well with any FB input - the first read figures out the LRECL, then allocates the dynamic variable it needs. If you were using a VB file, you might need to read the whole file to determine the longest record and allocate the dynamic accordingly.


DEFINE DATA                                                
LOCAL                                                      
1 #RECORD (A) DYNAMIC                                      
1 #LENGTH (I4)                                             
END-DEFINE                                                 
*                                                          
READ WORK FILE 1 ONCE #RECORD GIVING LENGTH #LENGTH        
EXPAND DYNAMIC #RECORD TO #LENGTH                          
MOVE ALL ' ' TO #RECORD UNTIL #LENGTH                      
CLOSE WORK FILE 1                                          
*                                                          
READ WORK FILE 1 RECORD #RECORD GIVING LENGTH #LENGTH      
 DISPLAY #LENGTH *LENGTH(#RECORD)                         
END-WORK                                                   
END                                                        
                                                           

If you are leaning towards Douglas’ solution for a recfm=VB dataset and if the number of records in the file may be too many, you also have the option of reading the dataset’s DCB (using IKJEFTSR and LISTDS) and pass on the LRECL which should be the largest record for that dataset to initialize your dynamic alpha variable upon start of the program.