I have previously written about using the error subfile to display error messages, rather than the message subfile. Personally I like using the error subfile as it is another case of allowing the operating system to do the work for me.
Since publishing that article I have received messages asking how can people create their own error message text, in the RPG program, that is displayed in the error subfile.
Fortunately there is a simple way to do this that will work in either RPG in CL.
No matter which language I use the display file can be the same. Here is the display file I will be using in this example.
01 A CA03(03) 02 A ERRSFL 03 A INDARA 04 A R SCREEN 05 A 3 2'First field . .' 06 A FLD001 1A B 3 18 07 A 50 ERRMSG('This is an error+ 08 A message created just for+ 09 A this display file only') 10 A 4 2'Second field .' 11 A FLD002 1 B 4 18 12 A 51 ERRMSGID(CPF0131 QCPFMSG) 13 A 5 2'Third field . .' 14 A FLD003 1A B 5 18DFTVAL('Y') 15 A VALUES('Y' 'N') 16 A CHKMSGID(CAE9078 QCPFMSG) 17 A 5 24'Y,N' 18 A 6 2'Fourth field .' 19 A FLD004 1A B 6 18 20 A 52 ERRMSGID(CPF9898 QCPFMSG+ 21 A &MSGDATA) 22 A MSGDATA 78A P |
Line 2: I need to have the ERRSFL as a file level keyword for the error subfile to be used.
Line 3: Regular readers know how I always use the Indicator area in my display files as this allows me to give the display file's indicators names.
Line 4: This is the start of my display file record format.
Line 5 – 9: This is the definition of the first field, FLD001. I created the text for the error message for this field, lines 7 – 9, I entered the text that will be displayed when the error occurs.
Why does he do that?: I always code the error indicators starting at 50. There is no reason why you have to do the same.
Lines 11 and 12: Definition for the second field, FLD002. The error message for this field, CPF0131, comes from a message file, QCPFMSG.
Lines 14 – 17: As FLD003 has the value keyword, line 15, the validation is performed by the display file. I use the CHKMSGID to replace the default message with, what I consider, to be a more meaningful one. For more details see here.
Lines 18 – 22: FLD004 is the field we are interested in. The ERRMSGID on line 20 has a third value, the "message data" field. This field needs to be defined as a program-to-system field. All this means you need to put a P in the use field of the DDS. The program-to-system does not have be after the ERRMSGID, it just has to be in the same record format.
Why did I choose to use CPF9898? It is a special message that has no fixed text, and just one parameter, &1, that I can use the program-to-system field to fill.
Select Message Details to Display Message ID . . . . . . . . . : CPF9898 Message file . . . . . . . . : QCPFMSG Library . . . . . . . . . : QSYS Message text . . . . . . . . : &1. |
The RPG program is sraight forward.
01 **free 02 dcl-f TESTDSPF workstn indds(IndDs) ; 03 dcl-ds IndDs qualified ; 04 Exit ind pos(3) ; 05 Errors char(3) pos(50) ; 06 ErrFld001 ind pos(50) ; 07 ErrFld002 ind pos(51) ; 08 ErrFld004 ind pos(52) ; 09 end-ds ; 10 dow (1 = 1) ; 11 exfmt SCREEN ; 12 if (IndDs.Exit) ; 13 leave ; 14 endif ; 15 IndDs.Errors = *all'0' ; 16 if (FLD004 = ' ') ; 17 iter ; 18 elseif ((FLD004 >= 'A') and (FLD004 <= 'Z')) ; 19 MSGDATA = 'You have entered alphabetic character:' ; 20 elseif ((FLD004 >= '0') and (FLD004 <= '9')) ; 21 MSGDATA = 'You have entered number:' ; 22 else ; 21 MSGDATA = 'You have entered special character:' ; 21 endif ; 22 MSGDATA = %trimr(MSGDATA) + ' ' + FLD004 ; 23 IndDs.ErrFld004 = *on ; 24 enddo ; 25 *inlr = *on ; |
Line 1: It is 2018 so this program is written in totally free RPG.
Line 2: This is the definition of my display file, as I want to use the indicator area to communicate with my display file I need to give a indicator data structure, INDDS keyword.
Lines 3 – 9: This is the indicator data structure. The error indicators from the display file are defined on lines 6 – 8.
Line 11: The record format SCREEN is displayed.
Lines 12 – 14: If F3 is pressed then indicator Exit comes on. As I qualified the indicator data structure name I need to qualify the fields to become IndDs.Exit.
Line 15: This is something I discovered to help initialize indicators. Within the indicator data structure I define a character subfield that is the length of all the combined error indicators. I then start this subfield as the where the first indicator is found, position 50. By moving all character 0 to this subfield I initialize all of the error indicators at once.
I am not going to bother to validate the first three fields as it is not relevant to this subject.
Lines 16 – 23: This isn't really validation of the contents of FLD004 it is me showing how I can create different text in the MSGDATA field. I hope the code is all familiar to you all without me needing to explain it. I prefer using If and Elseif rather than Select.
What does this look like when the program is run?
I enter A in the fourth field and press Enter.
First field . . Second field . Third field . . Y Fourth field . A You have entered alphabetic character: A. |
Then the number 5.
First field . . Second field . Third field . . Y Fourth field . 5 You have entered number: 5. |
Finally an asterisk ( * ).
First field . . Second field . Third field . . Y Fourth field . * You have entered special character: *. |
Each occasion I am getting a different message generated by the program, rather than a message from the display file.
Now you can use this to display a message of your choice when an error occurs.
This article was written for IBM i 7.3, and should work for earlier releases too.
Exception handling is the most important
ReplyDelete