|
Hello Joel ! While going through your Subfile templet program I came across the remark pasted below. I found an answer which is why I though of informing you. Maybe it will help you too. // Can I read this from the DSPF somehow??? // This is the only change I would like to make: can I get the // display file itself to tell me what the SFLSIZE is? If so // I would not need to put it in as a constant. That way if you // change the subfile screen you don't have to remember to // change the constant in this program. for i=1 to sflSize ; There is an article (Id 14220) by Gary Guthrie dated May 1st 2002 where he has developed a utility to dynamically extract the subfile size using an API. I'm pasting it below incase you do not have access to it. Best regards Ewart PS: I have not yet got a program working using your templet & neither did the utility below work for me !!! Maybe you could try your luck. ------------------------------------------------------------------------------------------ Dynamic Subfile Processing Article Information Article ID: 14220 Pub: iSeries NEWS Dept: Load 'n' Go Utility Date: May 01, 2002 Related Topics: â APIs â Application Development â RPG â Utilities Other Articles By: Gary Guthrie by Gary Guthrie HOW MANY TIMES HAVE YOU HAD TO modify program logic because you changed a display file's subfile size characteristics? A simple change to the subfile size (DDS keyword SflSiz) or the number of records in a subfile page (DDS keyword SflPag), and you must also change the program to correctly perform its subfile-related tasks. For example, you may need to change routines that load the subfile, page through the subfile, or process the records in the subfile. Wouldn't it be nice if you could change a subfile's size characteristics without having to change program logic? With procedures RtvSflSize (Retrieve Subfile Size) and RtvSflPage (Retrieve Subfile Page) from service program DspFInfo, you can! These procedures let you design your applications to retrieve a subfile's size characteristics at runtime and then use this information, rather than hard-coded references, to control subfile-related routines. Behind the Scenes The key element behind procedures RtvSflSize and RtvSflPage is API QDFRtvFD (Retrieve Display File Description). This API lets you retrieve detailed display file information as specified in the DDS used in creating the file. Calling the API is easy enough. Simply call QDFRtvFD and pass the following parameters: Receiver variable â a variable-length output parameter to contain retrieved display file information Length of receiver variable â an input parameter that defines the length of the receiver variable Format name â an input parameter that defines the format of the receiver variable; the value must be DSPF0100 Qualified file name â an input parameter that defines the display file (along with its library) for which information is to be retrieved Error code â a variable-length input/output parameter that contains standard API error structure As you'll soon see, however, using the information the API returns is a somewhat intricate task. A quick look at QDFRtvFD's documentation (http://publib.boulder.ibm.com/pubs/html/as400/v5r1/ic2924/info/apis/qdfrtvfd.htm) shows that the API covers a lot of ground. Not only is the amount of information that QDFRtvFD returns voluminous, but a closer look shows that its organization is complex. The API returns all DDS details used in creating the file in a single variable, and mapping the information to numerous structures whose lengths and positions vary can be confusing. I can't possibly describe QDFRtvFD in its entirety here. Instead, I focus on basic steps for working with the API and show you how to extract the subfile size and subfile page values from the display file details that QDFRtvFD returns. You can use the techniques I demonstrate to extract any display file details of interest to you. Click here to download code Retrieving Subfile Size Information The first thing you need to know about QDFRtvFD's return variable is that it's organized into several categories. These include base file formats file formats record formats field formats keyword formats where-used formats As we analyze service program DspFInfo, you'll see that these categories constitute a series of linked structures containing display file details. The API's documentation includes charts that show you the formats and the structures they contain. You'll refer to these charts to determine how to traverse the various formats and structures to find the information of interest to you. Let's now examine a section of service program DspFInfo (Figure 1) to see how it's done. You can download the complete program at http://www.iseriesnetwork.com. The service program begins with procedure prototype definitions. Your applications use procedures RtvSflSize and RtvSflPage, whose prototypes appear at A. These procedures have the following parameters: display file name â a required parameter that identifies the display file for which to retrieve information display file library â a required parameter that identifies the library containing the display file (special values *CurLib and *LibL are allowed) record format name â a required parameter that identifies the subfile control record format name for which to retrieve information API error structure â a required parameter that communicates error information display mode â an optional param-eter that identifies the display mode for which to retrieve information (valid values are *DS3 and *DS4; *DS3 is the default) RtvSflSize and RtvSflPage call procedure RtvSflAttr (Retrieve Subfile Attribute) to retrieve the desired attribute. RtvSflAttr (at B) is internal to service program DspFInfo: application programs don't use it. The prototype for API QDFRtvFD appears next, at C. Procedures RtvSflSize and RtvSflPage appear after the prototypes. Each of these procedures simply determines the display mode (*DS3 or *DS4) for which to retrieve information, calls procedure RtvSflAttr to retrieve its respective attribute value, and returns the value to its caller. If an error occurs (BytesAvail <> NoAPIError), the procedure returns a value of zero. Procedure RtvSflAttr is the service program's workhorse. After defining the procedure interface and the variable to return to its caller, the procedure defines several structures used by API QDFRtvFD. To make it easier to correlate the procedure's structures with those that IBM documents, RtvSflAttr uses the names found in IBM's documentation for its structures' names. Data structure QDFFBASE (at D) maps the base file section. This structure always appears first in QDFRtv FD's return variable and marks the beginning point for navigation through that variable. In addition to a few basic display file details, QDFFBASE contains information you use in further navigating the return variable. For example, it contains the offset (subfield OffsetToQDFFINFO) to the file header section. Next, data structure QDFFINFO (at E) maps the file header section. RtvSflAttr doesn't use any of the many display file details housed in this structure, so they don't appear in the data structure definition. However, notice that QDFFINFO contains the first subfield, QDFFINFOLen. This subfield's value indicates the actual length of the file header section portion of QDFRtvFD's return variable. This value is necessary when calculating offset information used in navigation. At F, data structure QDFARFTE maps the record format table. RtvSflAttr needs only the record format name (subfield RcdFmtEntry) and, for navigational purposes, the offset to the record header section (subfield OffsetToQDFFRINF). Data structure QDFFRINF (at G) maps the record header section. Of the many display file details found in this structure, RtvSflAttr uses only two: subfields Flags and OffsetTo QDFFSFCR. Subfield Flags is a single byte whose bit structure determines certain subfile characteristics. Rtv SflAttr uses this subfield to determine whether a specified record format is a subfile control record. OffsetTo QDFFSFCR is necessary for navigation to the subfile control record portion of QDFRtvFD's return variable. At H, data structure QDFFSFCR maps the subfile control record. This structure contains many subfile control record details, including the subfile size and subfile page values within the QDFFSFHR substructure. Notice that this substructure is a two-element array: one element is for display mode *DS3, and is one for *DS4. Before RtvSflAttr can retrieve display file details with API QDFRtvFD, it must determine the size of the display file information and allocate the required amount of storage. Procedure RtvSflAttr's C-specs begin with a call to API QDFRtvFD (prototyped procedure RtvDspFDesc) and place into data structure RtvSizeInfo the first eight bytes of the display file information. After calling the API, subfield RtvSize reflects the amount of storage needed to contain all the display file details. The procedure allocates the required amount of storage to data structure QDFFBASE, which is based on pointer QDFFBASEPtr. After allocating storage, RtvSflAttr retrieves the display file details with yet another call to API QDFRtvFD and stores these details in data structure QDFFBASE. Using offsets and structure lengths, the procedure then navigates this data structure and extracts the requested information. As its first navigational step, the procedure calculates a pointer to the file header section (QDFFINFOPtr) by adding the offset to the file header section (OffsetToQDFFINFO) to the pointer to the base format (QDFF BASEPtr). RtvSflAttr then calculates a pointer to the first record format table entry (QDFARFTEPtr) by adding the file header section length (QDFFINFOLen) to the pointer to the file header section (QDFFINFOPtr). Next, RtvSflAttr searches through the list of record formats QDFRtvFD returns and looks for the record format specified by its caller. When the procedure locates the correct record format, control passes to subroutine ProcessRcdFmt. This subroutine first calculates a pointer to the record header section (QDFFRINFPtr) by adding the offset to the record header section (OffsetToQDFFRINF) to the pointer to the file header section (OffsetToQDFFINFO). Next, the subroutine tests bit 2 in the Flags subfield to determine whether the selected record format is a subfile control record. If it is, the subroutine calculates a pointer to the subfile control record (QDFFSFCRPtr) by adding the offset to the subfile control record (OffsetToQDFFSFCR) to the record header section pointer (QDFFRINFPtr). The subroutine finishes by extracting the requested attribute value for the specified display mode (*DS3 or *DS4). After extracting the requested information, RtvSflAttr releases the previously allocated storage. Finally, the procedure returns the requested attribute value to its caller. A Simple Application Example Figure 2 shows example application program fragments that demonstrate how you use service program DspFInfo. Keep in mind that this code is for demonstrative purposes and doesn't contain robust features such as error checking and testing for end-of-file conditions. In this example, the subfile is a page-at-a-time subfile. That is, the subfile page (SflPag) value is the same as the subfile size (SflSiz) value. However, you can easily adapt the technique for applications whose subfile size value is larger than the subfile page value. The C-specs begin by retrieving the subfile page value specified in the subfile control record and storing that value in variable SflPag. A section for loading the subfile appears later in the C-specs. Notice that the program loads the subfile in a For loop that executes the number of times specified in variable SflPag. You can change the value you specify for keyword SflPag in the display file DDS, and the program will load the correct number of subfile records. And More! Procedures RtvSflSize and RtvSflPage also simplify processing when your display file can operate in *DS3 and *DS4 mode. Because you can specify the display mode for which to retrieve information when you call these procedures, you can use a single routine (such as loading the subfile) to process the subfile records regardless of the display mode. You can even use procedures Rtv SflSize and RtvSflPage in an impact analysis tool. Suppose your shop adopts a standard that says that all subfile programs are to use page-at-a-time subfiles. You could write a program that searches through all your display files looking for subfiles that don't adhere to that standard by comparing the subfile size value to the subfile page value. In today's world of model/view/ controller and multi-platform architectures, it's important to isolate the user interface from the rest of the application. You may find that DspFINfo's procedures helpful in such an environment. Gary Guthrie is a senior technical editor for iSeries NEWS and an iSeries technical support consultant. You can reach him at gguthrie @iSeriesNetwork.com. * =================================================================== * = Service program... DspFInfo = * = Description....... Retrieve display file information routines = * =================================================================== H NoMain * =================================================================== * = Prototypes = * =================================================================== * ------------------------------------------------------------------- * - RtvSflSize - Retrieve subfile size - * ------------------------------------------------------------------- D RtvSflSize PR 5I 0 D 10 Value D 10 Value D 10 Value D 272 D 4 Value D Options( *NoPass ) * ------------------------------------------------------------------- * - RtvSflPage - Retrieve subfile page - * ------------------------------------------------------------------- D RtvSflPage PR 5I 0 D 10 Value D 10 Value D 10 Value D 272 D 4 Value D Options( *NoPass ) * ------------------------------------------------------------------- * - RtvSflAttr - Retrieve subfile attribute - * ------------------------------------------------------------------- D RtvSflAttr PR 5I 0 D 10 Value D 10 Value D 10 Value D 1 Value D 5 Value D 272 * ------------------------------------------------------------------- * - RtvDspFDesc - Retrieve display file description (QDFRTVFD API) - * ------------------------------------------------------------------- D RtvDspFDesc PR ExtPgm( 'QDFRTVFD' ) D 8 D 10I 0 Const D 8 Const D 20 Const D 272 * =================================================================== * = Procedure RtvSflSize = * =================================================================== P RtvSflSize B Export * ------------------------------------------------------------------- * - Parameters - * ------------------------------------------------------------------- D RtvSflSize PI 5I 0 D DspFName 10 Value D DspFLib 10 Value D RcdFmt 10 Value D APIError 272 D DspMode 4 Value D Options( *NoPass ) * ------------------------------------------------------------------- * - Return value - * ------------------------------------------------------------------- D SubfileSize S 5I 0 Inz( *Zero ) * ------------------------------------------------------------------- * - Work fields - * ------------------------------------------------------------------- D DspModeDS3 C X'03' D DspModeDS4 C X'04' D ModeToRtv S 1 D NoAPIError C Const( *Zero ) D APIErrorDS DS D 10I 0 Inz( %Size( APIErrorDS ) ) D BytesAvail 10I 0 Inz( *Zero ) D 7 Inz( *Blanks ) D 1 Inz( X'00' ) D 256 Inz( *Blanks ) * ------------------------------------------------------------------- * - Set selected display mode - * ------------------------------------------------------------------- C If %Parms > 3 And C DspMode = '*DS4' C Eval ModeToRtv = DspModeDS4 C Else C Eval ModeToRtv = DspModeDS3 C EndIf * ------------------------------------------------------------------- * - Retrieve display file size - * ------------------------------------------------------------------- C Reset APIErrorDS C Eval SubFileSize = RtvSflAttr( C DspFName : C DspFLib : C RcdFmt : C ModeToRtv : C '*SIZE' : C APIErrorDS C ) C If BytesAvail <> NoAPIError C Eval SubfileSize = *Zero C EndIf C Eval APIError = APIErrorDS C Return SubfileSize P RtvSflSize E * =================================================================== * = Procedure RtvSflPage = * =================================================================== P RtvSflPage B Export * ------------------------------------------------------------------- * - Parameters - * ------------------------------------------------------------------- D RtvSflPage PI 5I 0 D DspFName 10 Value D DspFLib 10 Value D RcdFmt 10 Value D APIError 272 D DspMode 4 Value D Options( *NoPass ) * ------------------------------------------------------------------- * - Return value - * ------------------------------------------------------------------- D SubfilePage S 5I 0 Inz( *Zero ) * ------------------------------------------------------------------- * - Work fields - * ------------------------------------------------------------------- D DspModeDS3 C X'03' D DspModeDS4 C X'04' D ModeToRtv S 1 D NoAPIError C Const( *Zero ) D APIErrorDS DS D 10I 0 Inz( %Size( APIErrorDS ) ) D BytesAvail 10I 0 Inz( *Zero ) D 7 Inz( *Blanks ) D 1 Inz( X'00' ) D 256 Inz( *Blanks ) * ------------------------------------------------------------------- * - Set selected display mode - * ------------------------------------------------------------------- C If %Parms > 3 And C DspMode = '*DS4' C Eval ModeToRtv = DspModeDS4 C Else C Eval ModeToRtv = DspModeDS3 C EndIf * ------------------------------------------------------------------- * - Retrieve display file page - * ------------------------------------------------------------------- C Reset APIErrorDS C Eval SubFilePage = RtvSflAttr( C DspFName : C DspFLib : C RcdFmt : C ModeToRtv : C '*PAGE' : C APIErrorDS C ) C If BytesAvail <> NoAPIError C Eval SubfilePage = *Zero C EndIf C Eval APIError = APIErrorDS C Return SubfilePage P RtvSflPage E * =================================================================== * = Procedure RtvSflAttr = * =================================================================== P RtvSflAttr B * ------------------------------------------------------------------- * - Parameters - * ------------------------------------------------------------------- D RtvSflAttr PI 5I 0 D DspFName 10 Value D DspFLib 10 Value D RcdFmt 10 Value D ModeToRtv 1 Value D AttrToRtv 5 Value D APIError 272 * ------------------------------------------------------------------- * - Return value - * ------------------------------------------------------------------- D SflAttrValue S 5I 0 Inz( *Zero ) * ------------------------------------------------------------------- * - Base File Section - * ------------------------------------------------------------------- D QDFFBASE DS Based( QDFFBASEPtr ) D OffsetToQDFFINFO... D 5I 0 Overlay( QDFFBASE : 9 ) D NbrRcdFmts 5I 0 Overlay( QDFFBASE : 11 ) D NbrScnSizes 5I 0 Overlay( QDFFBASE : 14 ) D ScnSizeTbl 5 Overlay( QDFFBASE : 20 ) D Dim( 2 ) D ScnID 1 Overlay( ScnSizeTbl : 1 ) * ------------------------------------------------------------------- * - File Header Section - * ------------------------------------------------------------------- D QDFFINFO DS Based( QDFFINFOPtr ) D QDFFINFOLen 10I 0 Overlay( QDFFINFO : 1 ) * ------------------------------------------------------------------- * - Record Format Table - * ------------------------------------------------------------------- D QDFARFTE DS Based ( QDFARFTEPtr ) D RcdFmtEntry 10 Overlay( QDFARFTE : 1 ) D OffsetToQDFFRINF... D 10I 0 Overlay( QDFARFTE : 13 ) * ------------------------------------------------------------------- * - Record Header Section - * ------------------------------------------------------------------- D QDFFRINF DS Based( QDFFRINFPtr ) D Flags 1 Overlay( QDFFRINF : 13 ) D OffsetToQDFFSFCR... D 5I 0 Overlay( QDFFRINF : 29 ) * ------------------------------------------------------------------- * - Subfile Control Record - * ------------------------------------------------------------------- D QDFFSFCR DS Based ( QDFFSFCRPtr ) D QDFFSFHR 24 Overlay( QDFFSFCR : 55 ) D Dim( 2 ) D SflSize 5I 0 Overlay( QDFFSFHR : 1 ) D SflPage 5I 0 Overlay( QDFFSFHR : 3 ) * ------------------------------------------------------------------- * - Work fields - * ------------------------------------------------------------------- D NoAPIError C Const( *Zero ) D QualDspF S 20 D APIErrorDS DS D 10I 0 Inz( %Size( APIErrorDS ) ) D BytesAvail 10I 0 Inz( *Zero ) D MsgID 7 Inz( *Blanks ) D 1 Inz( X'00' ) D MsgDta 256 Inz( *Blanks ) D RtvSizeInfo DS D 4 D RtvSize 10I 0 D Counter S 5I 0 D Idx S 5I 0 * ------------------------------------------------------------------- * - Get length of information to be retrieved and allocate that - * - amount of storage - * ------------------------------------------------------------------- C Eval QualDspF = DspFName + DspFLib C Reset APIErrorDS C CallP RtvDspFDesc( C RtvSizeInfo : C 8 : C 'DSPF0100' : C QualDspF : C APIErrorDS C ) C If BytesAvail <> NoAPIError C ExSr ReturnError C EndIf C Alloc RtvSize QDFFBASEPtr * ------------------------------------------------------------------- * - Retrieve display file information - * ------------------------------------------------------------------- C Reset APIErrorDS C CallP RtvDspFDesc( C QDFFBASE : C RtvSize : C 'DSPF0100' : C QualDspF : C APIErrorDS C ) C If BytesAvail <> NoAPIError C ExSr ReturnError C EndIf * ------------------------------------------------------------------- * - Set pointer to File Header Section - * ------------------------------------------------------------------- C Eval QDFFINFOPtr = QDFFBASEPtr + C OffsetToQDFFINFO * ------------------------------------------------------------------- * - Set pointer to first Record Format Table entry - * ------------------------------------------------------------------- C Eval QDFARFTEPtr = QDFFINFOPtr + C QDFFINFOLen * ------------------------------------------------------------------- * - Search through record formats and when the selected record - * - format is located, process it - * ------------------------------------------------------------------- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * - In case the selected record format is not found, set default - * - error message - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - C Eval MsgID = 'CPF9897' C Eval MsgDta = 'Record format ' + C %Trim( RcdFmt ) + C ' was not found in file ' + C %Trim( DspFLib ) + C '/' + C %Trim( DspFName ) + C '.' C Eval BytesAvail = %Len( %Trim( MsgDta ) ) C For Counter = 1 To NbrRcdFmts C If RcdFmt = RcdFmtEntry C ExSr ProcessRcdFmt C Leave C EndIf * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * - Set pointer to next Record Format Table entry - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - C Eval QDFARFTEPtr = QDFARFTEPtr + C %Len( QDFARFTE ) C EndFor * ------------------------------------------------------------------- * - Release previously allocated storage - * ------------------------------------------------------------------- C DeAlloc QDFFBASEPtr * ------------------------------------------------------------------- * - Return information to caller - * ------------------------------------------------------------------- C Return SflAttrValue * ------------------------------------------------------------------- * - Subroutine.... ProcessRcdFmt - * - Description... Process record format - * ------------------------------------------------------------------- C ProcessRcdFmt BegSr * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * - In case the selected record format is not a subfile control - * - record, set default error message - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - C Eval MsgID = 'CPF9897' C Eval MsgDta = 'Record format ' + C %Trim( RcdFmt ) + C ' in file ' + C %Trim( DspFLib ) + C '/' + C %Trim( DspFName ) + C ' is not a subfile control ' + C 'record.' C Eval BytesAvail = %Len( %Trim( MsgDta ) ) * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * - Set pointer to Record Header Section - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - C Eval QDFFRINFPtr = QDFFINFOPtr + C OffsetToQDFFRINF * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - * - Process record format if it is a subfile control record - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - C TestB '2' Flags 01 C If *In01 * : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : * : Clear error structure : * : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : C Reset APIErrorDS * : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : * : Set pointer to Subfile Control Record : * : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : C Eval QDFFSFCRPtr = QDFFRINFPtr + C OffsetToQDFFSFCR * : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : * : Set subfile size information : * : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : C For Idx = 1 To NbrScnSizes C If ScnID( Idx ) = ModeToRtv C Select C When AttrToRtv = '*SIZE' C Eval SflAttrValue = SflSize( Idx ) C When AttrToRtv = '*PAGE' C Eval SflAttrValue = SflPage( Idx ) C EndSl C Leave C EndIf C EndFor C EndIf C EndSr * ------------------------------------------------------------------- * - Subroutine.... ReturnError - * - Description... Return error condition to caller - * ------------------------------------------------------------------- C ReturnError BegSr C Eval APIError = APIErrorDS C Return *Zero C EndSr P RtvSflAttr E
As an Amazon Associate we earn from qualifying purchases.
This mailing list archive is Copyright 1997-2025 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].
Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.