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.
Hi Simon,
ReplyDeleteI found the idea of having selective field update capabilities for subfile records very fascinating.
But it seems that also before 7.5 the %fields functions support for subfiles was not stable/reliable - at least if I read this here correctly:
https://www.ibm.com/docs/en/i/7.5?topic=wds-ile-rpg-changes
What do you think about it?
I have not seen that article on IBM's website.
DeleteI have been using %FIELDS with any update op-code for years, even decades without ever encountering an error with it. Could I have just been lucky? Possibly, but the number of times I have used it in a subfile program I guess I would have seen an issue at least once.
As for reasons when you should not need it I think I proved the second reason unfounded.
If you use DSPATR(&Variable) in the screen DDS and use %fields(Variable) in your RPG to control field Highlight, Protect, Non-Display, etc.. attributes.
ReplyDeleteYou can create a situation where the input/output layout are different lengths and the screen subfile data will shift to the right on screen after issuing the update %fields.