HOWTO: How to read an iSeries/400 Data Area from AVR
The information in this article applies to:
- ASNA Visual RPG, Release 3.5 and Higher
- Windows
- AS/400
- DataGate/400, Version 5.670 and Higher
SUMMARY:
This article will discuss a way in which you can read an iSeries/400 Data
Area from AVR.
The technique is
simple: Issue a CALL the OS/400 QWCRDTAA API from AVR to read a data area. This
example assumes a character data area named TESTDA in library MYLIB. It reads
the first ten bytes of the data in that data area.
MORE INFORMATION:
NOTE: These methods listed below are examples. There might be
other methods in which this feature can be incorporated into an AVR application that
is not mentioned in this article.
The AVR example program to read a data
area is shown below. Before we dive into its code, we need to take a look at how
OS/400 APIs use parameters and how those parameters are declared in AVR.
Although this program very specifically calls the QWCRDTAA API, the basic API
calling techniques used here can be used with virtually any OS/400 API.
TIP: The key to understanding is to understand the parameters the
QWCRDTAA API uses and how those parameters are declared in AVR.
Click
here to read the IBM QWCRDTAA documentation.
Requirements:
- ASNA Visual RPG 3.5 and higher;
- Access to an AS/400 and DataGate/400
installed on the AS/400.
QWCRDTAA API Information and how it relates to
AVR:
The QWCRDTAA API uses the following six parameters (See Figure 1):
|
Parameter description |
Input/Ouput |
Type |
Len |
| Receiver variable |
Output |
Char |
* |
| Length of receiver variable |
Input |
Binary |
4, 0 |
| Qualified data area name |
Input |
Char |
20 |
| Starting position of data to read |
Input |
Binary |
4, 0 |
| Length of data to read |
Input |
Binary |
4, 0 |
| Error code |
Input/Output |
Char |
* |
Figure 1
The two dark rows (Receiver
variable and Error code) must be defined and passed as
Data Structures.
The asterisk for the length of these two parameters indicates that these
parameters are of variable
length. The
structure of the Receiver variable and the Error code are shown below.
-
Receiver parameter layout:
The Receiver variable parameter is described with the data structure below
(See Figure 2):
|
Parameter description |
Type |
Len |
| Bytes available |
Binary |
4, 0 |
| Bytes returned |
Binary |
4, 0 |
| Type of value returned |
Char |
10 |
| Library name |
Char |
10 |
| Length of value returned |
Binary |
4, 0 |
| Number of decimal positions |
Binary |
4, 0 |
| Value |
Char |
* |
Figure 2
The Receiver parameter as described by code (See Figure 3):
DclDS APIRecVar FldScope( *Local )
// OS/400 QWCRDTAA API return variable.
DclDSFld BytesAvail Start(
1 ) Len( 9, 0 ) Type( *Binary )
DclDSFld BytesReturned Start( 5
) Len( 9, 0 ) Type( *Binary )
DclDSFld TypeReturned Start( 9
) Len( 10 ) Type( *Char
)
DclDSFld Library
Start( 19 ) Len( 10 )
Type( *Char )
DclDSFLd RetValLen Start(
29 ) Len( 9, 0 ) Type( *Binary )
DclDSFld DecPos
Start( 33 ) Len( 9, 0 )
Type( *Binary )
DclDSFld Buffer
Start( 37 ) Len( 1024 )
Type( *Char )
|
Figure 3
NOTE: That the code is using 4-byte binary fields. Within the data
structure, a four-byte binary takes four bytes; however, internally, a four-byte binary value is seen as a nine digit,
zero decimal number (i.e. 9,0).
- Error code parameter layout:
The Error code parameter is described with the data structure below (See
Figure 4):
|
Parameter description |
Type |
Len |
| Bytes returned |
Binary |
4, 0 |
| Bytes available |
Binary |
4, 0 |
| CPF message ID |
Char |
7 |
Figure 4
If an error occurs calling the API, the CPF message ID will
be in the third parameter value above. As you'll see in a moment, this value is
used to fetch the error message text in the AVR program.
The Error code parameter as described by code (See
Figure 5):
DclDS Error FldScope( *Local )
// OS/400 API error structure.
DclDSFld BytesReturned Start( 1 ) Len( 9, 0 ) Type( *Binary )
DclDSFld BytesAvail Start( 5 ) Len( 9, 0 ) Type( *Binary )
DclDSFld Text Start( 9 ) Len( 7 ) Type( *Char )
|
Figure 5
NOTE: That the code is using 4-byte binary fields. Within the data
structure, a four-byte binary takes four bytes; however, internally, a four-byte binary value is seen as a nine digit,
zero decimal number (i.e. 9,0).
Here is the complete code (See Figure 6 below) to describe the parameters
the QWCRDTAA API (See Figure 1 above) uses:
DclFld RecVarLen
Len( 9, 0 ) Type( *Binary )
DclFld DataArea Len( 20
) Type( *Char )
DclFld StartPos Len( 9, 0
) Type( *Binary )
DclFld DataLen Len( 9,
0 ) Type( *Binary )
DclDS APIRecVar FldScope( *Local )
// OS/400 QWCRDTAA API return variable.
DclDSFld BytesAvail Start(
1 ) Len( 9, 0 ) Type( *Binary )
DclDSFld BytesReturned Start( 5
) Len( 9, 0 ) Type( *Binary )
DclDSFld TypeReturned Start( 9
) Len( 10 ) Type( *Char
)
DclDSFld Library
Start( 19 ) Len( 10 )
Type( *Char )
DclDSFLd RetValLen Start(
29 ) Len( 9, 0 ) Type( *Binary )
DclDSFld DecPos
Start( 33 ) Len( 9, 0 )
Type( *Binary )
DclDSFld Buffer
Start( 37 ) Len( 1024 )
Type( *Char )
DclDS Error FldScope( *Local )
// OS/400 API error structure.
DclDSFld BytesReturned Start( 1 ) Len( 9, 0 ) Type( *Binary )
DclDSFld BytesAvail Start( 5 ) Len( 9, 0 ) Type( *Binary )
DclDSFld Text Start( 9 ) Len( 7 ) Type( *Char )
|
Figure 6
You'll notice that the DataArea parameter (See Figure 6,
Line 2) is 20 bytes long. This value is to be the qualified data area name
where the first ten bytes are the data area name and the second ten are the
library name. Using the data structure below (see Figure 7) to build the qualified data area
name makes it easy to provide the required trailing blanks.
DclDS ObjName FldScope( *Local )
// OS/400 qualified object name.
DclDSFld DataArea Start( 1 ) Len( 10 ) Type( *Char )
DclDSFld Library Start( 11 ) Len( 10 ) Type( *Char )
|
Figure 7
The FldScope( *Local ) specifies a
qualified reference to the data structure. Thus, with the example above, you'd
use these two lines (See Figure 8) to set the DataArea and Library names:
ObjName.DataArea = 'TESTDA'
ObjName.Library = 'MYLIB'
|
Figure 8
Example AVR Program Form
(See Figure 9):

Figure 9
The button is named btnCallAPI and the bottom label control is named
lblDataArea. None of the other controls are referenced in the code.
Example AVR Program Code (See
Figure 10):
// ASNA Miscellaneous Controls Library. Make sure you have a
Project Reference to this Control.
DclFld as Type( MISCCTLSLib.String )
// Declare a collection to hold the API's CPF messages.
DclFld CPFMsgs Type( AVRCtlsLib.Collection )
// Fill the collection with the messages the API can return.
ExSr SetErrorMsg
DclDS APIRecVar FldScope( *Local )
// OS/400 QWCRDTAA API return variable.
DclDSFld BytesAvail Start( 1 ) Len( 9, 0 ) Type( *Binary )
DclDSFld BytesReturned Start( 5 ) Len( 9, 0 ) Type( *Binary )
DclDSFld TypeReturned Start( 9 ) Len( 10 ) Type( *Char )
DclDSFld Library Start( 19 ) Len( 10 ) Type( *Char )
DclDSFld RetValLen Start( 29 ) Len( 9, 0 ) Type( *Binary )
DclDSFld DecPos Start( 33 ) Len( 9, 0 ) Type( *Binary )
DclDSFld Buffer Start( 37 ) Len( 1024 ) Type( *Char )
// The total length of the APIRecVar data structure is 1060 bytes. The API
// needs to have this specified. This constant does that. If you needed to read
// more than 1024 bytes from a data area, you could make the Buffer variable above
// larger being sure to keep the APIRECVAL_LEN constant set correctly.
DclConst APIRECVAR_LEN Value( 1060 )
// OS/400 QWCRDTAA API arguments.
DclFld RecVarLen Len( 9, 0 ) Type( *Binary )
DclFld DataArea Len( 20 ) Type( *Char )
DclFld StartPos Len( 9, 0 ) Type( *Binary )
DclFld DataLen Len( 9, 0 ) Type( *Binary )
DclDS Error FldScope( *Local )
// OS/400 API error structure.
DclDSFld BytesReturned Start( 1 ) Len( 9, 0 ) Type( *Binary )
DclDSFld BytesAvail Start( 5 ) Len( 9, 0 ) Type( *Binary )
DclDSFld Text Start( 9 ) Len( 7 ) Type( *Char )
DclDS ObjName FldScope( *Local )
// OS/400 qualified object name.
DclDSFld DataArea Start( 1 ) Len( 10 ) Type( *Char )
DclDSFld Library Start( 11 ) Len( 10 ) Type( *Char )
BEGSR btnCallAPI Click
ObjName.DataArea = 'TESTDA'
ObjName.Library = 'MYLIB'
APIRecVar.Buffer = *Blanks
RecVarLen = APIRECVAR_LEN // 1060 is the length of the APIRecVar DS.
DataArea = ObjName
StartPos = 1 // Get data area data at position 1.
DataLen = 10 // Get 10 bytes of data area data.
ExSr MakeAPICall
ENDSR
BegSr MakeAPICall
DclFld DB Type( *String )
DclFld CallErr Type( *Boolean )
DB = 'ASNA 400 DB'
Call Pgm( 'QSYS/QWCRDTAA' ) DB( DB ) Err( CallErr )
DclParm APIRecVar
DclParm RecVarLen
DclParm DataArea
DclParm StartPos
DclParm DataLen
DclParm Error
If ( CallErr )
MsgBox Msg( 'error: ' + *Err.Description )
Else
If ( Error.CPFMSGID <> *Blanks )
// If Error.CPFMSGID has a value a CPF message error occurred.
// Use DisplayError to display the message.
DisplayError( Error.CPFMSGID )
Else
// Set caption to display data read from data area.
lblDataArea.Caption = %SUBST( APIRecVar.Buffer, 1, DataLen )
EndIf
EndIf
EndSr
BegSr SetErrorMsgs
// Put all possible CPF messages for the API in the CFPMsgs collection.
CPFMsgs.Add( 'Operation on DDM data area &1 in &2 failed.' , 'CPF101A' )
CPFMsgs.Add( 'Data area &1 in &2 not found.' , 'CPF1015' )
CPFMsgs.Add( 'No authority to data area &1 in &2.' , 'CPF1016' )
CPFMsgs.Add( 'Library &1 not found for data area &2.' , 'CPF1021' )
CPFMsgs.Add( 'No authority to library &1 data area &2.' , 'CPF1022' )
CPFMsgs.Add( 'DTAARA(*GDA) not valid because job not group job.' , 'CPF1046' )
CPFMsgs.Add( 'Cannot allocate data area &1 in library &2.' , 'CPF1063' )
CPFMsgs.Add( 'Cannot allocate library &1.' , 'CPF1067' )
CPFMsgs.Add( 'DTAARA(*PDA) not valid because job not prestart job.', 'CPF1072' )
CPFMsgs.Add( 'Starting position outside of data area.' , 'CPF1088' )
CPFMsgs.Add( 'Substring specified for data area not valid.' , 'CPF1089' )
CPFMsgs.Add( 'Function &1 not allowed.' , 'CPF180B' )
CPFMsgs.Add( 'Length of value not valid.' , 'CPF1863' )
CPFMsgs.Add( 'Severe error while addressing parameter list.' , 'CPF24B4' )
CPFMsgs.Add( 'Error code parameter not valid.' , 'CPF3CF1' )
CPFMsgs.Add( 'Error occurred with receiver variable specified.' , 'CPF3C19' )
CPFMsgs.Add( 'Length of the receiver variable is not valid.' , 'CPF3C24' )
CPFMsgs.Add( 'Literal value cannot be changed.' , 'CPF3C90' )
CPFMsgs.Add( 'Program or service program &1 in library &2 ended.' , 'CPF9872' )
EndSr
BegSr DisplayError
// Display a CPF error message for the API.
DclSrParm Index Type( *String )
DclFld CPFMsg Type( *String )
// Fetch error message.
CPFMsg = CPFMsgs[ Index ]
If ( CPFMsg <> *Blanks )
// &1 = Data area name.
CPFMsg = as.Replace( CPFMsg, '&1', %TRIM( ObjName.DataArea ) )
// &2 = Library name.
CPFMsg = as.Replace( CPFMsg, '&2', %TRIM( ObjName.Library ) )
Else
CPFMsg = 'An unidentified error occurred trying to call the API'
EndIf
// Show the message.
MsgBox CPFMsg
EndSr
|
Figure 10
Other ASNA KB Articles:
IBM Documentation:
Misc. Information:
Keywords: Data Area, dataarea, dtaara, example,
develop, IDE, application, retrieve, CALL, QWCRDTAA, API
|