|
||||||||
|
|
![]() |
|
|
Easy-to-Use User Indexes by Bruce Guetzkow [The code for this article is available for download.] Keyed physical and logical files can be useful when organizing data, but sometimes they can't be used. A variance report is typically sorted by a calculated value, which is not part of the database. Data returned from an API is not in a database, so it can't be processed using physical and logical keys. Work files can solve this problem, but an alternative is user indexes. A user index offers the usefulness of a key structure without the typical maintenance issues involved with production physical and logical files. This article explains the basic APIs needed to employ user indexes, and presents procedures and a service program to simplify their use. General Concepts These APIs make use of the standard API error data structure:
d apierrds ds inz qualified
d bytesprov 9b 0 inz(%size(apierrds.msgdata))
d bytesaval 9b 0
d msgid 7a
d filler 1a
d msgdata 100a
I have configured all of the procedures to return the error message ID and message text in the first 107 bytes of the return value. Your application program can then test the message ID for a successful call (blanks). If the message ID is not blank, it can be passed to an error-handling routine, along with the message text, for error processing. The following procedures have simplified the API calls as much as possible. The version presented uses default values that are appropriate to my own work environment. If you find these defaults are not right for your situation, you can easily customize them. Create a User Index To use a user index, you must first create one, using the QUSCRTUI (Create User Index) API. The API has 10 required parameters and five optional parameters. First, the required parameters:
I will only discuss the first two optional parameters, as I have never needed to use the remaining parameters. These are the optional parameters:
Procedure #crtusridx simplifies this list to just four parameters: user index name, user index library, user index entry length, and user index key length. Here are the remaining parameters use default values:
The return value for this procedure is the API error data structure message ID and message text. This can be interrogated to determine the success of the procedure call. Add User Index Entries Now that you have created a user index, it is time to load it with entries, using the QUSADDUI (Add User Index Entries) API. This API has nine required parameters:
Procedure #addusridx simplifies this to four parameters: user index name, user index library name, entry, and entry length. The remaining input parameters use default these values:
As with the previous procedure, the return value is the API error data structure message ID and message text. Retrieve User Index Entries With your user index loaded with data, it's time to retrieve that data, using the QUSRTVUI (Retrieve User Index Entries) API. This API has 14 parameters:
That list may seem daunting, but procedure #rtvusridx trims the list to only six: user index name, user index library, entry length, key length, search type, and search criteria. Default values for the remaining parameters are:
For this procedure, the return value is the API error data structure message ID, the message text, the number of entries returned, and the receiver variable. Delete a User Index When finished with a user index, it should be deleted, using the QUSDLTUI (Delete User Index) API. There are only two parameters:
The #dltusridx procedure also uses two parameters: user index name and user index library. The return value is the API error data structure message ID and the message text. The Procedures The source for the service module is available for download. And here are the prototypes for the procedures. You will need to add these to the calling programs:
d #addusridx pr 107a
d p_usridxnam 10a
d p_usridxlib 10a
d p_entry 2000a
d p_entlgth 9b 0
d #crtusridx pr 107a
d p_usridxnam 10a
d p_usridxlib 10a
d p_entlgth 9b 0
d p_keylgth 9b 0
d #dltusridx pr 107a
d p_usridxnam 10a
d p_usridxlib 10a
d #rtvusridx pr 2111a
d p_usridxnam 10a
d p_usridxlib 10a
d p_entlgth 9b 0
d p_keylgth 9b 0
d p_srchtype 9b 0
d p_srchcrit 200a
The following data definitions are used in calling the procedures:
d uientds ds inz
d ui_keyflds
d ui_field01 3a overlay(ui_keyflds)
d ui_field02 1a overlay(ui_keyflds:*next)
d ui_field03 3s 0 overlay(ui_keyflds:*next)
d ui_field04 3s 0
d ui_field05 5s 0
d ui_field06 12a
d uientlgth s 9b 0 inz(%size(uientds))
d uikeylgth s 9b 0 inz(%size(ui_keyflds))
d entry s 2000a inz
d strpos s 9b 0 inz(9)
d usridxnam s 10a inz('YOURUSRIDX')
d usridxlib s 10a inz('QTEMP ')
d srchcrit s 200a inz
d srchtype s 9b 0 inz(2)
d rtnds01 ds inz qualified
d msgid 7a
d msgdata 100a
d rtnds02 ds inz qualified
d msgid 7a
d msgdata 100a
d nbrentrtn 9b 0
d rcvvar 2000a
Using the Procedures To use the user indexes, first create the user index:
rtnds01 = #crtusridx(usridxnam:
usridxlib:
uientlgth:
uikeylgth);
Next, in a loop, add the entries:
entry = uientds;
rtnds01 = #addusridx(usridxnam:
usridxlib:
entry:
uientlgth);
When retrieving the user index entries, remember that the data is returned in a receiver variable that may contain multiple entries. Each entry must be parsed out. The first eight bytes of the receiver variable do not contain data, so by resetting field strpos, you begin retrieving data from the receiver variable from the ninth position. The following logic retrieves all entries in the user index sequentially by key. The for-loop will process all index entries retrieved with each execution of the API:
reset srchcrit;
dou rtnds02.nbrentrtn <= *zeros;
rtnds02 = #rtvusridx(usridxnam:
usridxlib:
uientlgth:
uikeylgth:
srchtype:
srchcrit);
if rtnds02.nbrentrtn > *zeros;
reset strpos;
for nbrentrtn = 1
to rtnds02.nbrentrtn;
uientds = %subst(rtnds02.rcvvar:
strpos:
%size(uientds));
strpos = strpos + uientlgth;
srchcrit = %subst(uientds:1:uikeylgth);
endfor;
endif;
enddo;
Finally, you can delete the user index:
rtnds01 = #dltusridx(usridxnam:
usridxlib);
For the create, add, and delete procedures, the following code can be used to test for error conditions:
if rtnds01.msgid <> *blanks;
error logic
endif;
For the retreive procedure, the only change is to reference the message ID from the corresponding return data structure:
if rtnds02.msgid <> *blanks;
error logic
endif;
Quirks I have noticed a couple of interesting quirks associated with user indexes. First, numeric values in a user index key are unsigned; therefore, a variance of $17.21- is the same as $17.21+. This can be useful if you want to list positive and negative variances intermingled on the same report. However, if you wish to have separate "negative" and "positive" variance reports, you may need to create separate user indexes for each. Second, user indexes do not accept duplicate entries. You must make your entries unique to accept all values. That's because of the Add User Index Entries API Insert Type parameter: Duplicate entries are either dropped or replaced based on the value you specify. If you want a variance report sorted by the variance amount, several items may have the exact same variance amount. In this instance you will want to create a user index with a key consisting of the variance amount and one or more values that make the entry unique, probably the item number (and warehouse location, if the variance is by location). Final Word User indexes are a valuable tool. And with the APIs available as procedures, using them should be a snap. Bruce Guetzkow has programmed on the AS/400 and iSeries since 1990, in manufacturing, distribution and other industries. He is currently the IS director at United Credit Service in Elkhorn, Wisconsin. E-mail: bruceg@unitedcreditservice.com
Editors: Shannon O'Donnell, Kevin Vandever
Managing Editor: Shannon Pastore
Contributing Editors: Howard Arner, Raymond Everhart,
G. Wayne Hawks, Joe Hertvik, Ted Holt, Marc Logemann, David Morris
Publisher and Advertising Director: Jenny Thomas
Advertising Sales Representative: Kim Reed
Contact the Editors: To contact anyone on the IT Jungle Team
Go to our contacts page and send us a message. |
|
| Copyright © 1996-2008 Guild Companies, Inc. All Rights Reserved. |