-1

How to delete a record from a subfile in RPGLE, the record is not written on to a Physical file, so deleting the record from the PF and reloading the subfile will not do, is there any other way to achieve this?

Kunal Roy
  • 729
  • 3
  • 11

1 Answers1

3

The short answer is DELETE.

Subfiles work just like any other non-keyed file. You access the records by relative record number. There is that READC op code, but that can confuse things, and does not always return what you might expect. There are a lot of DDS things that were useful in the days that a 5250 session could be accessed via a 300 baud modem and the Async workstation controller. No-one does that these days.5250 is an extremely efficient protocol, so with today's bandwidth you don't need the extra complexity in your code to handle a slow connection. These days they are all fast relative to what 5250 considered slow.

That being said. There are a couple ways to delete a record from a subfile. If you know the record number of the record you want to delete, you could just say something like this:

dcl-s rrn Int(5);

rrn = /* record to delete */
delete rrn subfile;

Or if you don't know the record number of the record to delete you could read through the subfile records to find it, and delete it. Like this:

dcl-s ix Int(5);
dcl-s max_subfile Int(5);
...
for ix = 1 to max_subfile;
  chain ix subfile;
  if /* the record read is the one to delete */
    delete subfile;
  endif;
endfor;

Some caveats: I don't like to delete records from the subfile as it leaves a gap in the relative record numbers that you have to deal with, and I like to process through a subfile using a for loop with a chain rather than READC. That way I never have to deal with SFLNXTCHG. It simplifies the code. I also persist changes to the backing physical file immediately. But if that is not an option, I have used an array to do the "delete". The approach is to copy the records from the subfile to an array, skipping the deleted records. Then clear and reload the subfile from the array. This way you have no gaps in the relative record number of the subfile. It looks something like this:

// Copy subfile to an array, skipping the deleted records
jx = 0;
for ix = 1 to sfl_max;
  chain ix subfile rec;
  if /* record not deleted */
    jx += 1;
    array[jx] = rec;
  endif;
endfor;

// clear the subfile
sflclear = *On;
write sflctl;
sflclear = *Off;

// load subfile from the array
for ix = 1 to jx;
  rec = array[ix];
  write subfile;
endfor;
sfl_max = jx;

One last comment. If you don't want to use an array to temporarily hold good subfile records, you could just as easily use another subfile.

jmarkmurphy
  • 11,030
  • 31
  • 59
  • For my scenario loading the subfile data onto an array (not loading the deleted rec) and then clear /Loading the subfile from the array is the best option. Thanks for the tip. – Kunal Roy May 22 '20 at 03:51