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.
Sé que tienes un programador en el edificio que dice:
"Estas tarjetas perforadas fueron lo suficientemente buenas para mí en
los años 70, así que ahora son lo suficientemente buenas para mí. Esto es
para ellos deslizar un par de líneas de Free Format
RPG en su fuente y mirar sus cabezas explotar.
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.
Si nada más, esto te dará una idea de otros lenguajes,
porque lo creas o no, llegará el momento / aquí cuando los lenguajes tipo de
PC van a reemplazar lentamente nuestro querido juego de rol.
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.
Las dos únicas líneas de código que deben comenzar en
una posición específica son las directivas de compilación / FREE y /
END-FREE, que comienzan en la columna 7. Las líneas intermedias pueden usar
cualquier columna entre 8 y 80, lo que le permite indentificar
lógicamente su código como lo hicimos aquí. Tenga en cuenta que incluso las
operaciones como Read, Dsply
y BegSR se pueden usar en formato libre.
Cada declaración termina con un punto y coma. Eso es
algo que olvidará muchas veces antes de que se vuelva natural para usted.
Todavía está limitado a un código de operación por línea, lo que
probablemente sea una buena idea, pero las declaraciones pueden abarcar
varias líneas si es necesario.
Supported Opcodes
Op-CodePurpose
ACQ Acquire device Adquirirdispositivo
BEGSR Begin
SubroutineComience la subrutina
CALLP CallPrototypedProcedureorProgramLlamar a
un procedimiento o programa prototipado
CHAIN Retrieve
Record by key Recuperar registro por clave
CLEAR ClearClaro, limpiar
CLOSE Close FileCerrar el archivo
COMMIT CommitDatabasechangesCambios en la base de datos
DEALLOCReleaseDynamicallyAllocated Storage Liberar el almacenamiento asignado dinámicamente
DELETE Delete RecordEliminar el registro
DOU Do
UntilHacer hasta
DOW Do
WhileHacer mientras
DSPLY Display
messageMostrar mensaje
DUMP DumpProgramPrograma
de volcado
ELSE Else
en caso contrario
ELSEIF Else
IfSi no
ENDyyEnd a Structured Group (where
yy = DO, FOR, IF, MON, SL, or SR) Finalizar un grupoestructurado (dondeyy = DO, FOR, IF, MON, SL o SR)
EVAL EvaluateexpressionEvaluar la
expresión
EVALR Evaluateexpression and rightadjustresultEvaluar la
expresión y ajustar el resultado a la derecha
EXCEPT PerformException Output_Realizar salida de excepción
EXFMT Write/ThenReadFormatfromdisplayEscribir / Leer Formato de
la pantalla
EXSR ExecuteSubroutineEjecutar subrutina
FEOD ForceEnd of DataForzar fin
de datos
FOR Forpara
FORCE Forcespecified file to be readonnextCycleForzar
archivo especificado para leer en el siguiente ciclo
IFIfsi
INRetrieve a Data AreaRecuperar
un área de datos
ITER IterateIterar
LEAVE Leave
a Do/For Group Deja o salir de un Do / For
Group
LEAVESRLeave a SubroutineDeje o salir de una subrutina
MONITORBegin
a Monitor GroupComience
un grupo de monitoreo
NEXT NextSiguiente
ON-ERRORSpecify
errors to handle within MONITOR group Especifique los errores para
manejar dentro del grupo MONITOR
OPEN Open
File for ProcessingAbrirarchivo
para procesamiento
OTHER Start of default processing
for SELECT groupInicio del procesamientopredeterminado para el grupo
SELECT
OUT Write Data Area Escribir área de datos
POST PostEnviar
READ Read
a recordLee un registro
READC Readnextchanged
recordLeer el siguiente registro modificado
READE Readnext record withequal KeyLea el
siguiente registro con la misma clave
READP Read prior recordLeer el registro anterior
READPE Read prior record withequal KeyLea el registro anterior con
la misma clave
REL ReleaseLanzamiento
RESET ResetReiniciar
RETURN Return to CallerRegresar
al programa que llama
ROLBK Roll
Back uncommitteddatabasechangesDeshacer
los cambios de base de datos no confirmados
SELECT Begin
a Select Group Comienza
un grupo select
SETGT Position
database to record withkeygreaterthanspecifiedkeyColoque la base de datos
para grabar con una clave mayor que la especificada
SETLL Position
database to record withkeynotgreaterthanspecifiedkeyPosicionar la base de datos
para grabar con clave no mayor que la clave especificada
SORTA SortanArrayOrdenar una matriz
TEST Test Date/Time/TimestampFecha / hora de prueba /
marca de tiempo
UNLOCK Unlock a Data AreaorRelease a Record Desbloquee un área de datos
o libere un registro
UPDATE Modify
Existing RecordModificar el registro existente
WHEN Condition
test within SELECT group Prueba de condición dentro del
grupo SELECT
packed2 = %dech(signed:5:2);
// result is 73.74000
*inLR =
*ON;
/END-FREE
D packed1s7p 3 inz
(8236.567)
D signed1s9s 5 inz
(23.73442)
D result1s5i 0
D result2s5i 0
/FREE
result1 = %decpos
(packed1); //"result1"
is3
result2 = %decpos
(signed1); //"result2"
is5
*inLR = *ON;
/END-FREE
D arr1dS20DIM(10)
D tableS10DIM(20) ctdata
D mdsDS20occurs(30)
D numS5p 0
* like_array
will be defined with a dimension of 10.
* array_dims
will be defined with a value of 10.
D like_arraySlike(arr1d) dim(%elem(arr1d))
D array_dimsCconst
(%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
// assign signed to a packed numeric
packed = %dec(signed);
// nice try - an alpha here will crash
the program
packed = %dec(character3:5:0)
;// *CRASH*
*inlr= *on;
/end-free
Examples posted by visitors
Posted by: jamie
- move data in and out of an array
evalxx_cnfn = *blanks;
evalxx_cnln = *blanks;
idx1 = %scan(' ' : AuthName);
if %subst(AuthName : idx1 + 2 :
1) = '.';
eval
idx2 = idx1 + 4;
else;
if %subst(AuthName : idx1 + 2 : 1) <> *blank;
eval
idx2 = idx1 + 1;
else;
eval
idx2 = idx1 + 3;
endif;
endif;
evalfNameLen = idx2 - 1;
if fNameLen
> 10;
evalfNameLen = 10;
endif;
evallNameLen = (40 - idx2) + 1;
if lNameLen
> 25;
evallNameLen = 25;
endif;
evalxx_cnfn = %subst(AuthName : 1 : fNameLen);
evalxx_cnln = %subst(AuthName : idx2 : lNameLen);
Posted by: Jimmy - Read a file
/free
DailyTotal =
0;
setll (MyDate) INVHEADER;
reade (MyDate) INVHEADER;
dow not
%EOF(INVHEADER);
InvTotal
= 0;
setll (InvDate: InvNo) INVDETAILS;
reade (InvDate: InvNo) INVDETAILS;
dow not
%EOF(INVDETAILS);
InvTotal
+= Price * Qty;
reade
(InvDate: InvNo)
INVDETAILS;
enddo;
InvTotal
-= Discounts;
InvTotal
+= Taxes;
DailyTotal
+= InvTotal;
reade (MyDate) INVHEADER;
enddo;
/end-free
Posted by: mike noun - Get the
remainder of a division
It's often
useful to be able to get the remainder of a division operation. For
example, if you want to know the remainder of X divided by Y, you'd
traditionally code the following:
A menudo es útil poder
obtener el resto de una división
operación. Por ejemplo, si quiere
saber el resto de X dividido
por Y, tradicionalmente
codificaría lo siguiente:
CXDIVYUNUSED
CMVRR
With the %REM()
BIF, you no longer need to do division first -- and you no longer need to
define a variable that you don't need elsewhere. You can simply code this:
Con% REM () BIF, ya no
es necesario hacer divisiones primero, y ya no es necesario definir una
variable que no necesite en otro lugar. Usted puede simplemente codificar
esto:
Posted by: Use monitor to test
numeric in Free form
monitor;
myNumFld =
%dec(myCharFld: 7:
2);
on-error;
myNumFld =
0;
msg = 'Invalid number!Try again';
endmon;
Posted by: Jimmy - Test date in
free form
TempDate = %subst(s2NewOvr:1:8);
test(de) *usa0 TempDate;
Posted by: Another keylist example with data structure
Assume a
keyed data file ARTRANSACT, record name ARRECORD, has key fields
ARcompany, ARcustomer,
and ARinvoice, and many other non-key fields. Supongamos que un
archivo de datos con clave ARTRANSACT, nombre de registro ARRECORD, tiene
campos clave
ARcompany, ARcustomer,
y ARinvoice, y muchos otros campos no clave.
FARTRANSACTIFEKDISK
*
D KeyStructDSLikeRec(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.
El ejemplo anterior
recoge valores de compañía y número de cliente de otro archivo,
posiblemente un archivo de dispositivo de visualización, y los coloca en
el archivo apropiado
subcampos de estructura de datos
calificados. Ahora, la estructura de datos clave se puede usar en
SETLL, READE u otras
operaciones. Una clave parcial se usa en este ejemplo para acceder a
todas las facturas de una empresa y un cliente especificados.
Posted by: Martin Hillier /
half adjust in free form
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
Postedby: /Free Overflow:
FKCG700PROEPRINTER OFLIN (Overflow)
If Overflow;
ExsrWriteHeadings;
Overflow = *Off;
EndIf;
Postedby: /Free Test date
test(de)
*iso0 khsdat;
if %error;
exsrWriteError;
endif;
Postedby: /Free Test Time
@Timex = %subst(timey:1:2) + ':' +
%subst(timey:3:2)
+ ':' + '00';
test(et) *hms
@timex;
if %error;
exsrWriteError;
endif;
Postedby: / Free Checkparameters
if %parms < 4;
*inlr = *on;
return;
endif;
Posted by: chrishayden - really long procedure names
D generalInformation...
DPr
D programmerInformation...
DPr
// write general
information
generalInformation();
// write
programmer information
programmerInformation();
***********************************
* write programmer information
***********************************
P programmerInformation...
PB
dprogrammerInformation...
dPi
P programmerInformation...
PE
Posted by: Gurmeet
Singh/built-in function : %replace/%check/
var1 have value as '1'.
following code will give the result in var2 as
'00001'.
eg: if var1 =
'123' then var2 will be equal to
'00123'.
El siguiente código dará
el resultado en var2 como '00001'.
por ejemplo: si var1 =
'123' entonces var2 será igual a '00123'.
//ChainWithAccessoryFitmentHeader file to checkthe record status Cadena con archivo de encabezado de
equipamiento accesorio para verificar el estado del registro
Chain (P#VIN:P#FRAN) VhlAfvh10;
If %found(VhlAfvh10);
If AfhStts
<>'P';
//CreatingRec order
ExSr
Subr41;
ExSr
Subr42;
EndIf;
Else;
Return;
EndIf;
//Dow
while VIN/Fran are same
Setll
(P#VIN:P#Fran) VHLAFVD10;
Reade (P#VIN:P#Fran)
VHLAFVD10;
Dow Not %Eof(VhlAfVd10);
//Omit Cancelled
If AFDSTTS ='C';
Reade (P#VIN:P#Fran) VHLAFVD10;
iter;
Endif;
//If Processed then skip
If AFDSTTS ='P';
Reade (P#VIN:P#Fran) VHLAFVD10;
iter;
Endif;
If Afditty
<> 'L';
Reade (P#VIN:P#Fran) VHLAFVD10;
iter;
Endif;
// Spec code/Spec description
/spec code/fitment status
RrSpDs
= AfDsPdS;
RrSpCd
= AfdSpCd;
RrSts= Afdftst;
WsRecCnt
= WsRecCnt+1;
If WsRecCnt
= 1;
Chain (P#VIN) VhlSto36;
If %found(VhlSto36);
//Check Work order no is not generated;
then get no
//from paramater
file
Chain (P#VIN)
VhlStkExt1;
If %found(VhlStkExt1);
//If SteWoNo <=0;
If W1Wono =0;
//Get Work Order No.from Parameter file and Update
Chain (StFran:StBrCd:StYdCd:'WORD') VhlVprm1;
if
%found(VhlVpRm1);
VpDoNo = VpDoNo+1;
WsWoPx = VpDoPx;
WsWoNo = VpDoNo;
Update RfVpRm;
Chain (StFran:StBrCd:StYdCd)
Vhlafbr1;
if
%found(Vhlafbr1);
WsWoFr = Afbsefr;
WsWoBr = AfBsebr;
WsWoPx = AfBwopx;
Endif;
// Update
Work order no into stock file
SteWobr = WsWoBr;
SteWoPx = WsWoPx;
SteWoNo = WsWoNo;
SteWoDt
= WsTmstamp;
WsIso= %date(SteWodt);
WsWoDt = WsIso;
UpdateRfStkExt;
// Update Work
order no in Accessory fitment filele
// and Create New
record into VHFAFVW file
ExSr Subr44;
//%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 filele
ExSr Subr45;
//W1Wono=0
Endif;
//%found(VhlStkExt1)
Endif;
Chain (StFran:'FRAN':STFRAN) VhlCode1;
Chain (StFran:StMocd:StChcd:StMoyr) VhlModl1;
If %found(VhlModl1);
RrMoDs = %trim(cddesl) +' -
' +%trim(MmMoDs);
Endif;
Chain (StFran:WsClTy:StCeCd) VhlClr1;
If %found(VhlClr1);
RrClDs = CoClDs;
Endif;
RrVin=StVin;
RrWoNo
=%trim(StFran)+'/'+
%trim(%Editc(WsWoBr:'4')) +'/'+
%trim(WsWoPx)+'/'+ %trim(%Editc(WsWoNo:'4'));
//Subr40 to get Work
order date
ExSr
Subr40;
// Print details
WriteRrVm0121;
//%found(VhlSto36)
Endif;
//WsRecCnt
= 1
Endif;
WriteRrVm0122;
Reade (P#VIN:P#Fran)
Vhlafvd10;
//Not %Eof(VhlAfVd10)
EndDo;
//Subr30
EndSr;
/End-Free
Postedby: AjayNayakal
If we are
having width > 200 of Printer File. Then Use Following Parameters to
compile the Printer File.
Si tenemos ancho> 200
de archivo de impresora. Luego use los siguientes parámetros para
compilar el archivo de impresora.
a) Width=215 (or whatever the width is)
b) Length=96
c) LPI=12
d) CPI=15
e) OF=88
f) FONT = try first with *CPI and
then with font 281