TAA Tools
CRTCLPEXT       CREATE CLP EXTRACT                     TAACLRH

The  Create  CLP  Extract   command  creates  CL  source  for   use  in
extracting  data from  a  record buffer  to variables  declared  from a
data  base file format.   The CRTCLPDCL  command may be  used to create
the DCL  commands.   CRTCLPEXT simplifies the  use of  a RDDBR  command
from the  CLPDBR tool.  See  also the CRTCLPINS  command which performs
the inverse function.

Note  that as  of V5R4,  the CL  Compiler allows  a data  structure and
eliminates the need for CRTCLPEXT.  See the CRTCLPDCL command.

CRTCLPEXT is intended primarily for  use with the CLPDBR tool to  allow
reading of data base  records from a CL program.   CRTCLPEXT works from
a data  base file definition.   The command may also  be helpful when a
record buffer  is passed  to CL  from a  HLL program  or an  externally
described data structure is processed in a CL program.

Steps used with CRTCLPEXT
-------------------------

The typical  use of  CRTCLPEXT is  to create  the code  needed to  work
with the  RDDBR command of  the CLPDBR tool.   If you  are not familiar
with   CRTCLPEXT,  go  thru  the  sample  described  in  the  following
section.

The CRTCLPEXT steps are summarized here:

  **   Create a source  member and write CL  code such as described  in
       the sample.

  **   Use  CRTCLPDCL  to  declare  the variables  for  the  externally
       described file.

  **   Use  a  source editor  to  move the  DCL statements  to  the DCL
       section of the program.

  **   Use  CRTCLPEXT  to  create  the  code  needed  to  perform   the
       extract.

  **   Use a  source editor to  1) Move the  DCL statements to  the DCL
       section  of the  program 2)  Move  the linkage  code immediately
       after the RDDBR  statement and  3) Move  the EXTRACT  subroutine
       after a RETURN and before a ENDPGM statement.

Sample use of CRTCLPEXT
-----------------------

The  best  method  of  understanding  CRTCLPEXT  is  to  use  a  simple
example.   You  must be  familiar with  the  CLPDBR tool  to understand
this example.

The  sample code reads a record from FILEA.   You can write a record to
FILEA using the CRTCLPINS  sample code.  If  you have not already  done
so,  you may want  to use  CRTCLPINS to  write a record  with a  key of
BBBBB which is used in this CRTCLPEXT sample.

Assume  you want a program that  will randomly read a  record by key in
a data base file and process the data.

Assume the file is named  FILEA (this is the  same file as used in  the
CRTCLPINS sample) and is defined as follows:

     A          R FILEARCD
     A            KEY            5
     A            FLD1          10
     A            FLD2           3  0
     A            FLD3           7  2
     A          K KEY

To  use CRTCLPEXT,  you would  create a  CL source  member (RDFILEA  is
used in  this example) in the QCLSRC file  with enough structure to get
your program started.   Note that the FILEA  file name must be  entered
into the DBRCTLx files to use OPNDBR.


             PGM
             OPNDBR     FILE(xxx/FILEA) OPNTYPE(*INP) DBRCTLLIB(yyy)
                        /* Read a record                           */
             RDDBR      TYPE(*EQUAL) RCD(&RCD) KEY(BBBBB)
                        /* Dump the CL pgm to allow view of data */
             DMPCLPGM
             CLSDBR
             RETURN
             ENDPGM

This  is  the only  code  you  need  to  write.   Other  code  will  be
generated for you by use of TAA commands.

The  CLPDBR tool's  RDDBR command  requires a  return variable  of 5000
bytes.   This  is much  larger than  the FILEA  record.  The  RDDBR RCD
parameter is  named  &RCD to  allow  you to  use  the default  name  on
CRTCLPEXT.  The  variable will be declared by the  use of CRTCLPEXT and
data  will be moved from &RCD  to a variable that is  given the name of
the record format of the file  (&FILEARCD in this example).  An  *EQUAL
type of read  is requested with a key  of BBBBB.  This is  the same key
as is written in the CRTCLPINS sample.

In  the sample code a  DMPCLPGM command is  used to allow  a display of
the variable data following  the read.  In  normal use, you would  have
additional CL statements to process the record.

The next step is to  use CRTCLPDCL to create the DCLs  that declare the
variables for the fields in FILEA.

             CRTCLPDCL     FILE(FILEA) SRCMBR(RDFILEA)

CRTCLPDCL  generates DCL statements  for each field  in the file.   The
source  statements  are  added  at  the  end  of  the  specified source
member.  Using  a source editor,  move the DCLs to  the DCL section  of
the program.  Your source would look like:


             PGM
                        /* Defined from FILEA in xxx                */
                        /*  Start CRTCLPDCL definitions - 09/07/09  */
             DCL        VAR(&KEY) TYPE(*CHAR) LEN(5)
             DCL        VAR(&FLD1) TYPE(*CHAR) LEN(10)
             DCL        VAR(&FLD2) TYPE(*DEC) LEN(3 0)
             DCL        VAR(&FLD3) TYPE(*DEC) LEN(7 2)
                        /* End of CRTCLPDCL definitions             */
             OPNDBR     FILE(xxx/FILEA) OPNTYPE(*INP) DBRCTLLIB(yyy)
             RDDBR      TYPE(*EQUAL) RCD(&RCD) KEY(BBBBB)
                        /* Dump the CL pgm to allow view of data */
             DMPCLPGM
             CLSDBR
             RETURN
             ENDPGM

When RDDBR  completes, the data  is in the  &RCD variable.   To process
the  data you  would have  to substring (%SST)  from the  &RCD variable
into the variables  created by CRTCLPDCL.   This can  be a tedious  and
error prone requirement.

To avoid this  coding of substring, the  CRTCLPEXT tool can be  used to
generate the code that will do it for you.

CRTCLPEXT will  generate source statements at the  end of your existing
source member:

             CRTCLPEXT     FILE(FILEA) SRCMBR(RDFILEA)

The source that is generated has 3 sections:

  **   DCL statements that  must be  moved to  the DCL  section of  the
       source.

  **   Linkage code  that is needed  to link to  a supplied section  of
       code  labeled   the  EXTRACT  routine  (described   in  a  later
       section).   You have to move  the statements (beginning with the
       comment 'EXTRACT  subroutine linkage'  to the appropriate  place
       in your program  which in this case is  immediately after RDDBR.
       Part  of the  linkage  code is  to do  CHGVAR  from &RCD  to the
       format name of the file you specified.

  **   The third section  is the EXTRACT  routine which uses  substring
       functions to  extract from  the record  buffer to the  variables
       declared  from the data  base fields.   Packed and  zoned fields
       that exist  in the  record buffer  require special  handling  in
       the EXTRACT  routine (see  later discussion).   This  subroutine
       like  function  is  intended  to  be  placed after  your  RETURN
       statement.

The added code looks like:

                        /* Defined from FILEA in xxx                */
                        /*  Start CRTCLPEXT definitions - 09/07/09  */
             DCL        VAR(&RCD) TYPE(*CHAR) LEN(5000)
             DCL        VAR(&FILEARCD) TYPE(*CHAR) LEN(21)
             DCL        VAR(&EXTRTN) TYPE(*CHAR) LEN(8)
             DCL        VAR(&EXTCHR8) TYPE(*CHAR) LEN(8)
             DCL        VAR(&EXTHEX0) TYPE(*CHAR) LEN(8) +
                          VALUE(X'0000000000000000')
             DCL        VAR(&EXTDEC15) TYPE(*DEC) LEN(15 0)
                        /*  End CRTCLPEXT definitions               */

/*  Move immediately after a command such as RDDBR  */
                        /*   EXTRACT subroutine linkage             */
             CHGVAR     VAR(&FILEARCD) VALUE(&RCD)
             CHGVAR     VAR(&EXTRTN) VALUE('EXTRACT1')
             GOTO       CMDLBL(EXTRACT)
 EXTRACT1:              /*  Return from EXTRACT subroutine          */


/*   Move after a RETURN and before ENDPGM   */
             SNDESCMSG  MSG('Your code has fallen into the +
                          EXTRACT subr')
                        /********************************************/
                        /*                                          */

 EXTRACT:               /* CRTCLPEXT for FILEA in xxx               */
                        /*   Retrieved by CRTCLPEXT on 09/07/09     */
                        /*                                          */
                        /********************************************/
             CHGVAR     VAR(&KEY) VALUE(%SST(&FILEARCD 1 5))
             CHGVAR     VAR(&FLD1) VALUE(%SST(&FILEARCD 6 10))
             CHGVAR     VAR(&EXTCHR8) VALUE(&EXTHEX0)
             CHGVAR     VAR(%SST(&EXTCHR8 7 2)) +
                          VALUE(%SST(&FILEARCD 16 2))
             MOVCHRDEC  DECOUT(&EXTDEC15) CHRINP(&EXTCHR8)
             CHGVAR     VAR(&FLD2) VALUE(&EXTDEC15)
             CHGVAR     VAR(&EXTCHR8) VALUE(&EXTHEX0)
             CHGVAR     VAR(%SST(&EXTCHR8 5 4)) +
                          VALUE(%SST(&FILEARCD 18 4))
             MOVCHRDEC  DECOUT(&EXTDEC15) CHRINP(&EXTCHR8)
             CHGVAR     VAR(&FLD3) VALUE(&EXTDEC15 / 100)
                        /*    Return GOTOs.  Modify as required     */
             IF         COND(&EXTRTN *EQ 'EXTRACT1') +
                          THEN(GOTO CMDLBL(EXTRACT1))
             SNDESCMSG  MSG('Bad return in EXTRACT routine of '  +
                        *CAT &EXTRTN)
                        /********************************************/
                        /*                                          */
                        /*     End of EXTRACT subroutine            */
                        /*                                          */
                        /********************************************/

Using a source editor, you then:

  **   Move the DCLs to the DCL section of the program.

  **   Move the linkage code immediately after RDDBR.

  **   Move the EXTRACT subroutine after the RETURN command.

  **   Delete the excess blank separator lines and extra comments.

The final code would look like:

             PGM
                        /* Defined from FILEA in xxx                */
                        /*  Start CRTCLPDCL definitions - 09/07/09  */
             DCL        VAR(&KEY) TYPE(*CHAR) LEN(5)
             DCL        VAR(&FLD1) TYPE(*CHAR) LEN(10)
             DCL        VAR(&FLD2) TYPE(*DEC) LEN(3 0)
             DCL        VAR(&FLD3) TYPE(*DEC) LEN(7 2)
                        /* End of CRTCLPDCL definitions             */
                        /* Defined from FILEA in xxx                */
                        /*  Start CRTCLPEXT definitions - 09/07/09  */
             DCL        VAR(&RCD) TYPE(*CHAR) LEN(5000)
             DCL        VAR(&FILEARCD) TYPE(*CHAR) LEN(21)

             DCL        VAR(&EXTRTN) TYPE(*CHAR) LEN(8)
             DCL        VAR(&EXTCHR8) TYPE(*CHAR) LEN(8)
             DCL        VAR(&EXTHEX0) TYPE(*CHAR) LEN(8) +
                          VALUE(X'0000000000000000')
             DCL        VAR(&EXTDEC15) TYPE(*DEC) LEN(15 0)
                        /*  End CRTCLPEXT definitions               */
             OPNDBR     FILE(xxx/FILEA) OPNTYPE(*INP) DBRCTLLIB(yyy)
                        /* Read a record                           */
             RDDBR      TYPE(*EQUAL) RCD(&RCD) KEY(BBBBB)
                        /*   EXTRACT subroutine linkage             */
             CHGVAR     VAR(&FILEARCD) VALUE(&RCD)
             CHGVAR     VAR(&EXTRTN) VALUE('EXTRACT1')
             GOTO       CMDLBL(EXTRACT)
 EXTRACT1:              /*  Return from EXTRACT subroutine          */
                        /* Dump the CL pgm to allow view of data */
             DMPCLPGM
             CLSDBR
             RETURN
             SNDESCMSG  MSG('Your code has fallen into the +
                          EXTRACT subr')
                        /********************************************/
                        /*                                          */
 EXTRACT:               /* CRTCLPEXT for FILEA in xxx               */
                        /*   Retrieved by CRTCLPEXT on 09/07/09     */
                        /*                                          */
                        /********************************************/
             CHGVAR     VAR(&KEY) VALUE(%SST(&FILEARCD 1 5))
             CHGVAR     VAR(&FLD1) VALUE(%SST(&FILEARCD 6 10))
             CHGVAR     VAR(&EXTCHR8) VALUE(&EXTHEX0)
             CHGVAR     VAR(%SST(&EXTCHR8 7 2)) +
                          VALUE(%SST(&FILEARCD 16 2))
             MOVCHRDEC  DECOUT(&EXTDEC15) CHRINP(&EXTCHR8)
             CHGVAR     VAR(&FLD2) VALUE(&EXTDEC15)
             CHGVAR     VAR(&EXTCHR8) VALUE(&EXTHEX0)
             CHGVAR     VAR(%SST(&EXTCHR8 5 4)) +
                          VALUE(%SST(&FILEARCD 18 4))
             MOVCHRDEC  DECOUT(&EXTDEC15) CHRINP(&EXTCHR8)
             CHGVAR     VAR(&FLD3) VALUE(&EXTDEC15 / 100)
                        /*    Return GOTOs.  Modify as required     */
             IF         COND(&EXTRTN *EQ 'EXTRACT1') +
                          THEN(GOTO CMDLBL(EXTRACT1))
             SNDESCMSG  MSG('Bad return in EXTRACT routine of '  +
                        *CAT &EXTRTN)
                        /********************************************/
                        /*                                          */
                        /*     End of EXTRACT subroutine            */
                        /*                                          */
                        /********************************************/
             ENDPGM

You  can then create the  RDFILEA CL program and  call it.  The spooled
file (QPPGMDMP)  created by the  DMPCLPGM command  should identify  the
variables for  &FLD1, &FLD2, and &FLD3  that exist in  the FILEA record
for a key of BBBBB.

Use of CLPDBR RCLDBR
--------------------

When  you  begin  to  use  CLPDBR  functions  along  with  the  EXTRACT
subroutine, it is  typical to make  mistakes which cause  the file  you
were operating  on to  remain open.   If  you correct  the program  and
call  it again, you will  receive an error saying  the OPNID is already
in use or open.

To correct the problem  you need to use  the RCLDBR command which  will
delete all  of the  data areas  created by OPNDBR  commands, close  any
files that  are open, and reclaim the activation  group that the CLPDBR
functions run in.

Then try your program again.

The Linkage code
----------------

The  linkage  code begins  by moving  from  the record  buffer variable
(&RCD) to the  variable assigned to  the format name  of the data  base
file  (&FILEARCD).  It  then sets  the value  EXTRACT1 into  a variable
that  will  be  used  in  an  IF  test  and  branches  to  the  EXTRACT
subroutine.  The  label EXTRACT1  is used  as a return  point from  the
subroutine.

The EXTRACT subroutine
----------------------

The EXTRACT subroutine  uses substring (%SST) to extract  the data from
the record buffer and place it in the appropriate variables.

The  first  statement  generated is  the  SNDESCMSG  TAA command  which
states that your code has fallen  into the subroutine.  The  subroutine
is intended  to be branched  to with a  GOTO, so the  SNDESCMSG command
protects your program logic.

Character data is moved by using substring positions.

Zoned and  packed decimal data  require specific handling  as described
in the next section.

At  the  end of  the  subroutine is  an  IF statement,  that determines
where the code should branch to.

If you have one  place in your program  where you need the  subroutine,
the linkage code  and ending GOTO appear overly  complex.  However, the
code  is  designed  to allow  multiple  uses of  the  subroutine  as is
described in a later section.

The last statement  is another  SNDESCMSG TAA  command which  describes
the problem  where you  have branched  to the  EXTRACT routine, but  do
not have a valid value in &EXTRTN.

Handling of decimal fields
--------------------------

Packed and zoned decimal fields are provided for automatically.

CL does  not allow a packed value in a *CHAR  variable to be moved to a
*DEC field (CHGVAR  would attempt  to convert the  data as  if it  were
character).   For example, if you  have a packed  3 digit field  in the
data base  the value might  be X'123F'.   If CHGDTA is  used, you would
receive CPF0818 (Value cannot be converted to the receiver).

The  TAA MOVCHRDEC tool is used to handle  the move from a packed *CHAR
value to  a *DEC  type  variable.   Before using  MOVCHRDEC, CHGVAR  is
used  to set a  work variable  to Hex  00s and  then another  CHGVAR to
substring  from the  record  data into  the Hex  00s field.   Following
MOVCHRDEC, a CHGVAR  occurs from  the &EXTDEC15 variable  to your  *DEC
variable.  &EXTDEC15  is a standard work field declared  as *DEC LEN(15
0).

If  a packed decimal  field has 2  decimal positions, the  final CHGVAR
divides by  100 to  make a  whole  number.   Unique divisors  are  used
depending on the number of decimal positions.

CL does  not support  a zoned  decimal type  of variable.   If a  zoned
decimal field  had existed in  the data base  record in the  example, a
DCL  would define  a *DEC variable  which is treated  as packed decimal
within the  CL program.   Zoned  decimal  fields are  processed in  the
subroutine by  first moving the data  to the &EXTDEC15 field.   As with
packed  decimal fields,  if more  than 0  decimal positions  exist, the
final CHGVAR divides by a number such as 100.

Binary fields  are declared  as *CHAR  and CHGVAR  is used.   You  must
supply your own processing of binary data.

Multiple use of the EXTRACT subroutine for the same file
--------------------------------------------------------

The  EXTRACT subroutine  is  designed to  allow  you  to have  multiple
points  within your program  where you need  access to a  record in the
same file such as the use of additional RDDBR commands.

The following steps are needed for each subsequent use:

  **   Duplicate the linkage  code (shown as  follows) just after  each
       subsequent use of RDDBR:

                        /*   EXTRACT subroutine linkage             */
             CHGVAR     VAR(&FILEARCD) VALUE(&RCD)
             CHGVAR     VAR(&EXTRTN) VALUE('EXTRACT1')
             GOTO       CMDLBL(EXTRACT)
 EXTRACT1:              /*  Return from EXTRACT subroutine          */

  **   Change the EXTRACT1 constant  in the CHGVAR and the  name of the
       label.   'EXTRACT2' would be  the typical choice  for the second
       use.

  **   The last statement in the subroutine is:

             IF         COND(&EXTRTN *EQ 'EXTRACT1') +
                          THEN(GOTO CMDLBL(EXTRACT1))

Duplicate  this code to  the next line and  change the 'EXTRACT1' value
on the IF and the THEN to the name you chose previously such as:

             IF         COND(&EXTRTN *EQ 'EXTRACT2') +
                          THEN(GOTO CMDLBL(EXTRACT2))

Using both CRTCLPEXT and CRTCLPINS in the same program
------------------------------------------------------

The  CRTCLPINS  tool  provides  the  inverse   function  of  CRTCLPEXT.
CRTCLPINS provides a  subroutine like function to insert  data from the
variables  declared from  the data base  fields to  a variable declared
as your record format.

You would use  CRTCLPINS if  you were  using a command  like WRTDBR  or
UPDDBR to write or update a record to the data base.

If you  are using  both RDDBR  and UPDDBR/WRTDBR  in the same  program,
then  both  subroutines   are  needed.    Just  follow  the  steps  for
CRTCLPINS in  addition  to  CRTCLPEXT.    You  only  need  to  use  the
CRTCLPDCL function  once to  declare variables  for the  fields in  the
file.

Use of EXTRACT for different files
----------------------------------

You  can use  CRTCLPEXT for  different files  within your  program, but
you  must use a different  name for each subsequent  use.  Use a source
editor to change the  name EXTRACT and the corresponding  linkage code.

Conversion of field types
-------------------------

Packed  and zoned  fields  are extracted  to  *DEC variables.   A  *DEC
field may have up to 15 digits and 9 decimal positions.

Binary  fields  and  all  other  field  types  are  extracted to  *CHAR
variables.

CRTCLPEXT escape messages you can monitor for
---------------------------------------------

None.  Escape messages from based on functions will be re-sent.

Command parameters                                    *CMD
------------------

   FILE          The externally  described file  to use  to create  the
                 extract information  from.  The  file may be  either a
                 PF or LF, but may only contain a single format.

                 The  library defaults  to *LIBL.   A  specific library
                 or *CURLIB may be entered.

   SRCMBR        The member of  the source file  to be added  to.   The
                 member  must exist.    The  statements will  be  added
                 after  the  last  existing  record  (if  any)  in  the
                 source member.

   SRCFILE       The  name of the source  file containing the member to
                 be  added  to.   The  source  file  name  defaults  to
                 QCLSRC.   The library qualifier defaults to  *LIBL.  A
                 specific library or *CURLIB may be entered.

   RCDVAR        The  name  of  the  variable  that  contains the  data
                 after using a  function like  RDDBR.   The default  is
                 &RCD.   The variable  is declared  as *CHAR  LEN(5000)
                 by  CRTCLPEXT.  The  name is  used in a  single CHGVAR
                 statement  that  is  generated  at  the  end  of   the
                 linkage code by CRTCLPEXT.

Restrictions
------------

Packed and decimal data base  fields must be 15 digits or  less and the
number of decimal positions must be 9 or less.

All  other field types  (including binary)  are extracted  to character
variables.

  **   The source file must be at least 92 bytes in length.

Prerequisites
-------------

The following TAA Tools must be on your system:

     HLRMVMSG        HLL Remove message
     RTVDBFA         Retrieve data base file attributes
     RTVFMT          Retrieve format
     RTVSYSVAL3      Retrieve system value 3
     SNDCOMPMSG      Send completion message
     SNDDIAGMSG      Send diagnostic message
     SNDESCINF       Send escape information
     SNDESCMSG       Send escape message

Implementation
--------------

None, the tool is ready to use.

Objects used by the tool
------------------------

   Object        Type    Attribute      Src member    Src file
   ------        ----    ---------      ----------    ----------

   CRTCLPEXT     *CMD                   TAACLRH       QATTCMD
   TAACLRHC      *PGM       CLP         TAACLRHC      QATTCL
   TAACLRHR      *PGM       RPG         TAACLRHR      QATTRPG
					

Added to TAA Productivity tools December 1, 2004


Home Page Up to Top