Wednesday, November 13, 2024

Using Fields BiF to update Subfile

When I use RPG Update operation code I tend to use the %FIELDS Built in Function, BiF, with it. The %FIELDS allows me to list the file fields I want to update, all other are unchanged. As I like my code to be "self-documenting" I use it a lot if I am not updating all of the fields in the record, this allows other developers to learn that I was only interested in updating the fields listed.

These days almost all of my data file I/O is with SQL, which leaves me using RPG I/O with just display and printer files. I cannot update a record in a printer file, therefore, this post is exclusively about display files, and subfiles in particular.

Why do I feel the need to write about this when %FIELDS and subfiles have been around for several releases. It is because of a change that is in IBM i 7.5. In this release it is no longer possible to compile a program that uses the %FIELDS when updating a subfile without some extra work. But before I go into that let me show my example code, starting with the DDS source for the display file:

01 A                                      DSPSIZ(24 80 *DS3)
02 A                                      INDARA
    *-------------------------------------------------------------------------
03 A          R SFL01                     SFL
04 A            ZRRN           3S 0H
05 A            FLD001        10A  O  2  4ALIAS(SUBFILE_FIELD_1)
06 A            FLD002        10A  O  2 16ALIAS(SUBFILE_FIELD_2)
07 A            FLD003        10A  O  2 28ALIAS(SUBFILE_FIELD_3)
    *-------------------------------------------------------------------------
08 A          R CTL01                     SFLCTL(SFL01)
09 A                                      SFLSIZ(0010)
10 A                                      SFLPAG(0010)
11 A                                      OVERLAY
12 A  31                                  SFLDSP
13 A  30                                  SFLDSPCTL
14 A N30                                  SFLDLT
15 A                                  1  4'Field 1     Field 2     Field 3   '
16 A                                      DSPATR(UL)
17 A                                      DSPATR(HI)

This display file has been stripped down to the "bare bones", a lot of the things I would add to display files I have omitted so that you can clearly see what is needed.

Line 2: I always use the indicator area/data structure as it is a better way to name your display file indicators in your RPG programs.

Lines 3 – 7: The subfile consists of these four fields. The first, ZRRN, is the subfile relative record number which I have hidden from displaying. The other three fields I have given aliases to, I will be using the alias names in my RPG program as they are more descriptive than the system field names.

Lines 8 – 17: The subfile control record. The subfile can contain a maximum of ten records, and will show all ten on the display file screen.

The RPG program is pretty much "bare bones" too:

01  **free
02  ctl-opt option(*srcstmt) dftactgrp(*no) ;

03  dcl-f TESTDSPF workstn indds(Dspf) sfile(SFL01:ZRRN) alias ;

04  dcl-ds Dspf qualified ;
05    SflDspCtl ind pos(30) ;
06    SflDsp ind pos(31) ;
07  end-ds ;

08  LoadSubfile() ;

09  exfmt CTL01 ;

10  chain 1 SFL01 ;
11  SUBFILE_FIELD_1 = 'Changed' ;
12  SUBFILE_FIELD_2 = 'Changed' ;
13  SUBFILE_FIELD_3 = 'Changed' ;
14  update SFL01 %fields(SUBFILE_FIELD_1) ;

15  exfmt CTL01 ;

16  *inlr = *on ;

Line 2: My favorite control option *SRCSTMT, and I need not to be in the default activation group as I am calling a procedure.

Line 3: Definition of the display file I showed the source code for above. Notice how there is the ALIAS keyword, this allows me to use the alias name of the fields in the display file.

Lines 4 – 7: The indicator area of the display file is mapped to an indicator data structure in the RPG program.

Line 8: I load the subfile in this procedure. I will show and describe it below.

Line 9: EXFMT displays the subfile.

Lines 10: When I chain the subfile using "1" as the key I retrieve the first subfile record.

Lines 11 – 13: Moved new values to all of the fields in the subfile.

Line 14: Update the subfile. Here I am using the %FIELDS BiF to only update the first subfile field.

I promised to show the procedure to load the subfile:

17  dcl-proc LoadSubfile ;
18    Dspf.SflDspCtl = *off ;
19    Dspf.SflDsp = *off ;
20    write CTL01 ;
21    Dspf.SflDspCtl = *on ;
22    Dspf.SflDsp = *on ;

23    ZRRN = 1 ;
24    SUBFILE_FIELD_1 = 'Original' ;
25    SUBFILE_FIELD_2 = 'Original' ;
26    SUBFILE_FIELD_3 = 'Original' ;
27    write SFL01 ;
28  end-proc ;

Lines 18 – 22: I initialize the subfile, and then set the indicators so that the subfile and subfile control records will be displayed.

Lines 23 – 26: Move values to the subfile's fields.

Line 24: Write the subfile.

I am working on a partition that has IBM i 7.5 installed, and when I compile this RPG program it does not compile. When I look in the compile listing, I find:

  *RNF7214 30      1 %FIELDS is not allowed for a subfile record.

As I mentioned before in IBM i 7.5 it is no longer possible to use %FIELDS BiF with subfile records.

How can I overcome this and continue to use %FIELDS?

I could compile the program with the "Target release" parameter, TGTRLS, as V7R4M0 or lower. I do not like doing that as it could mean a lot of the newer RPG enhancements, I use, may not be compatible with IBM i 7.4.

With IBM i 7.5 a new environmental variable was introduced. QIBM_RPG_DISALLOW_SUBFILE_BIF_FIELDS allows me to control if I want to use BiFs with subfiles. I would not want to add this at a system level, just at a job level. Before I compile my program again, I need to add it:

  ADDENVVAR ENVVAR(QIBM_RPG_DISALLOW_SUBFILE_BIF_FIELDS) VALUE('N')

Now the program compiles without error. I do not need this environmental value to run the program, just to compile it.

As the environmental value is at the job level when this job ends it is deleted.

I can now call my successfully created program.

The first time the subfile is displayed, line 9, the following is displayed:

   Field 1     Field 2     Field 3   
   Original    Original    Original

After I displayed the subfile for the first time I chained the record, changed the contents of its fields, and updated subfile using %FIELDS to update the first field. Which means when the subfile is displayed a second time, line 15, this is displayed:

   Field 1     Field 2     Field 3   
   Changed     Original    Original

The first column has been changed.

Seeing the name of the environmental value, QIBM_RPG_DISALLOW_SUBFILE_BIF_FIELDS it makes me wonder if there are other BiFs I can control the use of with subfiles.

 

This article was written for IBM i 7.5, and should work for some earlier releases too.

No comments:

Post a Comment

To prevent "comment spam" all comments are moderated.
Learn about this website's comments policy here.

Some people have reported that they cannot post a comment using certain computers and browsers. If this is you feel free to use the Contact Form to send me the comment and I will post it for you, please include the title of the post so I know which one to post the comment to.