Thursday, November 7, 2013

Renaming one field in a file using EXTFLD

In September I wrote about a problem I had encountered where I had to rename one field in a file, and not rename the other fields, in Renaming one field in a file in RPG. I achieved this using RPG's Input specification, I-spec. BlueBull posted a comment on the post explaining that I could have used the EXTFLD keyword in the Data Definition specification, D-spec, to do the same.

In this post I will show how I would use the EXTFLD to rename a field, and determine if it would fit the scenario I used in my previous post.

The file I will be using in this example, TESTPF, has 3 fields, see below. I will be renaming the first field, and wanting to leave the others with their original names.

01 A          R TESTPFR
02 A            F1             9A
03 A            F2             1A
04 A            F3             1A

The EXTFLD keyword is used to rename a subfield in an externally described data structure, therefore, I need to create an external data structure for my file and then read from the file directly into the data structure.

Let me show the program I created and then explain it:

01 FTESTPF    UF   E             DISK
02 D File1         E DS                  extname(TESTPF:*INPUT)
03 D   wF1         E                     extfld(F1)

04 D New_F1          S             10
    /free
05     read TESTPFR File1 ;
06     if not(%eof) ;
07       New_F1 = wF1 ;
08     endif ;

09     wF1 = 'A' ;
10     update TESTPFR File1 ;

On line 1 I have defined the file, TESTPF, as update. I will explain why I have later.

Line 2 is where I define the external data structure, File1. It has an 'E' in the External field of the D-spec, position 22, to denote that is defined externally. Unlike in previous examples there are two values in the EXTNAME keyword. The first is, obviously, the file name. The second defines which fields in the "external record" are used. If this second parameter is not given then the program will not compile, giving the error RNF7595. Do not worry that I have used *INPUT, as you will see late it is still possible to output to the file.

Line 3 is where I have used the EXTFLD keyword. The name of the field in the file, F1, is given within the EXTFLD keyword. The name I will be using for this field, WF1, is given in the Name part of the D-spec. Notice that there is an 'E' in the External field, to indicate that the field is defined externally.

When I read TESTPF, line 5, I have to read it into the data structure File1. The rename happens in the external data structure, not with the file. Therefore, if I had just READ the file then field F1 would still be known as F1.

As end of file was not encountered I move the value of wF1 to New_F1, on line 7.

So now I can show, on lines 9 and 10, that the *INPUT in the EXTNAME keyword does not stop me from updating the file. On line 9 I change the value in wF1. On line 10 I update the file using the values in the data structure. If I had just UPDATE without the data structure then the file would have been updated with the value in F1, rather than what is in wF1.

Can this be used in the scenario described in that previous post?

I was asked to quickly modify a program. The program currently uses a file, I'll call it FILE1, and the modification was to add a second file, FILE2 to it. If the user selects to search for a certain type of information the the program would uses FILE1, if they want to search for a different type of information the program would need to use FILE2.

All of the fields in FILE1 and FILE2 have the same names and attributes, except for the Part number field. The Part number field, PART, in FILE1 is 20 long, in FILE2 it is 15.

The way I overcame the problem was to rename the PART field in the second file to PART_2 in the Input specifications. After reading FILE2 I moved the value in PART_2 to PART.

Using the EXTFLD I was not able to do this. The program would not compile as the two PART fields, in FILE1 and FILE2, are different. I would need to rename the PART field in FILE2 to something else to allow the program to compile. I do not want to use the prefix keyword as it would rename all the fields in FILE2. Therefore, I would need to rename PART field in FILE2 in the Input specification to allow the program to compile. By doing that I no longer have the need to use the EXTFLD.

 

This article was written for IBM i 7.1, and it should work with earlier releases too.

7 comments:

  1. You could declare your files as qualified and avoid the ambiguity altogether.
    -kh

    ReplyDelete
    Replies
    1. I am still not convinced on using the QUALIFIED on files in the F-spec.

      I assume if I need to change one file to another, e.g. logical file FILE1A to FILE1B for a better sort, then if I was using the QUALIFIED I would have to change everywhere a field in FILE1A was used to change it to FILE1B. .

      Is that true?

      Delete
  2. I don't like renaming fields, unless I really, really, really, really have to.

    It's like using multi-member files, avoid it like the plague.

    ReplyDelete
  3. To rename only one field, I agree with Simon and would use (and have used) the I specification. I would rather key one line of code, than setting up the data structure, and then having to make the I/O to that file using DS I/O.

    If you are in a big program, and there are many lines of code that access the file, you would have to remember to change all of them to use the DS to get the field renamed. Otherwise, sometimes the system will read the records into the DS, and other times it will not, and if you have that field defined somewhere else in the program, its contents will be overwritten.

    Another way to rename fields in a file would be to use the PREFIX() keyword on the F spec.

    ReplyDelete
  4. In i 6.1 and later, there is a way to do it. The trick is to keep the RPG compiler from defining I-specs for the files, so the same field name won't be defined with conflicting parameters. Then you can use EXTFLD to rename the field in the data structures.

    One way to do this is to use the QUALIFIED keyword on the F-specs. This will prevent the generation of I- and O-specs. All I/O for a qualified file must be done through data structures. Also, if you specify a record format name, you must qualify it with the file name; i.e., TESTPF.TESTPFR, not just TESTPFR.

    ReplyDelete
  5. I used this approach to combine multiple key fields into one field.
    I then moved the single field to an array.
    When I needed to use the key fields, I moved a single array element back to the data structure and chained out to the file.
    This saved me having to create multiple arrays, and have multiple moves back and forth.

    ReplyDelete
  6. How can I do this in free format? Can't find any examples and keep getting errors;

    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.