Contributor: PEDRO EISMAN
UNIT U123; {Soure PC MAG. DECEMBER 13 1988... and others}
 { YES ! I did it in TP seven years Ago !!!}
INTERFACE
{
This routines ARE simple to use as 123.. :-)
1) Open the file
2) Add what you want.. where you want
3) Close the File
}
PROCEDURE Open123(n:string);
PROCEDURE Close123;
PROCEDURE ColW123(c:integer; a:byte);
PROCEDURE Add123Int(c,f:integer; v:integer);
PROCEDURE Add123Rea(c,f:integer; v:double);
PROCEDURE Add123TXC(c,f:integer; v:string);
PROCEDURE Add123TXL(c,f:integer; v:string);
PROCEDURE Add123TXR(c,f:integer; v:string);
PROCEDURE Add123FML(c,f:integer; s:string);
{
 Open123(n:string);
 n = File Name WITHOUT EXTENSION it ALways add WK1
 It didn't check for a valid File Name or Existing, is
 YOUR responsability to do that
 Close123;
 Close the Open File .. Always DO THIS !
 In the rest of PROCEDURES c=Column and f=Row
 c and F begins with 0 (cero)
 if you want to Add in cell A1, use c=0 f=0
 if you want to Add in cell B2, use c=1 f=1
 etc.
 Add123Int(c,f:integer; v:integer);
 Add a Integer value (v) in Col=c Row=f
 Add123Rea(c,f:integer; v:double);
 Add a Double value (v) in Col=c Row=f
 Add123TXC(c,f:integer; v:string);
 Add a Label (v) in Col=C Row=f
 - Label CENTER -
 Add123TXR(c,f:integer; v:string);
 Add a Label (v) in Col=C Row=f
 - Label at RIGHT -
 Add123TXL(c,f:integer; v:string);
 Add a Label (v) in Col=C Row=f
 - Label at LEFT -
 ColW123(c:integer; a:byte);
 Change width of Col=c to size=a
 Add123FML(c,f:integer; s:string);
 Add Formula (s) at Col=c Row=f
 Examples:
 Add123FML(0,0,'A5+B2+A3*C5');
 Add123FML(0,1,'@Sum(B1..B8)');
 ==========================================
 THE ONLY VALID @ function is SUM !!!!
 Sorry :-(
 ==========================================
}
{ The rest of Comments are in SPANISH ... Sorry again }
IMPLEMENTATION
CONST
 C00 = 00ドル;
 CFF = $FF;
VAR
 ALotus : File;
PROCEDURE Open123(n:string);
Type
 Abre = record
 Cod : integer;
 Lon : integer;
 Vlr : integer;
 end;
Var
 Formato : array[1..6] of byte;
 Registro : Abre absolute Formato;
Begin
 Assign(ALotus,n+'.WK1');
 Rewrite(ALotus,1);
 with Registro do
 begin
 Cod:=0;
 Lon:=2;
 Vlr:=1030;
 end;
 BlockWrite(ALotus,Formato[1],6);
End;
PROCEDURE Close123;
Type
 Cierra = record
 Cod : integer;
 Lon : integer;
 end;
Var
 Formato : array[1..4] of byte;
 Registro : Cierra absolute Formato;
Begin
 with Registro do
 begin
 Cod:=1;
 Lon:=0;
 end;
 BlockWrite(ALotus,Formato[1],4);
 Close(ALotus);
End;
PROCEDURE ColW123(c:integer; a:byte);
Type
 Ancho = record
 Cod : integer;
 Lon : integer;
 Col : integer;
 Anc : byte;
 end;
Var
 Formato : array[1..7] of byte;
 Registro : Ancho absolute Formato;
Begin
 with Registro do
 begin
 Cod:=8;
 Lon:=3;
 Col:=c;
 Anc:=a;
 end;
 BlockWrite(ALotus,Formato[1],7);
End;
PROCEDURE Add123Int(c,f,v:integer);
Type
 Entero = record
 Cod : integer;
 Lon : integer;
 Frm : byte;
 Col : integer;
 Fil : integer;
 Vlr : integer;
 end;
Var
 Formato : array[1..11] of byte;
 Registro : Entero absolute Formato;
Begin
 with Registro do
 begin
 Cod:=13;
 Lon:=7;
 Frm:=255;
 Fil:=f;
 Col:=c;
 Vlr:=v;
 end;
 Blockwrite(ALotus,Formato[1],11);
End;
PROCEDURE Add123Rea(c,f:integer; v:double);
Type
 Entero = record
 Cod : integer;
 Lon : integer;
 Frm : byte;
 Col : integer;
 Fil : integer;
 Vlr : double;
 end;
Var
 Formato : array[1..17] of byte;
 Registro : Entero absolute Formato;
Begin
 with Registro do
 begin
 Cod:=14;
 Lon:=13;
 Frm:=2 or 128;
 Fil:=f;
 Col:=c;
 Vlr:=v;
 end;
 Blockwrite(ALotus,Formato[1],17);
End;
PROCEDURE GrabaTXT(c,f:integer; v:string; t:char);
Type
 Entero = record
 Cod : integer;
 Lon : integer;
 Frm : byte;
 Col : integer;
 Fil : integer;
 Vlr : array[1..100] of char;
 end;
Var
 Formato : array[1..109] of byte;
 Registro : Entero absolute Formato;
 i : word;
Begin
 with Registro do
 begin
 Cod:=15;
 Lon:=length(v)+7;
 Frm:=255;
 Fil:=f;
 Col:=c;
 Vlr[1]:=t;
 for i:=1 to Length(v) do Vlr[i+1]:=v[i];
 Vlr[i+2]:=chr(0);
 end;
 Blockwrite(ALotus,Formato[1],length(v)+11);
End;
PROCEDURE Add123TXL(c,f:integer; v:string);
begin
 GrabaTXT(c,f,v,'''');
end;
PROCEDURE Add123TXC(c,f:integer; v:string);
begin
 GrabaTXT(c,f,v,'^');
end;
PROCEDURE Add123TXR(c,f:integer; v:string);
begin
 GrabaTXT(c,f,v,'"');
end;
PROCEDURE Add123FML(c,f:integer; s:string);
Type
 Formula = record
 Cod : integer; {codigo}
 Lon : integer; {longitud}
 Frm : byte; {formato}
 Col : integer; {columna}
 Fil : integer; {fila}
 Res : Double; {resultado de formula}
 Tma : integer; {tamanio de formula en bytes}
 Fml : array[1..2048] of byte; {formula}
 end;
 symbol = (cel,num,arr,mas,men,por,dvs,pot,pa1,pa2);
 consym = set of symbol;
Var
 Formato : array[1..2067] of byte;
 Registro : Formula absolute Formato;
 fabs : boolean; {flag que indica si ffml es absoluta}
 v, {v = string 's' sin blancos}
 nro : string; {nro = numero de ffml}
 cfml, {cfml = valor de columna en formula}
 ffml : word; {ffml = " " fila " " }
 nfml, {nfml = " " constante " " }
 i, {i = indice de 'v' (formula) }
 ii, {ii = " " 's' " }
 index, {index= " " Fml}
 j,ret, {usados para convertir a numeros}
 len, {len = longitud de 'v'}
 lens : integer; {lens = " " 's'}
 sym : symbol; {sym = ultimo simbolo leido}
 symsig, {usados para analizar formula para }
 syminifac : consym; {grabarla con notacion posfija }
 z : byte; {indice para inicializar array}
 Procedure CalculaDir(var Reg : Formula);
 var
 veces : integer;
 (* Primero, se decide si cfml es absoluta o relativa. Si es absoluta
 calcula el valor real. Si es relativa primero chequea si cfml=i) do
 begin
 cfml:=(cfml+1)*26+ord(v[i])-ord('A');
 inc(i);
 end;
 end
 else
 begin
 if (ord(v[i])-ord('A') < col) then begin cfml:=49152-col+(ord(v[i])-ord('A')); inc(i); veces:=1; while (v[i] in ['A'..'Z']) and (len>=i) do
 begin
 cfml:=49152-col+(26*veces)+(ord(v[i])-ord('A'));
 cfml:=cfml+((ord(v[i-1])-ord('A'))*26);
 inc(i);
 inc(veces);
 end;
 end
 else
 begin
 cfml:=ord(v[i])-ord('A');
 inc(i);
 while (v[i] in ['A'..'Z']) and (len>=i) do
 begin
 cfml:=(cfml+1)*26+ord(v[i])-ord('A');
 inc(i);
 end;
 cfml:=cfml+32768-col;
 end;
 end;
 Fml[index]:=Lo(cfml); {graba cfml}
 inc(index); {que posee }
 Fml[index]:=Hi(cfml); {dos bytes }
 inc(index);
 if v[i]='$' then {calcula la fila (ffml)}
 begin
 inc(i);
 fabs:=true;
 end
 else
 fabs:=false;
 j:=i;
 while (v[i] in ['0'..'9']) and (len>=i) do
 begin
 inc(i);
 end;
 nro:=copy(v,j,i-j);
 val(nro,ffml,ret);
 if fabs then {siempre se resta 1 por estar en base 0}
 begin
 if ffml>0 then ffml:=ffml-1;
 end
 else
 begin
 if fil=i) do
 begin
 if v[i]='.' then esreal:=true;
 inc(i);
 end;
 nro:=copy(v,j,i-j);
 {R-}
 val(nro,numero,codigo);
 {R+}
 if (codigo=0) and (numero>=-32768) and (numero<=32767) then esreal:=false else esreal:=true; if esreal then begin val(nro,d,ret); {convierte en real doble} dfml:=d; {ConvRD(d,dfml);} Fml[index]:=0; {0 = indica que sigue una constante} inc(index); { real doble precision (8 bytes)} for k:=1 to 8 do begin Fml[index]:=VDoble[k]; {graba dfml} inc(index); {son ocho bytes} end; end else begin val(nro,nfml,ret); {convierte en entero} Fml[index]:=5; {5 = indica que sigue una constante } inc(index); { entera con signo (2 bytes) } Fml[index]:=Lo(nfml); {graba nfml} inc(index); {son dos bytes} Fml[index]:=Hi(nfml); inc(index); end; dec(i); end; end; Procedure CalculaRan(var Reg : Formula); begin with Reg do begin Fml[index]:=2; {2 = codigo de rango; le sigue 8 bytes} inc(index); { que son (col1fil1..col2fil2) } CalculaDir(Reg); {calcula col1fil1} i:=i+2; {salta los 2 .. } CalculaDir(Reg); {calcula col2fil2} end; end; Procedure CalculaArr(var Reg : Formula); {** SOLO CODIFICA @TRUE,@FALSE,@SUM(COL1FIL1..COL2FIIL2) **} var func,dir : string; {func = string del @} {dir = del rango} N_arg,nc : byte; {N_arg = cantidad de argumentos} {nc = numero de codigo (T,F,S)} begin with Reg do begin inc(i); case v[i] of 'F' : nc:=51; 'T' : nc:=52; 'S' : nc:=80; end; while (v[i] in ['A'..'Z']) and (len>=i) do inc(i);
 inc(i);
 if nc=80 then
 begin
 CalculaRan(Reg); {calcula el rango (col1fil1..col2fil2}
 N_arg:=1; {hay un solo argumento}
 end;
 Fml[index]:=nc;
 inc(index);
 if nc=80 then
 begin
 Fml[index]:=N_arg; {graba numero de argumentos}
 inc(index);
 end;
 end;
 end;
 Procedure TraerChar;
 begin
 inc(i); {carga el simbolo para }
 if len>=i then {la recursividad }
 begin
 case v[i] of
 'A'..'Z','$' : sym:=cel;
 '0'..'9','.' : sym:=num;
 '@' : sym:=arr;
 '+' : sym:=mas;
 '-' : sym:=men;
 '*' : sym:=por;
 '/' : sym:=dvs;
 '^' : sym:=pot;
 '(' : sym:=pa1;
 ')' : sym:=pa2;
 end;
 end;
 end;
 Procedure Expresion(symsig : consym; var Reg : Formula);
 var
 opsuma:symbol;
 Procedure Termino(symsig : consym; var Reg : Formula);
 var
 opmul:symbol;
 Procedure Factor(symsig : consym; var Reg : Formula);
 var
 opexp:symbol;
 Procedure Exponente(symsig : consym; var Reg : Formula);
 begin{Exponente}
 while (sym in syminifac) and (len>=i) do
 begin
 case sym of
 num : begin
 CalculaNum(Registro);
 TraerChar;
 end;
 cel : begin
 Reg.Fml[index]:=1;
 inc(index);
 CalculaDir(Registro);
 dec(i);
 TraerChar;
 end;
 arr : begin
 CalculaArr(Registro);
 TraerChar;
 end;
 else
 begin
 if sym=pa1 then
 begin
 TraerChar;
 Expresion([pa2]+symsig,Registro);
 if sym=pa2 then
 begin
 Reg.Fml[index]:=4; {4 = simbolo '(' }
 inc(index);
 TraerChar;
 end;
 end;
 end;
 end;
 end;
 end;{Exponente}
 begin{Factor}
 Exponente(symsig+[pot],Registro);
 while (sym=pot) and (len>=i) do
 begin
 opexp:=sym;
 TraerChar;
 Exponente(symsig+[pot],Registro);
 if opexp=pot then
 begin
 Reg.Fml[index]:=13; {13 = simbolo '^' }
 inc(index);
 end;
 end;
 end;{Factor}
 begin{Termino}
 Factor(symsig+[por,dvs],Registro);
 while (sym in [por,dvs]) and (len>=i) do
 begin
 opmul:=sym;
 TraerChar;
 Factor(symsig+[por,dvs],Registro);
 if (opmul=por) or (opmul=dvs) then
 begin
 if opmul=por then Reg.Fml[index]:=11 {11 = simbolo '*' }
 else
 Reg.Fml[index]:=12; {12 = simbolo '/' }
 inc(index);
 end;
 end;
 end;{Termino}
 begin{Expresion}
 (* Este es el primero de cuatro procedimientos recursivos (Expresion,
 Termino, Factor y Exponente) que se usan para transformar la formula
 en una expresion en notacion posfija, tal como se debe grabar. La
 tecnica consiste en retrasar la transmision del operador aritmetico.
 Ejemplo: a+(b*c)^d ==> abc*(d^+ .
 Expresion analiza si es suma o resta. Luego llama a Termino. Al
 volver trae el proximo dato y llama otra vez a Termino. Al volver
 genera el codigo de suma o resta si hubo.
 Termino llama a Factor. Al volver trae el proximo dato y llama otra
 vez a Factor. Al volver genera el codigo de multiplicacion o division
 si hubo.
 Factor llama a Exponente. Al volver trae el proximo dato y llama
 otra vez a Exponente. Cuando vuele genera el codigo de exponenciacion
 si hubo.
 Exponente analiza si el valor es un numero, una celda, un arroba o
 un parentesis. Si es un parentesis, vuelve a llamar a Expresion para
 calcular el contenido este; sino genera el codigo correspondiente.
 *)
 if sym in [mas,men] then
 begin
 opsuma:=sym;
 TraerChar;
 Termino(symsig+[mas,men],Registro);
 if opsuma=men then
 begin
 Reg.Fml[index]:=8; {8 = simbolo '-' unario}
 inc(index);
 end;
 end
 else
 Termino(symsig+[mas,men],Registro);
 while (sym in [mas,men]) and (len>=i) do
 begin
 opsuma:=sym;
 TraerChar;
 Termino(symsig+[mas,men],Registro);
 if (opsuma=mas) or (opsuma=men) then
 begin
 if opsuma=mas then Reg.Fml[index]:=9 { 9 = simbolo '+' }
 else
 Reg.Fml[index]:=10; {10 = simbolo '-' }
 inc(index);
 end;
 end;
 end;{Expresion}
Begin
 with Registro do
 begin
 Cod:=16; {16= formula}
 Col:=c;
 Fil:=f;
 Frm:=0; {Comienzo con 0}
(*
 if p=true then Frm:=Frm+128; {Si se protege se prende el MSB}
 ch:=UpCase(ch); {Veo que formato se quiere y prendo }
 {los bits respectivos }
 case ch of
 'F' : Frm:=Frm+ 0; {'F' ==> decimales fijos }
 'S' : Frm:=Frm+ 16; {'S' ==> notacion cientifica}
 'C' : Frm:=Frm+ 32; {'C' ==> moneda corriente }
 'P' : Frm:=Frm+ 48; {'P' ==> porcentaje }
 'M' : Frm:=Frm+ 64; {',' ==> miles con comas }
 'O' : Frm:=Frm+112; {'O' ==> otros }
 end;
 Frm:=Frm+d; {Si ch'O' ==> d= cant. de decimales}
 {Si ch= 'O' ==> d= 1 --> general }
 { 2 --> DD/MMM/AA }
 { 3 --> DD/MMM }
 { 4 --> MM/AA }
 { 5 --> texto }
 { 6 --> hidden }
 { 7 --> date; HH-MM-SS}
 { 8 --> date; HH-MM }
 { 9 --> date; int'l 1 }
 { 10 --> date; int'l 2 }
 { 11 --> time; int'l 1 }
 { 12 --> time; int'l 2 }
 { 13-14 --> no utilizado}
 { 15 --> default }
 *)
 Res:=C00;
{ for z:=1 to 8 do Res[z]:=C00;} {se modifica automaticamente cuando se recalcula y regraba}
 lens:=length(s); {convierto todo a mayusculas}
 for ii:=1 to lens do s[ii]:=UpCase(s[ii]);
 i:=1;
 v:='';
 for ii:=1 to lens do {paso el string 's' al string 'v' }
 begin {eliminando los espacios en blanco}
 if s[ii]' ' then
 begin
 v:=v+s[ii];
 inc(i);
 end;
 end;
 len:=i-1;
 i:=0;
 index:=1;
 syminifac:=[cel,num,arr,pa1];
 symsig:=syminifac;
 TraerChar; {toma el primer caracter de formula}
 Expresion(symsig,Registro); {analiza y graba toda la formula}
 Fml[index]:=3; {3 = fin de formula}
 Tma:=index; {tamanio de Fml}
 Lon:=15+Tma; {longitud de dato}
 BlockWrite(ALotus,Formato[1],19+index);
 end;
End;
END.


AltStyle によって変換されたページ (->オリジナル) /