Locate field value field name

From MidrangeWiki
Jump to: navigation, search

You can't do this in general in RPG (or any compiled language), but if the field is in an externally-described file, you can define an externally-described data structure for the file to get the fields in the same layout in the program as they are in the file. Then you can call the QUSLFLD API to find where that field is in the data structure.

You can also use this technique to do generic processing on files. For example, if you want to check several files to ensure that all zoned fields have valid data, you could use the program below. It uses a program described file, and calls QUSLFLD to find out the location and length of all the zoned fields in the file. Then it reads the file and checks the zoned fields in every record.

If you wanted to find a particular field or set of fields by name, rather than looking for type = 'S' as this program does, you'd look for the name you were interested in (subfield fieldName).

      * Parameters:
      * 1. File name
      * 2. Record name
      * 3. Library name (optional, defaults to *LIBL)

     Ffile      if   f32766        disk    usropn infds(infds)
     Fqsysprt   o    f   80        printer

     D record          DS         32766
     D infds           DS
     D   rrn                 397    400i 0

      * ==> create user space QTEMP/LIST (call the QUSCRTUS API to do this)
     D userSpace       C                   'LIST      QTEMP     '

     D pUserSpace      S               *
     D genericHeader   DS                           based(pUserSpace)
     D   headerOffset        117    120i 0
     D   headerSize          121    124i 0
     D   listOffset          125    128i 0
     D   listSize            129    132i 0
     D   numEntries          133    136i 0
     D   entrySize           137    140i 0

     D filename        DS
     D   fileN                       10a
     D   libN                        10a   inz('*LIBL')

     D                 DS                           based(pEntry)
     D fieldName               1     10
     D dataType               11     11
     D use                    12     12
     D outBufPos              13     16i 0
     D inBufPos               17     20i 0
     D byteLeng               21     24i 0
     D digits                 25     28i 0
     D decPos                 29     32i 0
     D fieldText              33     82
     D editCode               83     84
     D editWordLen            85     88i 0
     D editWord               89    152
     D colHead1              153    172
     D colHead2              173    192
     D colHead3              193    212
     D intName               213    222
     D altName               223    252
     D lenAltFld             253    256i 0
     D numDBCS               257    260i 0
     D alwNull               261    261N
     D hostVarInd            262    262N
     D datTimFmt             263    266
     D datTimSep             267    267
     D varyingInd            268    268N

     D i               S             10i 0

     D zonedFields     S               *   dim(100)
     D numZoned        S              5p 0 inz(0)
     D zonedCheck      S             30a   varying

     C     *entry        plist
     C     fileN         parm                    fileParm         10
     C                   parm                    recordParm       10
     C                   parm                    libParm          10

     C                   if        %parms > 2
     C                   eval      libN = libParm
     C                   endif

      * Get the list of all the fields
     C                   call      'QUSLFLD'
     C                   parm      userSpace     space            20
     C                   parm      'FLDL0100'    format           10
     C                   parm                    filename         20
     C                   parm                    recordParm       10
     C                   parm      '0'           override          1

      * Get a pointer to the user space containing the list
     C                   call      'QUSPTRUS'
     C                   parm      userSpace     space            20
     C                   parm                    pUserSpace

      * Process the list
     C                   do        numEntries    i
     C                   eval      pEntry = pUserSpace + listOffset
     C                                    + ((i - 1)  * entrySize)

      * Store the pointer to the entry for each zoned field
     C                   if        dataType = 'S'
     C                   eval      numZoned = numZoned + 1
     C                   eval      zonedFields(numZoned) = pEntry
     C                   endif

     C                   enddo

      * Print the header
     C                   except    header

      * Process the file
     C                   eval      ovrCmd = 'OVRDBF FILE '
     C                                    + 'TOFILE('
     C                                    + %TRIM(libN)
     C                                    + '/'
     C                                    + %TRIM(fileN)
     C                                    + ')'
     C                   call      'QCMDEXC'
     C                   parm                    ovrCmd          100
     C                   parm      100           ovrCmdLen        15 5
     C                   open      file
     C                   read      file          record
     C                   dow       not %eof
     C                   exsr      process
     C                   read      file          record
     C                   enddo
     C                   close     file

     C                   seton                                        lr

     C     process       begsr
     C                   do        numZoned      i
     C                   eval      pEntry = zonedFields(i)
     C                   exsr      checkDDE
     C                   enddo
     C                   endsr

     C     checkDDE      begsr
     C                   eval      zonedCheck = %subst(record
     C                                               : inBufPos
     C                                               : byteLeng)
     C                   testn                   zonedCheck           10
     C                   if        not *in10
     C                   except    haveDDE
     C                   endif
     C                   endsr

     Oqsysprt   e            header
     O                                              ' Library:           '
     O                       libN
     Oqsysprt   e            header
     O                                              ' File:              '
     O                       fileN
     Oqsysprt   e            header
     O                                              ' Record:            '
     O                       recordParm
     Oqsysprt   e            header
     O                                              ' # of zoned fields: '
     O                       numZoned      J
     Oqsysprt   e            header
     O                                              '--------------------'
     O                                              '--------------------'
     O                                              '--------------------'
     O                                              '--------------------'

     Oqsysprt   e            haveDDE
     O                                              ' Record: '
     O                       rrn           J
     O                                              ' Field:  '
     O                       fieldName