Wednesday, April 18, 2018

Sending your own program created messages to the error subfile

filling the error subfile, errsfl, with program generated message

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.

1 comment:

  1. Exception handling is the most important

    ReplyDelete

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.