Read work file with a variable length record

I have a work file record I am trying to read. It is a variable length record archive of a database file over several years, so it cannot be loaded back in to Adabas easily. It contains 4 fixed fields: field1, field2, field3, field4 and 2 mu fields (field 5 p9(1:50) and field6 a4(1:50)). I’m having difficulty reading the record properly. I mostly get invalid data for numeric input field. There are no delimiters in the record. I can see a 1 byte mu-count fields in the dump of the file for field5 and field6

How do I read this as a variable length work file please. thank you
Kevin

Assuming field1 to field4 are fixed length and you don’t run into a shifted data issue here
right away you will do so as soon as field5 does not come with all 50 elements.

You will have to define the record as an array of B1 fields, “parse” the record,
find out how many field5 elements there are, move them to an array of P9
fields in the correct length and use that instead of the data out of the work file
record directly.

Then go on parsing as, assuming the record comes compressed, the field6 MU will
immediately follow field5, etc.

The format sounds like the output of the Adabas decompression routine. You should be able to read the file with the Adabas compression utility and load the resulting file with the Adabas load utility into a database file.

Try this sample (It works for me):


0010 DEFINE DATA LOCAL
0020 1 #W-RECORD1 (A32760)
0030 *
0040 1 #W-RECORD
0050   2 #FIELD1 (A) DYNAMIC
0060   2 #FIELD2 (A) DYNAMIC
0070   2 #FIELD3 (A) DYNAMIC
0080   2 #FIELD4 (A) DYNAMIC
0090   2 #FIELD5 (B9/1:*)
0100   2 #FIELD6 (A4/1:*)
0110 *
0120 1 #W-F5   (B1)
0130 1 #W-F6   (B1)
0140 *
0150 1 #I      (P3)
0160 *
0170 1 #W-LIMF5  (P5)
0180 1 #W-LIMF6  (P5)
0190 *
0200 1 #LEN-F1 (N3) CONST <2>       /* LENGTH OF FIELD1
0210 1 #LEN-F2 (N3) CONST <3>       /* LENGTH OF FIELD2
0220 1 #LEN-F3 (N3) CONST <8>       /* LENGTH OF FIELD3
0230 1 #LEN-F4 (N3) CONST <4>       /* LENGTH OF FIELD4
0240 1 #LEN-F5 (N3) CONST <9>       /* LENGTH OF FIELD5
0250 1 #LEN-F6 (N3) CONST <4>       /* LENGTH OF FIELD6
0260 *
0270 1 #STRT-F1 (P5)                /* ADDRESS OF FIELD1
0280 1 #STRT-F2 (P5)                /* ADDRESS OF FIELD2
0290 1 #STRT-F3 (P5)                /* ADDRESS OF FIELD3
0300 1 #STRT-F4 (P5)                /* ADDRESS OF FIELD4
0310 1 #STRT-F5 (P5)                /* ADDRESS OF FIELD5
0320 1 #STRT-F6 (P5)                /* ADDRESS OF FIELD6
0330 *
0340 END-DEFINE
0350 *
0360 * INITIALISE FIELDS
0370 *
0380 #STRT-F1 := 1                  /* ADDRESS OF FIELD1
0390 #STRT-F2 := #LEN-F1 + #STRT-F1 /* ADDRESS OF FIELD2
0400 #STRT-F3 := #LEN-F2 + #STRT-F2 /* ADDRESS OF FIELD3
0410 #STRT-F4 := #LEN-F3 + #STRT-F3 /* ADDRESS OF FIELD4
0420 *
0430 READ WORK 1 #W-RECORD1
0440 *
0450 * ====>    GET FIXED FIELDS 1 TO 4
0460 *
0470   #FIELD1 := SUBSTR(#W-RECORD1, #STRT-F1, #LEN-F1)   /* FIELD1
0480   #FIELD2 := SUBSTR(#W-RECORD1, #STRT-F2, #LEN-F2)   /* FIELD2
0490   #FIELD3 := SUBSTR(#W-RECORD1, #STRT-F3, #LEN-F3)   /* FIELD3
0500   #FIELD4 := SUBSTR(#W-RECORD1, #STRT-F4, #LEN-F4)   /* FIELD4
0510 *
0520   WRITE '=' #FIELD1 (AL=2)
0530   WRITE '=' #FIELD2 (AL=3)
0540   WRITE '=' #FIELD3 (AL=8)
0550   WRITE '=' #FIELD4 (AL=4)
0560 *
0570 * ====>    GET VAR FIELD 5
0580 *
0590   #STRT-F5  := #LEN-F4 + #STRT-F4        /* ADDRESS OF FIELD5
0600   #W-F5     := SUBSTR(#W-RECORD1, #STRT-F5, 1)   /* FIELD5 MU COUNTER
0610   #W-LIMF5  := #W-F5                     /* FIELD5 TOTAL OF OCURRENCES
0620   EXPAND ARRAY #FIELD5 TO (1: #W-LIMF5)
0630 *
0640   #STRT-F5 := #STRT-F5 + 1               /* REAL POSITION FIELD5
0650   FOR #I EQ 1 TO #W-LIMF5
0660     MOVE SUBSTRING(#W-RECORD1, #STRT-F5, #LEN-F5) TO #FIELD5(#I)
0670     WRITE '=' #FIELD5(#I)
0680     #STRT-F5 := #STRT-F5 + #LEN-F5
0690   END-FOR
0700 *
0710 * ====>    GET VAR FIELD 6
0720 *
0730   #STRT-F6  := #STRT-F5                  /*
0740   #W-F6     := SUBSTR(#W-RECORD1, #STRT-F6, 1)   /* FIELD6 MU COUNTER
0750   #W-LIMF6 := #W-F6                        /* FIELD6 TOTAL OF OCURRENCES
0760   EXPAND ARRAY #FIELD6 TO (1: #W-LIMF6)
0770 *
0780   #STRT-F6  := #STRT-F6 + 1             /* REAL POSITION FIELD6
0790   FOR #I EQ 1 TO #W-LIMF6
0800     MOVE SUBSTRING(#W-RECORD1, #STRT-F6, #LEN-F6) TO #FIELD6(#I)
0810     WRITE '=' #FIELD6(#I)
0820     #STRT-F6 := #STRT-F6 + #LEN-F6
0830   END-FOR
0840 END-WORK
0850 END

Note: lines 600-690 do the same that lines 740-830

One additional note here:

If this is an unload created with ADAULD then using ADACMP DECOMPRESS with that
unload file as the input to create a fixed length record (using the FORMAT option)
may be the easier route.