Professional Documents
Culture Documents
I know you have a programmer in the building that says " These punch cards were good enough for
me in the 70’s so there good enough for me now. This is for them slip a couple lines of Free Format
RPG into their source and watch their heads explode.
If nothing else, this will give you a taste of other languages, cause believe it or not, the time is
coming/here when those PC type languages are going to slowly replace our beloved RPG.
The only two lines of code that must start in a specific position are the compiler directives /FREE
and /END-FREE, which begin in column 7. The lines in between can use any columns between 8 and
80, allowing you to logically indent your code as we did here. Notice that even operations like Read,
Dsply and BegSR can be used in free format.
Each statement ends with a semicolon. That is something you?ll forget many times before it
becomes natural to you. You are still limited to one op-code per line, which is probably a good idea,
but statements can span multiple lines if necessary.
Supported Opcodes
Op-Code Purpose
ACQ Acquire device
BEGSR Begin Subroutine
CALLP Call Prototyped Procedure or Program
CHAIN Retrieve Record by key
CLEAR Clear
CLOSE Close File
COMMIT Commit Database changes
DEALLOC Release Dynamically Allocated Storage
DELETE Delete Record
DOU Do Until
DOW Do While
DSPLY Display message
DUMP Dump Program
ELSE Else
ELSEIF Else If
ENDyy End a Structured Group (where yy = DO, FOR, IF,
MON, SL, or SR)
EVAL Evaluate expression
EVALR Evaluate expression and right adjust result
EXCEPT Perform Exception Output
EXFMT Write/Then Read Format from display
EXSR Execute Subroutine
FEOD Force End of Data
FOR For
FORCE Force specified file to be read on next Cycle
IF If
IN Retrieve a Data Area
ITER Iterate
LEAVE Leave a Do/For Group
LEAVESR Leave a Subroutine
MONITOR Begin a Monitor Group
NEXT Next
ON-ERROR Specify errors to handle within MONITOR group
OPEN Open File for Processing
OTHER Start of default processing for SELECT group
OUT Write Data Area
POST Post
READ Read a record
READC Read next changed record
READE Read next record with equal Key
READP Read prior record
READPE Read prior record with equal Key
REL Release
RESET Reset
RETURN Return to Caller
ROLBK Roll Back uncommitted database changes
SELECT Begin a Select Group
SETGT Position database to record with key greater
than specified key
SETLL Position database to record with key not
greater than specified key
SORTA Sort an Array
TEST Test Date/Time/Timestamp
UNLOCK Unlock a Data Area or Release a Record
UPDATE Modify Existing Record
WHEN Condition test within SELECT group
WRITE Write New Record
*Inlr = *On ;
/End-Free
C*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
C* *Inzsr - Initial one time run subroutine.
C*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
CSR *Inzsr Begsr
C*
C*
C Endsr
C*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
C*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
C* Read entire file free format
C*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
/free
/end-free
C*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
C* Free format keylist processing
C*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
V5R2
C*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
C* Free format call a prototype
C*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
/FREE
READ somefile;
DOW Not %EOF(somefile);
RecordCount = RecordCount + 1;
If RecordCount = MaxPage;
Leave; // Max records reached so exit loop
Else;
READ somefile;
EndIf;
C*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
C* Free format elseif process
C*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
/free
Dsply 'Display this message';
If Not %Eof(MyFile);
Read MyFile;
ElseIf RecordCount > *Zero;
ProcessTotals();
EndIf;
/end-free
C*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
C* Free Format %dec and %decpos
C*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
d character1 S 5 inz('12345')
d character2 S 5 inz('1 3 5')
d character3 S 5 inz('1234w')
d signed S 5S 0 inz(12345)
d packed S 5 0
d*----------------------------------------------------------
/free
// assign characters '12345' to a packed numeric
packed = %dec(character1:5:0) ; // packed = 12345
/end-free
D arr1d S 20 DIM(10)
D table S 10 DIM(20) ctdata
D mds DS 20 occurs(30)
D num S 5p 0
* like_array will be defined with a dimension of 10.
* array_dims will be defined with a value of 10.
D like_array S like(arr1d) dim(%elem(arr1d))
D array_dims C const (%elem (arr1d))
/free
num = %elem (arr1d); // num is now 10 ;
num = %elem (table); // num is now 20 ;
num = %elem (mds); // num is now 30 ;
Eval *inlr = *on ;
/end-free
/end-free
/free
DailyTotal = 0;
Date8a0 = %Char(%Date():*USA0);
BirthDate = %DATE(BirthYMD:*USA);
DaysOld = %DIFF(Today:BirthDate:*DAYS);
DaysOld = %DIFF(%DATE() :
%DATE(BirthYMD:*USA) :
*DAYS);
DateNumeric = %UNS(%CHAR(Date:*ISO0));
// no more EVAL
dataBaseField = screenField;
*inlr = *On;
// no more CALLP
$CopyNotes( Scr_OrgOrd : Scr_Ord# );
// julian dates
LongJulA = %Char(%Date(DMY:*DMY):*LongJul0) ;
// for loops
For Index = StartVal To EndVal By IncVal;
ExSr Process;
EndFor;
// Error Extension
Chain(E) SlcKey Master;
Select;
When %Error;
MasterIOErr();
When Not %Found( Master );
MasterNFnd();
Other;
ProcMaster();
EndSl;
// divide and remainder
quote = %div( total : count );
remain = %rem( total : count );
/Free
/Free
Dou %EOF(TimeRecord);
// Process all time records
Read(e) TimeRecord;
// Get next time record
Select;
When %EOF(TimeRecord);
Leave;
When %ERROR;
Dsply 'Error reading time records.';
Leave;
Other;
Chain(ne) EmployeeID Employees;
Select;
When %ERROR;
Dsply 'Error reading employees.';
Leave;
When not %FOUND;
Dsply 'Employee not found.';
Iter;
Endsl;
TotalPay = (RegHours * Rate)
+ (OvtHours * Rate * 1.5)
+ (DblHours * Rate * 2);
FedTax =
CalcTaxes('FED':EmployeeID:TotalPay);
FICATax =
CalcTaxes('FICA':EmployeeID:TotalPay);
StateTax =
CalcTaxes(EmpState:EmployeeID:TotalPay);
UpdateTimeRecord();
Endsl;
Enddo;
*INLR = *ON;
Return;
/End-Free
monitor;
myNumFld = %dec(myCharFld: 7: 2);
on-error;
myNumFld = 0;
msg = 'Invalid number! Try again';
endmon;
TempDate = %subst(s2NewOvr:1:8);
test(de) *usa0 TempDate;
FARTRANSACT IF E K DISK
*
D KeyStruct DS
LikeRec(ARRECORD:*KEY)
*
/free
. . .
KeyStruct.ARcompany = ScreenComp;
KeyStruct.ARcustomer = ScreenCust;
Setll %kds(KeyStruct:2) ARTRANSACT; // Set
file-ptr
Dou %eof(ARTRANSACT); // Loop through invoices
ReadE %kds(KeyStruct:2) ARTRANSACT;
If not %eof(ARTRANSACT);
// Process an invoice for this Company/Cust
group
Endif;
Enddo;
. . .
The above example picks up company and customer number
values from another
file, possibly a display device file, and puts them in
the appropriate
qualified data structure subfields. Now, the key data
structure can be used on
the SETLL, READE, or other operations. A partial key
is used in this example
to access all invoices for a specified company and
customer.
Question:
When doing a divide in freeform, how do I use half-
adjust?
Answer:
Try the %INTH or %DECH Bifs
ie,
x=%INTH(5/3);
Here x will be 2
If Overflow;
Exsr WriteHeadings;
Overflow = *Off;
EndIf;
Posted by: /Free Test date
if %parms < 4;
*inlr = *on;
return;
endif;
D generalInformation...
D Pr
D programmerInformation...
D Pr
***********************************
* write programmer information
***********************************
P programmerInformation...
P B
d programmerInformation...
d Pi
P programmerInformation...
P E
Posted by: Gurmeet Singh/built-in function : %replace/%check/
var3 = %dec(var1:5:0) ;
evalr var4 = %char(var3) ;
var2 = %replace(%triml(var4):var2:%check('
':var4)) ;
dsply var2 ;
*inlr = *on ;
/end-free
*==================================================================*
/free
BegSr Subr30;
//Omit Cancelled
If AFDSTTS ='C';
Reade (P#VIN:P#Fran) VHLAFVD10;
iter;
Endif;
WsRecCnt = WsRecCnt+1;
If WsRecCnt = 1;
SteWobr = WsWoBr;
SteWoPx = WsWoPx;
SteWoNo = WsWoNo;
SteWoDt = WsTmstamp;
WsIso = %date(SteWodt);
WsWoDt = WsIso;
Update RfStkExt;
//%Found(VhlVprm1)
Endif;
//SteWono<=0
//W1Wono=0
Else;
WsWoBr = SteWoBr;
WsWoPx = SteWoPx;
WsWoNo = SteWoNo;
WsIso = %date(SteWodt);
WsWoDt = WsIso;
// Update Work order no in Accessory fitment
file le
ExSr Subr45;
//W1Wono=0
Endif;
//%found(VhlStkExt1)
Endif;
RrVin=StVin;
RrWoNo =%trim(StFran)+'/'+
%trim(%Editc(WsWoBr:'4')) +'/'+
%trim(WsWoPx)+'/'+
%trim(%Editc(WsWoNo:'4'));
// Print details
Write RrVm0121;
//%found(VhlSto36)
Endif;
//WsRecCnt = 1
Endif;
Write RrVm0122;
Reade (P#VIN:P#Fran) Vhlafvd10;
//Not %Eof(VhlAfVd10)
EndDo;
//Subr30
EndSr;
/End-Free