tnt400.com - AS/400 Tips And Techniques

Sponsored by news400.com

This page is a discussion on the mentioned topic.
Most of the answers are in their original posted form, including any technical/spelling/grammatical errors.
No guarantees are expressed or implied. :-)
Comments, corrections, concerns about this tip?

Got another AS/400 question? Ask it here


What's New?
See what's new at Tips-N-Tech.

AS/400 Tips-N-Tech
AS/400 tips, techniques, and FAQ. Updated frequently.
CODEPage/400
All the code samples you can eat! RPG, CL, DDS, etc. etc.
AS/400 FAQs
The official news400.com FAQs.






All AS/400 Tip Categories / AS/400 Programming / Help with data area API


Question:

I need help with the QWCRDTAA api. I have copied the data structures from the system include source file and added space for the variable data to be returned at the end. The length of both the receiver variable and the error parameter DS is 32767. The ILE RPG compiles without error, but the call to the API errors out with the message "Receiver value to small to hold output." That is VALUE and not variable. The error returned in the Error DS is the ever-popular CPF9999. What I need to do is print the contents of every data area in a given library. QUSLOBJ gives me the list of names (and that part of the program works fine). Now I want to walk through that list and access each data area on the list. Can anybody share an example of a call that works?


Answer(s):



Since RPG has built in support for data areas, we have found little need to use the API with RPG. However, PL/I has no support for data areas, so we wrote a function using the QWCRDTAA API to retrieve data areas for use in our PL/I programs. Perhaps you can gleen some information from this code. One important thing to remember about this API is that the data area's value is returned in the same field, regardless of the type and Packed fields are not converted to readable characters. I hope this helps. Sorry I don't have an RPG example for you
 RTVDTAARA:  PROCEDURE (DTAARA,LIB)  RETURNS(CHAR(1024) VARYING);



     DCL        DTAARA    CHAR(10);
     DCL        LIB       CHAR(10);

     Dcl        DecVal    Char(31) Varying;

   Dcl (Int,I) Bin(15);
   Dcl Char1 Char(1);


     %INCLUDE QPLIINCL(TRIM);
 Dcl 1 ErrRtn Static,
     5 ErrStrLen     Bin(31) Unaligned Init(272),
     5 ErrRtnLen     Bin(31) Unaligned,
     5 ErrMsgID      Char(7),
     5 Filler        Char(1),
     5 ErrMsgDta     Char(256);

   Dcl QWCRDTAA Ext Entry
                 (*,    /* Return variable           */
                  Bin(31),    /* Length of return variable */
                  Char(20),   /* Qualified data area name  */
                  Bin(31),    /* Start position            */
                  Bin(31),    /* Length to retrieve        */
                  *))                       /* Error code structure    */
                Options(Assembler);


   Dcl 1 Value_St,
         5 AvailBytes        Bin(31) Unaligned,
         5 RtnBytes          Bin(31) Unaligned,
         5 Type              Char(10),
         5 RtnLib            Char(10),
         5 RtnLen            Bin(31) Unaligned,
         5 DecPos            Bin(31) Unaligned,
         5 Value             Char(1024);

  ON ERROR  GOTO EOJ;


 IF (LIB=' ') THEN LIB = '*LIBL';
 Call     QWCRDTAA   (Value_St,1060,DTAARA³³LIB,-1,1024,ErrRtn);
 Select(Value_St.Type);
   When ('*LGL','*CHAR')
     Return(Substr(Value,1,RtnLen));
   When ('*DEC')
     Do;
       DecVal = '';
       Do i = 1 to RtnLen/2 + 1;
         Char1 = substr(value,i,1);
         /* moves the first four bits to an interger field */
         int = substr(unspec(char1),1,4);
        /* convert integer to character and append  */
        DecVal = DecVal||Trim(Char(int));
         /* moves the first four bits to an interger field */
          int = substr(unspec(char1),5,4);
         Select(int);
           When(0,1,2,3,4,5,6,7,8,9)
             DecVal = DecVal|| Trim(Char(int));
           When(13) /* x'D' found make value negative */
             DecVal = '-'|| DecVal;
           When(15); /* x'F' found value is positive, ignore it */
         End;
       End;
       If DecPos > 0 Then
         DecVal = Substr(DecVal,1,Length(DecVal)-DecPos) ||'.'||
                  Substr(DecVal,Length(DecVal)-DecPos+1);
       Return(DecVal);
     End;
 End; /* Select */
 EOJ: Return('NOT FOUND');
 END RTVDTAARA;





Here is an example of using QWCRDTAA from ILE RPG.

  D* copy qsysinc/qrpglesrc,qwcrdtaa into source to change QWCVALUE
     DQWCRDRTN         DS
     D*                                             Qwc Rdtaa Data Return
     D QWCBAVL                 1      4B 0
     D*                                             Bytes Available
     D QWCBRTN                 5      8B 0
     D*                                             Bytes Returned
     D QWCTVRTN                9     18
     D*                                             Type Value Returned
     D QWCLIBN                19     28
     D*                                             Library Name
     D QWCLVRTN               29     32B 0
     D*                                             Length Value Returned
     D QWCNBRDP               33     36B 0
     D*                                             Number Decimal Positio
     D QWCVALUE               37    512
     D*
     D*                             Varying length MODIFIED and uncommente
     D*
     D/copy qsysinc/qrpglesrc,qusec
     D*
     Drcvvarsiz        s             10i 0 inz(512)
     Ddataname         s             20    inz('DTAARA    DTALIB    ')
     Dstrpos           s             10i 0 inz(-1)
     Dstrlen           s             10i 0 inz(475)
     C*
     C                   eval      QUSBPRV = 0
     C                   call      'QWCRDTAA'
     C                   parm                    QWCRDRTN
     C                   parm                    rcvvarsiz
     C                   parm                    dataname
     C                   parm                    strpos
     C                   parm                    strlen
     C                   parm                    QUSEC
     C* The variable QWCVALUE now contains the *DTAARA value
     C                   eval      *inlr = '1'
     C                   return





Whenever you define a binary field in the D-specs in RPG IV, you need to make it 9 positions. The API docs make you assume 4 positions, but that is the physical length. Remeber, most of the API documentation was written before RPG 4 came out. Make sure that the receiver variable is as long as the longest data area you'll be accessing, and the length parameter must match it. Code your DS in RPG III with the binary values as B 4, run it through CVTRPGSRC, and you'll see what I mean. HTH,





Other tips in this category:

Click here to see all categories.

Socket Programming And Timeout Issues
Deleting Duplicate Records From A Table
What are data queues and how to use
Retrieving SMTP Name
RPGLE example for Dynamic Screen Manager API
Calling APIs from CL - with examples!
Compare two strings in RPG character by character
How to search all pgms in QCLSRC for a keyword
Retrieve Database File Description (QDBRTVFD) API
How to redirect the output to STDERR from RPG-IV
Using Multiformat Logical To Join 2 Identical File
D-Spec *LIKE DEFN
RPG: Converting Character to Decimal
Example of ILE RPG CGI Program
Handling ILE RPG Numeric Overflow
Help with Subfile Programming in RPG III
Zoned parameter in ILE RPG
What's the best way to do modulus in CL?
RPG Nesting Source Print Utility
More on changing the SIGNON screen
A silly ILE RPG question
Calling Validation List API From ILE RPG
Soft Coding Module Names
RPG Multidimensional Arrays in Action
Build a Page-Equals-Size Lookup Window
Procedures within an ILE RPG program
Break msg from RPG
Source Debugger for batch jobs
RPGLE debugging
Timing out display sessions in DDS
Building Dynamic Stored Procedures
Put Message in System Log
Dynamic RPGSQL
Randomize function for the AS/400
What's the fastest way to do a simple RPG lookup?
First time Data queue application in RPG
Print file overflow in ILE RPG
Mapping Fields To Arrays in ILE RPG
Named inidicators
STRQMQRY: comparision operator '=' isn't correct?!
DSPDTAARA to an outfile - possible?
PCL ESC codes in RPG
Sharing DB files between two AS/400s
Help: AS/400 subfiles
How do you change the signon screen?
Determining Even/Odd Values in queries
Get day of the week in RPG
Convert UPPERCASE to lowercase
RPG IV help using APIs
Help with data area API
Detecing IFS Files from RPG
SQL in a CL program
Calling AS/400 APIs from ILE RPG
CVTDAT command to convert an *MDY to a *LONGJUL
CPYSPLF Automation
Subfile Window background problem
Using IFS APIs w/ ILE RPG
Packed or unpacked fields?
QRYDFN to source and back
What does the "optimize" parm do?
Determining the calling program
Sockets in RPG?
Sorting a user space
OVRDBF and SECURE() keyword in an ILE environment
RPG record locking
RPG Differences: V2R3 to V3R2 upgrade
Getting the relative record number (RRN)
What is the longest parameter usable in RPG?
A C function that returns a string to an RPG pgm
Problems with ZADD *ZEROS
Can you highlight code in SEU?
Reusing deleted records - OK?
Is there an easy way to change edit codes?
Help - Windowed Subfiles
Logical Files and DDS
AS/400 'machine language' - MI Programming
Library lists and performance
How to use ERRSFL
Updating in CL
Record lock wait time
Message subfile problem
Physical File Joins
CL: Copying User Profiles
Commands and PARM
ILE RPG, RPG IV, vs. RPG/400
RPG and subfiles
Multiple subfiles
Field masking for passwords
SFLMODE keyword in an ILE program
Subfile size
Color coding records in a subfile
MSGLINE in windows
Controlling cursor movement on a display file
API returns error! Why?
Put an RPG Program on the Web
Variable length records in RPG
Differences Between RPG400, RPG IV, and ILE RPG
ddddddddddddddddddddd