ibmi-brunch-learn

Announcement

Collapse
No announcement yet.

File definition in a sub procedure

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • File definition in a sub procedure

    I have a sub procedure that I want to define a file within a sub procedure and then chain to that file and populate an external data structure based on the file being chained to. My preference, if possible, is to prefix the fields in the externally defined data structure.


    DCL-DS dsPrdmstl1 Extname('PRDMSTL1') END-DS;

    Chain prmPrdno Prdmstl1 dsPrdmstl1;


    I get the following syntax error

    RNF7595


    The result data structure does not include a subfield in position 1 for a record format.

    20

    Cause . . . . . : A result data structure is specified for an input operation by file name but does not contain a subfield data structure for at least one of the record formats in that file. The data structure is ignored.

    Recovery . . . : For an input operation by file name, the result data structure must contain one subfields data structure corresponding to each record format in the file. These subfield data structures must be defined using LIKEREC or LIKEDS such that the definition of the subfields is based on the fields in the input record. In addition, each subfield data structure must be at the beginning of the result data structure. Compile again.
    How can I populate a data structure with the fields prefixed in a chain operation in a subprocedure

  • #2
    Using extname means that the data structure is not qualified.
    So when reading the file the fields in the data structure will be filled with the values from the record.

    So you could do something like this:

    DCL-DS dsPrdmstl1 Extname('PRDMSTL1') END-DS;
    Chain prmPrdno Prdmstl1;
    return dsPrdmstl1;

    Comment


    • #3
      Instead of using the file name on the CHAIN, try using the record format name (although Peder is correct in that the way you have it coded, there is no need for the data structure name to be on the chain). If you want to prefix the field names in the data structure, you have to add the PREFIX keyword to the data structure definition.

      Comment


      • #4
        Try adding *INPUT to the EXTNAME keyword. The default type for EXTNAME isn't exactly the same as *INPUT, and the compiler requires a *INPUT DS. The LIKEREC keyword defaults to *INPUT, so you don't need to be specific with LIKEREC.

        Comment


        • #5
          Originally posted by Barbara Morris View Post
          Try adding *INPUT to the EXTNAME keyword. The default type for EXTNAME isn't exactly the same as *INPUT, and the compiler requires a *INPUT DS. The LIKEREC keyword defaults to *INPUT, so you don't need to be specific with LIKEREC.
          This works. As always, thanks. Just curious why PREFIX keyword works with EXTNAME but not LIKEREC.

          Comment


          • #6
            I don't recall exactly why PREFIX isn't supported for LIKEREC, but it's probably for a couple of reasons. First, LIKEREC picks up the PREFIX from the file definition - I guess we thought that if you wanted to add or remove a prefix for the field names, you'd want it for the file itself. And second, PREFIX is often used to make the program field names unique, and a LIKEREC data structure is qualified, so there's no need to make the names unique.

            Comment


            • #7
              Yeah, I'm curious -- why would you want PREFIX on a LIKEREC? What value would it provide?

              Comment


              • #8
                Originally posted by Barbara Morris View Post
                PREFIX is often used to make the program field names unique, and a LIKEREC data structure is qualified, so there's no need to make the names unique.
                Makes sense

                Comment


                • #9
                  I read an article yesterday about using the STATIC keyword when defining files in a sub procedure. It stated that when a file is opened in a sub procedure using STATIC it stays opened until the activation group ends or the file is manually closed. In the latter case, does this mean you have to specify the USROPN keyword along with STATIC and then check to see if it is open using %OPEN and then open it if %OPEN is = ‘0’? I assume that to tell the sub procedure you want to close the file, you have to call it one last time and include a parameter in the PI to tell it to close the file. If so, what about the parameters the sub procedure receives, pass dummy values on the last pass (except for the parm that signals to close the file)?

                  What would be the best way to close the file opened using STATIC, aside from waiting for the activation group to end?

                  Comment


                  • #10
                    Greg, I quit using PREFIX and started using QUALIFIED files, and I have been very pleased with the results.

                    When IBM adds a new feature to the RPG compiler, they do so for a reason. That’s why I try to learn new techniques. I hope they’ll improve the quality of the source code I write. One relatively new feature that I do not see widely used is the qualified file. In the following paragraphs,

                    Comment


                    • #11
                      Originally posted by gregwga50 View Post
                      What would be the best way to close the file opened using STATIC, aside from waiting for the activation group to end?
                      This is probably the main reason I still declare files at the global level in modules. I write a subprocedure to close a file or the files.

                      Comment


                      • #12
                        Originally posted by gregwga50 View Post
                        I read an article yesterday about using the STATIC keyword when defining files in a sub procedure. It stated that when a file is opened in a sub procedure using STATIC it stays opened until the activation group ends or the file is manually closed. In the latter case, does this mean you have to specify the USROPN keyword along with STATIC and then check to see if it is open using %OPEN and then open it if %OPEN is = ‘0’? I assume that to tell the sub procedure you want to close the file, you have to call it one last time and include a parameter in the PI to tell it to close the file. If so, what about the parameters the sub procedure receives, pass dummy values on the last pass (except for the parm that signals to close the file)?
                        You don't have to manually control how the file is opened -- just how it is closed. Remove USROPN from the DCL-F, and the system will manage opening it. You can still use CLOSE to manually close it.

                        One way to handle parameters would be to make them all *NOPASS, and if the parameters required for a "normal" file operation aren't passed, you close the file.

                        Originally posted by gregwga50 View Post
                        What would be the best way to close the file opened using STATIC, aside from waiting for the activation group to end?
                        Personally, I prefer to wait for the activation group to end. I think that's a lot more elegant than manually doing calls to close the files. The caller shouldn't need to know how the subprocedure works -- and by forcing it to call a 2nd time to close the file, you are requiring at least some knowledge of that.

                        What objection do you have to leaving the file open until the activation group ends?

                        Comment

                        Working...
                        X