|
If all the "file fields" are located in the sub-procedure, the fields are never populated on my chain...
In traditional RPG file access, data is read from a file into fields using a mechanism called "input specs". These input specs are put at the top of your code, and they tell the RPG runtime how data in the record is to be mapped into fields in your program.
Even if you're using an externally defined file, and you don't code any input specs, the system will generate them for you. So there will still be input specs (look at the compile listing!) even though you didn't type them.
The problem is, input specs are always at the top of your code. You can't put input specs in a subprocedure! Therefore, they're never able to read data into a variable that exists in the subprocedure.
As a consequence, the following code won't work: FCUSTMAS IF E K DISK . . P Cust_GetCity B export D Cust_GetCity PI 15A D CustNo 4P 0 value D City s 15A /free chain CustNo CUSTMAS; if not %found; return *Blanks; else; return City; endif; /end-free P EEven though City is a valid field in the CUSTMAS file, it won't work because I have it defined in the subprocedure. Variables that are defined inside a subprocedure are just like variables defined in a completely different prgoram -- they're only available from within that one subprocedure, they're not avialable elsewhere.
Since the input specs that the system generates for this file won't be able to read into the subprocedure's "City" variable, the code above will ALWAYS return blanks, whether the chain succeeds or fails.
The solution is relatively simple, though: Don't name variables in the procedure the same as the ones in the file, and you'll be all set. For example, consider this code:
P Cust_GetCity B export D Cust_GetCity PI 15A D CustNo 4P 0 value D myCity s 15A /free chain CustNo CUSTMAS; if not %found; return *Blanks; else; myCity = City; return myCity; endif; /end-free P ESince myCity is defined in the subprocedure, and City is defined outside the subprocedure, there's no conflict, and the routine will work.
Is there a way around this? I tried using an external DS, but that didn't seem to work either...
Starting in V5R2, you can read directly into a data structure. This bypasses the input specs completely, and just loads the data from the record straight into a data structure. Using that technique, you can read into fields that are defined in the procedure. For example:
FCUSTMAS IF E K DISK // Note: CUSTMAS's record format name is "CUSTMASF" . . P Cust_GetCity B export D Cust_GetCity PI 15A D CustNo 4P 0 value // You must use the record format name with LIKEREC. D CustRec DS likerec(CUSTMASF:*INPUT) /free if not %open(CUSTMAS); open CUSTMAS; endif; // Note: You must use the record format name on the CHAIN // operation. chain CustNo CUSTMASF CustRec; if not %found; return *Blanks; else; return CustRec.City; endif; /end-free P ENote that this isn't the same as an "external DS". (A data structure declared with EXTNAME)
As an Amazon Associate we earn from qualifying purchases.
This mailing list archive is Copyright 1997-2024 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].
Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.