Reputation: 1
I'm hoping you can help me with using data structures to improve code readability.
I am experimenting with the new fully free RPG and was able to get my program to work. The working program populates fields defined in an externally described file as brought in from the compiler. It takes a job name as an input parm and either write a new rec with the job's start time or updates the existing rec with the job's end time. It would be called just before and after some process executes to log the runtime.
I'm working with an old file with short names:
File Name JOBTIMES
rjobnm *char 10
rastim *packed 6 0
raetim *packed 6 0
I can get the program to do what I want, but I wanted to take it one step further. I was hoping to define a data structure with fields of the same size and type, but with more meaningful names, and use those fields in the body of the program to self-document a bit better.
Ultimately I couldn't get this to work. I had two problems.
First I had hoped to be able to rename the fields in the data structure corresponding to the file I wanted to update to longer names. I couldn't figure out how to do that, so I defined a separate data structure by hand with the same fields of the same types. I'm hoping there's a better way here.
Second I wanted to be able to write or update to my file using that new data structure, but that didn't work out either. Ultimately through an inelegant process, I could write, but I could not update. Trying to do both caused a compiler error with the *output vs *update being the sticking point.
I have some code that doesn't work though it gives the idea of what I wanted to do.
push data from the new fields into the file using an update or write in a simple way. The copy from one DS to the other was something I wanted to avoid if possible.
dcl-f JOBTIMES disk(*ext) usage(*update : *output) keyed;
dcl-s Now timestamp;
dcl-s currTime time(*hms);
dcl-ds FileKey likerec(jtfmt : *key)
dcl-ds FileDs extname'JOBTIMES' : *output) qualified;
end-ds;
dcl-ds UpdateFields; // was hoping to use overlay in FileDs.
JobName char(10); // compiler doesn't like.
StartTime packed(6 : 0);
EndTime packed(6 : 0);
end-ds;
dcl-pr RECORDTIME extpgm;
jobnam char(10);
end-pr;
dcl-pi RECORDTIME;
jobnam char(10);
end-pi;
Now = %timestamp();
currTime = %time(Now);
FileKey.rjobnm = jobnam;
chain %kds(FileKey) JOBTIMES;
if not %found;
JobName = jobman;
StartTime = %dec(currTime : *hms);
FileDs = UpdateFields;
write jtfmt FileDs; // would rather use UpdateFields here
else;
EndTime = %dec(currTime : *hms);
FileDs = UpdateFields;
update jtfmt FileDs; // would rather use UpdateFields here
endif;
return;
Is there some way to make this work, or should I just forget about renaming the fields from the external file? It's not a tough job if I settle for that.
Thanks all for your time.
Upvotes: 0
Views: 4053
Reputation: 23783
Old school answer would be to use I-Spec to rename the fields...but that would only give you a 14 character name. Slightly better would be to use D-Spec DS with EXTFLD.
Modern answer would be to assign the fields longs names using either DDS ALIAS()
keyword or SQL DDL. The thing to remember is you can assign long names without affecting anything existing as long as you leave the short system names alone; so no level checks for existing programs.
Then in your RPG program, simply add the ALIAS
keyword to your F-Spec and instead of pulling in the short names, the compiler will use the long names.
You can if you wish, create a DS for I/O using the LIKEREC()
or EXTNAME()
and ALIAS
keywords on the DS declaration.
Google RPGLE ALIAS
and you should find plenty of examples...
Upvotes: 4