Can somebody help me with the complete c# code to call QUSLSPL with SPLF0200 format. I am able to call the program but don't know how to capture/read through the output. I am new to this area. Appreciate your help.
Here is my code.
cwbx.ProgramParameters parameters = new cwbx.ProgramParameters();
//user space name
parameters.Append("usrspcnam", cwbrcParameterTypeEnum.cwbrcInout, 20);
StringConverter stringConverterUsrSpaceNm = new cwbx.StringConverter();
stringConverterUsrSpaceNm.Length = 20;
parameters["usrspcnam"].Value = stringConverterUsrSpaceNm.ToBytes("HRAHMAN QGPL ");
//Format
parameters.Append("frmname", cwbrcParameterTypeEnum.cwbrcInout, 8);
StringConverter stringConverterFrmname = new cwbx.StringConverter();
stringConverterFrmname.Length = 8;
parameters["frmname"].Value = stringConverterFrmname.ToBytes("SPLF0200");
//User Name
parameters.Append("usrnam", cwbrcParameterTypeEnum.cwbrcInout, 10);
StringConverter stringConverterUsrnam = new cwbx.StringConverter();
stringConverterUsrnam.Length = 10;
//parameters["usrnam"].Value = stringConverterUsrnam.ToBytes("*CURRENT");
parameters["usrnam"].Value = stringConverterUsrnam.ToBytes(" ");
//qualified output queue
parameters.Append("cola", cwbrcParameterTypeEnum.cwbrcInout, 20);
StringConverter stringConverterCola = new cwbx.StringConverter();
stringConverterCola.Length = 20;
//parameters["cola"].Value = stringConverterCola.ToBytes("*ALL");
parameters["cola"].Value = stringConverterCola.ToBytes(" ");
//form type
parameters.Append("frmtyp", cwbrcParameterTypeEnum.cwbrcInout, 10);
StringConverter stringConverterFrmtyp = new cwbx.StringConverter();
stringConverterFrmtyp.Length = 10;
//parameters["frmtyp"].Value = stringConverterFrmtyp.ToBytes("*ALL");
parameters["frmtyp"].Value = stringConverterFrmtyp.ToBytes(" ");
//user-specific data
parameters.Append("usrdta", cwbrcParameterTypeEnum.cwbrcInout, 10);
StringConverter stringConverterUsrdta = new cwbx.StringConverter();
stringConverterUsrdta.Length = 10;
//parameters["usrdta"].Value = stringConverterUsrdta.ToBytes("*ALL");
parameters["usrdta"].Value = stringConverterUsrdta.ToBytes(" ");
//error
parameters.Append("error", cwbrcParameterTypeEnum.cwbrcInout, 116);
Structure sc2 = new Structure();
sc2.Fields.Append("bytesprov", 4);
sc2.Fields.Append("bytesavail", 4);
sc2.Fields.Append("messageid", 7);
sc2.Fields.Append("err", 1);
sc2.Fields.Append("messagedta", 100);
parameters["error"].Value = sc2.Bytes;
//qualified job name
parameters.Append("qualifiedjobnm", cwbrcParameterTypeEnum.cwbrcInput, 26);
StringConverter stringConverterUsrdta1 = new cwbx.StringConverter();
stringConverterUsrdta1.Length = 26;
parameters["qualifiedjobnm"].Value = stringConverterUsrdta1.ToBytes("* ");
//keys
parameters.Append("keys", cwbrcParameterTypeEnum.cwbrcInput, 44); //44 is 11 keys times 4 bytes per key
LongConverter lc = new cwbx.LongConverter();
Structure keys = new Structure();
keys.Fields.Append("Spooledfilename", 4); //char10 201
keys.Fields["Spooledfilename"].Value = lc.ToBytes(201);
keys.Fields.Append("Username", 4); //char10 203
keys.Fields["Username"].Value = lc.ToBytes(203);
keys.Fields.Append("opqueue", 4); //206
keys.Fields["opqueue"].Value = lc.ToBytes(206);
keys.Fields.Append("userdata", 4); //209
keys.Fields["userdata"].Value = lc.ToBytes(209);
keys.Fields.Append("status", 4); //210
keys.Fields["status"].Value = lc.ToBytes(210);
keys.Fields.Append("totpages", 4); //bin 211
keys.Fields["totpages"].Value = lc.ToBytes(211);
keys.Fields.Append("copies", 4); //bin 213
keys.Fields["copies"].Value = lc.ToBytes(213);
keys.Fields.Append("openeddate", 4); //216
keys.Fields["openeddate"].Value = lc.ToBytes(216);
keys.Fields.Append("opentime", 4); //217
keys.Fields["opentime"].Value = lc.ToBytes(217);
keys.Fields.Append("jobid", 4); //218
keys.Fields["jobid"].Value = lc.ToBytes(218);
keys.Fields.Append("fileid", 4); //219
keys.Fields["fileid"].Value = lc.ToBytes(219);
parameters["keys"].Value = keys.Bytes;
//number of keys to return
parameters.Append("numberoffields", cwbrcParameterTypeEnum.cwbrcInput, 4);
LongConverter LongConverterKeys = new cwbx.LongConverter();
parameters["numberoffields"].Value = LongConverterKeys.ToBytes(11); //11 keys in total
program.Invoke(true, ref parameters);
Now what next? Where and how to read output? Appreciate your response.
You picked a humdinger of an API to start out with. You have a user space list API with an all-key list format. Those are complex. I'll do my best to explain it all. Buckle up!
The QUSLSPL API does not return anything except what's in the error structure. Everything else is an input parameter. To access the spooled file list generated by the API, you must access the user space object. In your example, the user space is QGPL/HRAHMAN. Before I get into examining the output of the user space, let's get into understanding how to use a user space.
What is a user space?
A user space is just a big old block of bytes stored in a library on the host system with a maximum size of 16,776,704 bytes. You can use them for more than just list API results, but that's all I really use them for. The steps for list APIs that require user spaces are as such:
Create the user space
Creating the user space is done via the Create User Space (QUSCRTUS) API. This API is pretty straight-forward. You pass it a qualified name of the user space, some initial values, and the API error structure (so you can handle problems that come up). The API definition can be found here: http://www.ibm.com/support/knowledgecenter/ssw_ibm_i_71/apis/quscrtus.htm
The parameters are:
Retrieve data from the user space
After you call the QUSLSPL API, you need to retrieve the data from the user space. For that you use the QUSRTVUS API. This API takes the user space name, the starting position, length, receiver variable, and the API error structure. The API definition is here: http://www.ibm.com/support/knowledgecenter/ssw_ibm_i_71/apis/qusrtvus.htm
The parameters are:
Delete the user space
When you're all done, delete the user space using the QUSDLTUS API. This one is even easier, it takes the fully qualified name and the API error structure. The API definition is found here: http://www.ibm.com/support/knowledgecenter/ssw_ibm_i_71/apis/qusdltus.htm
List API Structure in the User Space
List APIs return data to the user space in a specific format. It looks like this:
What really matters, as far as reading through a list API are the following values in the front of the user space, in that generic header. Note that these positions are zero-based.
With this information, you read the user space in chunks. Each chunk starts at offset+(current zero-based entry number * size of each entry) and runs for the length of the entry size.
Looking at the results from QUSLSPL
Each entry in the list returned from QUSLSPL for format SPLF0200 has two parts. The first 4 bytes hold a count of fields returned. Then it has the field data structure repeated for each field. The size of the field data structure is variable. You have to loop through it for each field, look at the field key, and use that determine which value got returned. The end result is a two-level loop. The outer loop cycles through each spooled file entry. The inner loop cycles through each field returned in the SPLF0200 format.
Here is some sample code, based on your original question. Some notes, first:
Also note that I altered the parameters slightly to bring up the current user's spooled files because, in testing this sample, I didn't want to have to generate spooled data within the current job.