Deprecated: Function get_magic_quotes_gpc() is deprecated in /home2/tonyso97/public_html/libraries/f0f/input/input.php on line 102

Deprecated: Function get_magic_quotes_gpc() is deprecated in /home2/tonyso97/public_html/libraries/f0f/input/input.php on line 102

Deprecated: Function get_magic_quotes_gpc() is deprecated in /home2/tonyso97/public_html/libraries/f0f/input/input.php on line 102
Procedures Firebird

CREATE PROCEDURE FU_ABS(
   WVAR DOUBLE PRECISION)
   RETURNS (
   R_ABS DOUBLE PRECISION)
   AS
   begin
   /*
   devolve o valor Absoluto de um número.
   -123,47 ou 123,47 devolve sempre 123,47
   */
   if (:wvar is not null) then begin
   if (:wvar < 0.0000) then
   r_abs = :wvar * -1;
   else
   r_abs = :wvar;
   end
suspend;
   end
===================================
   CREATE PROCEDURE FU_ALLTRIM(
   WVAR VARCHAR(8192))
   RETURNS (
   R_ALLTRIM VARCHAR(8192))
   AS
   DECLARE VARIABLE T SMALLINT;
   begin
   /*
   Devolve um string sem espaços
   */
   select r_Len from Fu_Len(:wvar) into :t;
   r_alltrim = '';
while ((:wvar is not null) and (:t > 0)) do begin
   if (substring(:wvar from 1 for 1) <> ' ') then
   r_alltrim = :r_alltrim || substring(:wvar from 1 for 1);
 wvar = substring(:wvar from 2 for 8191);
   t = :t - 1;
   end
suspend;
   end
====================================
   CREATE PROCEDURE FU_BEFORE_AFTER(
   WPES VARCHAR(8192),
   WVAR VARCHAR(8192),
   WTIP CHAR(1))
   RETURNS (
   WRET VARCHAR(8192))
   AS
   declare variable wint smallint;
   declare variable wlen smallint;
   begin
   /*
   Devolve os caracteres "Anteriores" ou "Posteriores" de
   um string tomando como base "WPES"
   */
   wtip = upper(:wtip);
   select result from Fu_Pos(:wpes, :wvar) into :wint;
if (:wtip = 'B') then     -- Before
   begin
   if (:wint = 0) then
   wret = wpes;
   else
   select r_Copy from Fu_Copy(:wvar, 1, (:wint - 1)) into :wret;
   end
   else begin                -- After
   if (:wint = 0) then
   wret = '';
   else begin
   select r_Len from Fu_Len(:wpes) into :wlen;
   select r_Copy from Fu_Copy(:wvar, (:wint + :wlen), 8191) into :wret;
   end
   end
suspend;
   end
================================================
   CREATE PROCEDURE FU_CENTRO(
   WSTR VARCHAR(8192),
   WTAM SMALLINT)
   RETURNS (
   R_CENTRO VARCHAR(8192))
   AS
   DECLARE VARIABLE I SMALLINT;
   DECLARE VARIABLE T SMALLINT;
   DECLARE VARIABLE S VARCHAR(8192);
   begin
   /*
   Devolve um string Centralizado Com o tamanho "WRAM"
   */
   select r_Len from Fu_Len(:wstr) into :t;
if (:t > :wtam) then
   select r_Copy from Fu_Copy(:wstr, 1, :wtam) into :r_centro;
   else if (:t = :wtam) then
   r_centro = :wstr;
   else begin
   select r_div from Fu_div((:wtam - :t), 2) into :i;
   select r_replicate from Fu_replicate(:i, ' ') into :s;
   wstr = :s || :wstr;
   select r_replicate from Fu_replicate(((:wtam - :t) - :i), ' ') into :s;
   r_centro = :wstr || :s;
   end
suspend;
   end
==============================================
   CREATE PROCEDURE FU_CLASS(
   WSTR VARCHAR(8192),
   WSUB VARCHAR(8192),
   WDEL CHAR(1),
   WORD CHAR(1))
   RETURNS (
   R_RET VARCHAR(8192))
   AS
   declare variable wpos smallint;
   declare variable tra1 varchar(8192);
   declare variable wfez smallint = 1;
   begin
   /*
   Insere "WSUB" em "WSTR" na ordem ascending ou
   descending (conforme "WORD"). "WSTR" deve estar delimitada por "WDEL" 
   */
   select result from Fu_pos(:wdel, :wstr) into :wpos;
   select r_copy from Fu_Copy(:wstr, 1, (:wpos - 1)) into :tra1;
if (:word = 'A') then                                               -- Ordem Ascending...
   begin
   if (:wsub < :tra1) then                                           -- Se já for a primeira
   r_ret = :wsub || :wdel || :wstr;                                 -- Concatenar
   else begin                                                        -- Senão...
   select r_last_pos from Fu_last_pos(:wdel, :wstr) into :wpos;        -- Última Posição do delimitador
   select r_copy from Fu_Copy(:wstr, (:wpos + 1), 8191) into :tra1;    -- Última String
 if (:wsub >= :tra1) then                                         -- Se for a última
   r_ret = :wstr || :wdel || :wsub;                                -- Concatenar
   else begin                                                       -- Senão
   select result from Fu_pos(:wdel, :wstr) into :wpos;                -- Posição do delimitador
   select r_copy from Fu_Copy(:wstr, 1, (:wpos - 1)) into :tra1;      -- Primeira String
   r_ret = :tra1 || :wdel;                                         -- ... e concatenar
   select r_copy from Fu_Copy(:wstr, (:wpos + 1), 8191) into :wstr;   -- STR resultante
 while (:wfez = 1) do begin                                      -- Enquanto não achar o lugar
   select result from Fu_pos(:wdel, :wstr) into :wpos;               -- Posição do delimitador ns STR resultante
 if (:wpos = 0) then                                            -- Se não tem mais...
   tra1 = :wstr;                                                 -- Inicializo :TRA1
   else                                                           -- Senão...
   select r_copy from Fu_Copy(:wstr, 1, (:wpos - 1)) into :tra1;    -- Defino
 if (:wsub <= :tra1) then                                       -- Comparo
   begin
   r_ret = :r_ret || :wsub || :wdel;                            -- Concateno se é o lugar
   select r_copy from Fu_Copy(:wstr, (:wpos + 1), 8191) into :wstr;-- STR resultante
   r_ret = :r_ret || :wstr;                                     -- Concateno o restante
   wfez = 0;                                                    -- Para sair do LOOP
   end
   else begin                                                     -- Senão...
   r_ret = :r_ret || :wdel || :tra1;                             -- concateno
   select r_copy from Fu_Copy(:wstr, (:wpos + 1), 8191) into :wstr; -- STR resultante
   end
   end
   end
   end
   end
   else begin                              -- Orden Descending...
   if (:tra1 < :wsub) then
   r_ret = :wsub || :wdel || :wstr;
   else begin
   select r_last_pos from Fu_last_pos(:wdel, :wstr) into :wpos;
   select r_copy from Fu_Copy(:wstr, (:wpos + 1), 8191) into :tra1;
 if (:tra1 >= :wsub) then
   r_ret = :wstr || :wdel || :wsub;
   else begin
   select result from Fu_pos(:wdel, :wstr) into :wpos;
   select r_copy from Fu_Copy(:wstr, 1, (:wpos - 1)) into :tra1;
   r_ret = :tra1 || :wdel;
   select r_copy from Fu_Copy(:wstr, (:wpos + 1), 8191) into :wstr;
 while (:wfez = 1) do begin
   select result from Fu_pos(:wdel, :wstr) into :wpos;
 if (:wpos = 0) then
   tra1 = :wstr;
   else
   select r_copy from Fu_Copy(:wstr, 1, (:wpos - 1)) into :tra1;
 if (:tra1 <= :wsub) then
   begin
   r_ret = :r_ret || :wsub || :wdel;
   select r_copy from Fu_Copy(:wstr, (:wpos + 1), 8191) into :wstr;
   r_ret = :r_ret || :wstr;
   wfez = 0;
   end
   else begin
   r_ret = :r_ret || :wdel || :tra1;
   select r_copy from Fu_Copy(:wstr, (:wpos + 1), 8191) into :wstr;
   end
   end
   end
   end
   end
suspend;
   end
================================================
   CREATE PROCEDURE FU_COPY(
   WVAR VARCHAR(8192),
   WINI INTEGER,
   WTAM INTEGER)
   RETURNS (
   R_COPY VARCHAR(8192))
   AS
   DECLARE VARIABLE I INTEGER;
   DECLARE VARIABLE J INTEGER;
   DECLARE VARIABLE K INTEGER;
   begin
   /*
   Copia de "WINI" "WTAM" bytes de "WVAR"
   Este recurso não é mais necessário no FB 2
   Pois já aceita o substring com variáveis
   */
   select r_Len from Fu_Len(:wvar) into :i;
   j = 1;
   k = 1;
   r_copy = '';
while ((:wvar is not null) and (:i > 0) and (j <= :wtam)) do begin
   if (:k >= :wini) then begin
   r_copy = :r_copy || substring(:wvar from 1 for 1);
   j = j + 1;
   end
 wvar = substring(:wvar from 2 for 8191);
   k = :k + 1;
   i = :i - 1;
   end
suspend;
   end
========================================
   CREATE PROCEDURE FU_CPA_PERI(
   PER1 VARCHAR(8),
   PER2 VARCHAR(8))
   RETURNS (
   R_CPA_PERI CHAR(1))
   AS
   begin
   /*
   Compara dois períodos (MM/AAAA) e devolve
   "<", ">" ou "=" conforme o caso
   */
   if ((:per1 is not null) and (:per2 is not null)) then begin
   if ((substring(:per1 from 4 for 4) || substring(:per1 from 1 for 2)) =
   (substring(:per2 from 4 for 4) || substring(:per2 from 1 for 2))) then
   r_cpa_peri = '=';
   else if ((substring(:per1 from 4 for 4) || substring(:per1 from 1 for 2)) >
   (substring(:per2 from 4 for 4) || substring(:per2 from 1 for 2))) then
   r_cpa_peri = '>';
   else if ((substring(:per1 from 4 for 4) || substring(:per1 from 1 for 2)) <
   (substring(:per2 from 4 for 4) || substring(:per2 from 1 for 2))) then
   r_cpa_peri = '<';
   end
suspend;
   end
===========================================
   CREATE PROCEDURE FU_CRIP(
   WSTR VARCHAR(1024),
   ACAO SMALLINT)
   RETURNS (
   R_STR VARCHAR(1024))
   AS
   DECLARE VARIABLE WS1 VARCHAR(255);
   DECLARE VARIABLE WS2 VARCHAR(255);
   DECLARE VARIABLE WLT CHAR(1);
   DECLARE VARIABLE WIN SMALLINT;
   DECLARE VARIABLE WLE SMALLINT;
   DECLARE VARIABLE WPO SMALLINT;
   begin
   /*
   Devolve um string criptografado se "ACAO" = 0
   senão descriptografa. Função bem CASEIRA
   */
   ws1 = ' [AaB1bC2(c+Ç3çD4dE5eF6fG7g)H8hI9iJ0jKk-LlMmNn]OoPpQqRrSsTtUuVvXxYyWwZz"!@#$%¨&*_´`{^~}|\<,>.:;?/' ||
   'éóúàèìòùêûâîôÁÉÍÓÚÀÈÌÒÙÃÕ¥¡¢£¤¦§¨©ª®°±²³µ•¸¹"¼¾¿ÅÆÏÐÑÖ×ÝÞö÷øýþ';
ws2 = 'éóúàèìòùêûâîôÁÉÍÓÚÀÈÌÒÙÃÕ¥¡¢£¤¦§¨©ª®°±²³µ•¸¹"¼¾¿ÅÆÏÐÑÖ×ÝÞö÷øýþ' ||
   ' AB0CÇ9DE8FG7HI6JK5LM4NO3PQ2RS1TUVXYWZabcçdefghijklmnopqrstuvxywz"!@#$%¨&*()_+´`{[^~}]|\<,>.:;?/-';
r_str = '';
   select r_Len from Fu_Len(:wstr) into :wle;
   win = 1;
if (:acao = 0) then -- Criptografa a string
   begin
   while (:win <= :wle) do begin
   select r_Copy from Fu_Copy(:wstr, :win, 1) into :wlt;
   select result from Fu_Pos(:wlt, :ws1) into :wpo;
 if (:wpo > 0) then
   select r_Copy from Fu_Copy(:ws2, :wpo, 1) into :wlt;
 r_str = :r_str || :wlt;
   win = :win + 1;
   end
   end
   else begin -- desfaz a criptografia
   while (:win <= :wle) do begin
   select r_Copy from Fu_Copy(:wstr, :win, 1) into :wlt;
   select result from Fu_Pos(:wlt, :ws2) into :wpo;
 if (:wpo > 0) then
   select r_Copy from Fu_Copy(:ws1, :wpo, 1) into :wlt;
 r_str = :r_str || :wlt;
   win = :win + 1;
   end
   end
suspend;
   end
=========================================
   CREATE PROCEDURE FU_CUBE(
   WNUM DOUBLE PRECISION)
   RETURNS (
   RAIZ DOUBLE PRECISION)
   AS
   declare variable parc double precision;
   declare variable wraz smallint = 3;
   begin
   /*
   Devolve a Raiz Cúbica de um número.
   Há uma tolerância em caso de inexato.
   */
   select sqr from Fu_sqrt(:wnum) into :parc;
while (:wraz > 2) do begin
   select sqr from Fu_sqrt(:parc) into :raiz;
   wraz = :wraz - 1;
   end
wraz = 3;
   parc = :raiz * raiz * :raiz;
while (:parc < :wnum) do begin
   raiz = :raiz + 1;
   parc = :raiz * raiz * :raiz;
   end
if (:parc > :wnum) then begin
   raiz = :raiz - 1;
   parc = :raiz * raiz * :raiz;
 while (:parc < :wnum) do begin
   raiz = :raiz + 0.50000;
   parc = :raiz * raiz * :raiz;
   end
 if (:parc > :wnum) then begin
   raiz = :raiz - 0.50000;
   parc = :raiz * raiz * :raiz;
 while (:parc < :wnum) do begin
   raiz = :raiz + 0.10000;
   parc = :raiz * raiz * :raiz;
   end
 if (:parc > :wnum) then begin
   raiz = :raiz - 0.250000;
   parc = :raiz * raiz * :raiz;
 while (:parc < :wnum) do begin
   raiz = :raiz + 0.050000;
   parc = :raiz * raiz * :raiz;
   end
 if (:parc > :wnum) then begin
   raiz = :raiz - 0.050000;
   parc = :raiz * raiz * :raiz;
 while (:parc < :wnum) do begin
   raiz = :raiz + 0.001000;
   parc = :raiz * raiz * :raiz;
   end
 if (:parc > :wnum) then begin
   raiz = :raiz - 0.0010000;
   parc = :raiz * raiz * :raiz;
 while (:parc < :wnum) do begin
   raiz = :raiz + 0.0001000;
   parc = :raiz * raiz * :raiz;
   end
 if (:parc > :wnum) then begin
   raiz = :raiz - 0.00010000;
   parc = :raiz * raiz * :raiz;
 while (:parc < :wnum) do begin
   raiz = :raiz + 0.00001000;
   parc = :raiz * raiz * :raiz;
   end
 if (:parc > :wnum) then begin
   raiz = :raiz - 0.000010000;
   parc = :raiz * raiz * :raiz;
 while (:parc < :wnum) do begin
   raiz = :raiz + 0.000001000;
   parc = :raiz * raiz * :raiz;
   end
   end
   end
   end
   end
   end
   end
   end
parc = cast(:raiz as integer);
if ((:parc * :parc * :parc) = :wnum) then
   raiz = :parc;
suspend;
   end
======================================
   CREATE PROCEDURE FU_DATATELA(
   DAT1 DATE,
   DAT2 VARCHAR(24),
   TIPO CHAR(1))
   RETURNS (
   DATA_TELA VARCHAR(19))
   AS
   begin
   /*
   Devolve uma data ou um TaimeStamp como:
   DD/MM/YY ou DD/MM/YYYY ou
   DD/MM/YY HH:MM:SS ou DD/MM/YYYY HH:MM:SS
   como um string (Bom para relatórios)
   */
   tipo = upper(:tipo);
if(:dat1 is not null) then
   begin
   if (:tipo = 'E') then
   data_tela = substring(cast(:dat1 as varchar(10)) from 9 for 2) || '/' ||
   substring(cast(:dat1 as varchar(10)) from 6 for 2) || '/' ||
   substring(cast(:dat1 as varchar(10)) from 1 for 4);
   else
   data_tela = substring(cast(:dat1 as varchar(10)) from 9 for 2) || '/' ||
   substring(cast(:dat1 as varchar(10)) from 6 for 2) || '/' ||
   substring(cast(:dat1 as varchar(10)) from 2 for 2);
   end
   else begin
   if (tipo = 'E') then
   data_tela = substring(:dat2 from 9 for 2) || '/' ||
   substring(:dat2 from 6 for 2) || '/' ||
   substring(:dat2 from 1 for 4) || ' ' ||
   substring(:dat2 from 12 for 8);
   else
   data_tela = substring(:dat2 from 9 for 2) || '/' ||
   substring(:dat2 from 6 for 2) || '/' ||
   substring(:dat2 from 2 for 2) || ' ' ||
   substring(:dat2 from 12 for 8);
   end
suspend;
   end
================================================
   CREATE PROCEDURE FU_DATE_TO_INTEGER(
   WDAT CHAR(10))
   RETURNS (
   R_DTI INTEGER)
   AS
   declare variable wano smallint;
   declare variable wmes smallint;
   declare variable wdia smallint;
   declare variable trab integer;
   declare variable wmat integer;
   begin
   /*
   Devolve um inteiro conforme a data informada
   "WDAT" deve vir assim: aaaa-mm-dd
   */
   wano = cast(substring(:wdat from 1 for 4) as smallint);
   wmes = cast(substring(:wdat from 6 for 2) as smallint);
   wdia = cast(substring(:wdat from 9 for 2) as smallint);
   if      (:wmes =  2) then wmat =  31;
   else if (:wmes =  3) then wmat =  59;
   else if (:wmes =  4) then wmat =  90;
   else if (:wmes =  5) then wmat = 120;
   else if (:wmes =  6) then wmat = 151;
   else if (:wmes =  7) then wmat = 181;
   else if (:wmes =  8) then wmat = 212;
   else if (:wmes =  9) then wmat = 243;
   else if (:wmes = 10) then wmat = 273;
   else if (:wmes = 11) then wmat = 304;
   else if (:wmes = 12) then wmat = 334;
   else                      wmat =   0;
select r_abs from fu_abs(((:wano - 1901) * 366)) into :trab;
   r_dti = :trab + :wmat + :wdia;
suspend;
   end
============================================
   CREATE PROCEDURE FU_DECIMAL_HORA(
   FNUM DECIMAL(10,4))
   RETURNS (
   HORA VARCHAR(10),
   WHOR INTEGER,
   WMIN INTEGER)
   AS
   declare variable wint integer;
   declare variable wtam integer;
   declare variable trab varchar(14);
   declare variable tra1 varchar(14);
   begin
   /*
   Se "FNUM" = 10,50 então devolve 10,30... etc
   Se "FNUM" = 15,20 então devolve 15,12
   */
   select r_formatar from Fu_formatar(:fnum, '######0,0000') into :trab;
   select r_sright   from Fu_s_right(:trab, 1)                into :tra1;
   select r_ltrim    from Fu_ltrim(:trab)                     into :trab;
   select r_len      from Fu_len(:trab)                       into :wtam;
while (:tra1 = '0') do begin
   select r_sleft  from Fu_s_left(:trab, :wtam - 1) into :trab;
   select r_sright from Fu_s_right(:trab, 1)        into :tra1;
   wtam = :wtam - 1;
   end
tra1 = :trab;
   select result from Fu_pos(',', :trab) into :wint;
select r_copy from Fu_Copy(:trab, (:wint + 1), (:wtam - :wint)) into :trab;
wmin = cast(:trab as integer);
   wmin = :wmin * 6;
   select r_div from Fu_div(:wmin, 10) into :wmin;
select r_copy from Fu_Copy(:tra1, 1, (:wint - 1)) into :trab;
   whor = cast(:trab as integer);
while (:wmin > 60) do begin
   wmin = :wmin - 60;
   whor = :whor + 1;
   end
 
hora = cast(:whor as varchar(6));
   select r_len from Fu_len(:trab) into :wtam;
if (:wtam = 1) then
   hora = '0' || :hora;
select r_intzero from Fu_intzero(:wmin, 2) into :trab;
   hora = :hora || ':' || :trab;
suspend;
   end
======================================
   CREATE PROCEDURE FU_DECODE_DATE(
   WDAT DATE)
   RETURNS (
   RDIA SMALLINT,
   RMES SMALLINT,
   RANO SMALLINT)
   AS
   begin
   /*
   Igual ao Delphi
   */
   rdia = extract(day   from :wdat);
   rmes = extract(month from :wdat);
   rano = extract(year  from :wdat);
suspend;
   end
=======================================
   CREATE PROCEDURE FU_DECODE_DATE_TIME(
   WDAT TIMESTAMP)
   RETURNS (
   RDIA SMALLINT,
   RMES SMALLINT,
   RANO SMALLINT,
   RHOR SMALLINT,
   RMIN SMALLINT,
   RSEG DECIMAL(6,4),
   WEEK SMALLINT,
   YDIA SMALLINT)
   AS
   declare variable trab varchar(24);
   begin
   /*
   Igual ao Delphi
   */
   trab = cast(:wdat as varchar(24));
rdia = extract(day   from :wdat);
   rmes = extract(month from :wdat);
   rano = extract(year  from :wdat);
if (substring(:trab from 12 for 13) = '00:00:00.0000') then
   begin
   rhor = 0;
   rmin = 0;
   rseg = 0.0000;
   end
   else begin
   rhor = extract(hour   from :wdat);
   rmin = extract(minute from :wdat);
   rseg = extract(second from :wdat);
   end
week = extract(weekday from :wdat);
   ydia = extract(yearday from :wdat);
suspend;
   end
===================================
   CREATE PROCEDURE FU_DIV(
   WRAD INTEGER,
   WDIV INTEGER)
   RETURNS (
   R_DIV INTEGER)
   AS
   begin
   /*
   Igual ao Delphi
   */
   R_DIV = :WRAD / :WDIV;
   suspend;
   end
=====================================
   CREATE PROCEDURE FU_DSTR(
   WSTR VARCHAR(8192),
   WTAM SMALLINT)
   RETURNS (
   R_DSTR VARCHAR(8192))
   AS
   DECLARE VARIABLE T SMALLINT;
   declare variable s varchar(8192);
   begin
   /*
   Devolve um string com espaços à direita até
   o tamanho "WTAM"
   */
   select r_Len from Fu_Len(:wstr) into :t;
   if (:wstr is null) then
   wstr = '';
if (:t > :wtam) then
   select r_Copy from Fu_Copy(:wstr, 1, :wtam) into :r_dstr;
   else begin
   select r_spaces from Fu_spaces(:wtam - :t) into :s;
   r_dstr = :wstr || :s;
   end
suspend;
   end
=========================================
   CREATE PROCEDURE FU_DVMODULO10(
   WSTR VARCHAR(50))
   RETURNS (
   WDIG INTEGER)
   AS
   declare variable wsom integer;
   declare variable wreg integer;
   declare variable wmul integer;
   declare variable wini integer;
   declare variable winj integer;
   declare variable winh integer;
   declare variable trab varchar(6);
   begin 
   /*
   Dígito Verificador Módulo 10
   */
   wsom = 0;
   wreg = 0;
   wmul = 2;
   select r_Len from Fu_Len(:wstr) into :wini;
   winh = :wini;
   winj = 1;
while (:winj <= :wini) do begin
   select r_Copy from Fu_Copy(:wstr, :winh, 1) into :trab;
   wreg = cast(:trab as integer) * :wmul;
   wsom = :wsom + :wreg;
 if (:wmul = 2) then
   wmul = 1;
   else
   wmul = :wmul + 1;
 winj = :winj + 1;
   winh = :winh - 1;
   end
select r_mod from Fu_mod(:wsom, 10) into :wdig;
suspend;
   end
==========================================
   CREATE PROCEDURE FU_DVMODULO11(
   WSTR VARCHAR(50))
   RETURNS (
   WDIG INTEGER)
   AS
   declare variable wsom integer;
   declare variable wreg integer;
   declare variable wmul integer;
   declare variable wini integer;
   declare variable winj integer;
   declare variable winh integer;
   declare variable wxi1 integer;
   declare variable wxi2 integer;
   declare variable waux char(2);
   declare variable wax1 char(1);
   declare variable wax2 char(1);
   declare variable wtra varchar(10);
   begin
   /*
   Dígito Verificador Módulo 11
   */
   wsom = 0;
   wreg = 0;
   wmul = 2;
   select r_Len from Fu_Len(:wstr) into :wini;
   winh = :wini;
   winj = 1;
while (:winj <= :wini) do begin
   select r_Copy from Fu_Copy(:wstr, :winh, 1) into :wtra;
   wreg = cast(:wtra as integer) * :wmul;
 while (:wreg > 9) do begin
   waux = cast(:wreg as char(2));
   wax1 = substring(:waux from 1 for 1);
   wax2 = substring(:waux from 2 for 1);
   wxi1 = cast(:wax1 as integer);
   wxi2 = cast(:wax2 as integer);
   wreg = :wxi1 + :wxi2;
   end
 wsom = :wsom + :wreg;
 if (:wmul = 9) then
   wmul = 2;
   else
   wmul = :wmul + 1;
 winj = :winj + 1;
   winh = :winh - 1;
   end
select r_mod from Fu_mod(:wsom, 11) into :wdig;
if ((:wdig = 10) or (:wdig = 1) or (:wdig = 0)) then
   wdig = 0;
suspend;
   end
=======================================
   CREATE PROCEDURE FU_ESTR(
   WSTR VARCHAR(8192),
   WTAM SMALLINT)
   RETURNS (
   R_ESTR VARCHAR(8192))
   AS
   DECLARE VARIABLE T SMALLINT;
   begin
   /*
   Devolve um string com espaços à direita conforme "WTAM"
   */
   select r_Len from Fu_Len(:wstr) into :t;
   r_estr = :wstr;
if      (:t > :wtam) then
   select r_Sright from Fu_S_Right(:wstr, :wtam) into :r_estr;
   else begin
   while (:t < :wtam) do begin
   r_estr = ' ' || :r_estr;
   t = :t + 1;
   end
   end
suspend;
   end
==============================================
   CREATE PROCEDURE FU_EXTENSO(
   VALO DECIMAL(18,2),
   LIN1 INTEGER,
   LIN2 INTEGER)
   RETURNS (
   R_EXT1 VARCHAR(126),
   R_EXT2 VARCHAR(126),
   R_EXT3 VARCHAR(256))
   AS
   declare variable nao1 varchar(16);
   declare variable nao2 varchar(50);
   declare variable nao3 varchar(16);
   declare variable nao4 varchar(25);
   declare variable wvlr varchar(16);
   declare variable trab varchar(256);
   declare variable tra1 varchar(16);
   declare variable rext varchar(256);
   declare variable wint integer;
   declare variable wtri integer;
   declare variable var1 integer;
   declare variable var2 integer;
   declare variable var3 integer;
   begin
   /*
   Devolve duas linhas com o número "VALO" por extenso
   a primeira linha tem "LIN1" de tamanho e
   a segunda linha tem "LIN2" de tamanho.
   Também é feita uma separação silábica considerando as
   regras de sintaxe da l´ngua portuguesa.
   Utiliza-se em conjunto as SPs FU_EXT_TESTA1 e FU_EXT_TESTA2 abaixo
   */
   if (Lin1 = 0) then
   Lin1 = 1;
   if (Lin2 = 0) then
   Lin2 = 1;
if (:Lin1 > 128) then Lin1 = 125;
   if (:Lin2 > 128) then Lin2 = 125;
   nao1 = 'bctdrqvhêõãm?';
   nao2 = ' o; n; s; u;ci;ei;nh;ce;qu;he;nz;oz;rz;ai;ss;uz';
   nao3 = 'rea;are;doi;ato';
   nao4 = 'trez;uinh;nhen;uato;ssei';
r_ext1 = '';
   wvlr  = '';
   wint   = 1;
   if (:valo < 0.01) then valo = :valo * -1;
   select r_Formatar from Fu_Formatar(:valo, '##########0,00') into :rext;
while (:wint < 15) do begin
   select r_Copy from Fu_Copy(:rext, :wint, 1) into :trab;
   select result From Fu_Pos(:trab, '0123456789,') into :wtri;
   if (:wtri > 0) then wvlr = :wvlr || :trab;
   wint = :wint + 1;
   end
rext = '';
   select result From Fu_Pos(',', :wvlr) into :wtri;
   if (:wtri = 0) then wvlr = :wvlr || ',00';
   select r_Len from Fu_Len(:wvlr) into :wtri;
while (:wtri < 14) do begin
   wvlr = '0' || :wvlr;
   wtri = :wtri + 1;
   end
if (substring(:wvlr from 13 for 1) = ',') then
   wvlr = substring(:wvlr from 2 for 11) || ',' || substring(:wvlr from 14 for 1) || '0';
if (cast(substring(:wvlr from 1 for 2) as integer) > 0) then begin
   trab = substring(:wvlr from 1 for 2);
   var1 = 0;
   var2 = cast(substring(:trab from 1 for 1) as integer);
   var3 = cast(substring(:trab from 2 for 1) as integer);
   select r_ext_2 from Fu_Ext_Testa2(:rext, :var2, :var3) into :rext;
 if (:trab = '01') then
   rext = :rext || ' bilhão';
   else
   rext = :rext || ' bilhões';
 if (substring(:wvlr from 3 for 9) = '000000000') then
   rext = :rext || ' de reais';
   else begin
   if ((substring(:wvlr from 3 for 3) = '000')       and
   (substring(:wvlr from 6 for 1) =   '0')       or
   (substring(:wvlr from 6 for 6) = '000000')    or
   (substring(:wvlr from 7 for 8) = '00000,00')) then
   rext = :rext || ' e ';
   else
   rext = :rext || ' , ';
   end
   end
if (substring(:wvlr from 3 for 3) > '000') then begin
   var1 = cast(substring(:wvlr from 3 for 1) as integer);
   var2 = cast(substring(:wvlr from 4 for 1) as integer);
   var3 = cast(substring(:wvlr from 5 for 1) as integer);
 if (:var1 > 0) then
   begin
   select r_ext_1 from Fu_Ext_Testa1(:rext, :var1, :var2, :var3) into :rext;
 if ((:var2 + :var3) > 0) then
   select r_ext_2 from Fu_Ext_Testa2(:rext, :var2, :var3) into :rext;
   end
   else
   select r_ext_2 from Fu_Ext_Testa2(:rext, :var2, :var3) into :rext;
 if ((:var1 + :var2 = 0) and (:var3 = 1)) then
   rext = :rext || ' milhão';
   else
   rext = :rext || ' milhões';
 if (substring(:wvlr from 6 for 6) = '000000') then
   rext = :rext || ' de reais';
   else if ((substring(:wvlr from 6 for 3) = '000') and (substring(:wvlr from 13 for 2) = '00')) then
   rext = :rext || ' e ';
   else
   rext = :rext || ', ';
   end
if (substring(:wvlr from 6 for 3) > '000') then begin
   var1 = cast(substring(:wvlr from 6 for 1) as integer);
   var2 = cast(substring(:wvlr from 7 for 1) as integer);
   var3 = cast(substring(:wvlr from 8 for 1) as integer);
 if (:var1 > 0) then
   begin
   select r_ext_1 from Fu_Ext_Testa1(:rext, :var1, :var2, :var3) into :rext;
 if ((:var2 + :var3) > 0) then
   select r_ext_2 from Fu_Ext_Testa2(:rext, :var2, :var3) into :rext;
   end
   else
   select r_ext_2 from Fu_Ext_Testa2(:rext, :var2, :var3) into :rext;
 rext = :rext || ' mil';
 if (substring(:wvlr from 9 for 3) = '000') then
   rext = :rext || ' reais';
   else if ((substring(:wvlr from 9 for 3) > '000') and (substring(:wvlr from 13 for 2) > '00')) then
   rext = :rext || ', ';
   else
   rext = :rext || ' e ';
   end
if (substring(:wvlr from 9 for 3) > '000') then begin
   var1 = cast(substring(:wvlr from  9 for 1) as integer);
   var2 = cast(substring(:wvlr from 10 for 1) as integer);
   var3 = cast(substring(:wvlr from 11 for 1) as integer);
 if (:var1 > 0) then
   begin
   select r_ext_1 from Fu_Ext_Testa1(:rext, :var1, :var2, :var3) into :rext;
 if ((:var2 + :var3) > 0) then
   select r_ext_2 from Fu_Ext_Testa2(:rext, :var2, :var3) into :rext;
   end
   else
   select r_ext_2 from Fu_Ext_Testa2(:rext, :var2, :var3) into :rext;
 if (substring(:wvlr from 1 for 11) > '00000000001') then
   rext = :rext || ' reais';
   else
   rext = :rext || ' real';
   end
if (substring(:wvlr from 13 for 2) > '00') then begin
   select r_Len from Fu_Len(:rext) into :wint;
 if (:wint > 2) then
   rext = :rext || ' e ';
 var1 = 0;
   var2 = cast(substring(:wvlr from 13 for 1) as integer);
   var3 = cast(substring(:wvlr from 14 for 1) as integer);
   select r_ext_2 from Fu_Ext_Testa2(:rext, :var2, :var3) into :rext;
   rext = :rext || ' centavo';
 if (substring(:wvlr from 13 for 2) > '01') then
   rext = :rext || 's';
   end
select r_Len from Fu_Len(:rext) into :wtri;
   select r_replicate from Fu_Replicate(:lin2, '*') into r_ext2;
   select r_replicate from Fu_Replicate(:lin2, '*') into r_ext3;
if (:wtri = :lin1) then
   r_ext1 = :rext;
   else if (:wtri < :lin1) then
   begin
   select r_replicate from Fu_Replicate((:lin1 - :wtri), '*') into r_ext1;
   r_ext1 = :rext || :r_ext1;
   end
   else begin    -- Se não for igual nem menor então é maior
   -- Preparo a primeira variável
   var1 = 0;
   select r_Copy from Fu_Copy(:rext, 1, :lin1) into :r_ext1;     -- a variável
   select r_Copy from Fu_Copy(:rext, (:lin1 + 1), (:lin2 + :lin2)) into :rext;  -- sobrou
 while (:var1 = 0) do begin
   var1 = 1;                             -- Suponho que farei este passo apenas esta vez
   -- Verifico a separação silábica com uma casa
   select r_Len from Fu_Len(:r_ext1) into :var2;
   select r_Copy from Fu_Copy(:r_ext1, :var2, 1) into :tra1;
   select result From Fu_Pos(:tra1, :nao1) into :var3;
 if (:var3 > 0) then begin         -- Letra final não permitida
   select r_Copy from Fu_Copy(:r_ext1, :var2, 1) into :tra1;
   rext = :tra1 || :rext;           -- Coloco na sobra
   select r_Copy from Fu_Copy(:r_ext1, 1, (:var2 - 1)) into :r_ext1; -- Tiro daqui
   var1 = 0;                        -- Fazer o passo (while) novamente
   end
   -- Verifico a separação silábica com duas casas
   select r_Len from Fu_Len(:r_ext1) into :var2;
   select r_Copy from Fu_Copy(:r_ext1, (:var2 -1), 2) into :tra1;
   select result From Fu_Pos(:tra1, :nao2) into :var3;
 if (:var3 > 0) then begin
   select r_Copy from Fu_Copy(:r_ext1, (:var2 - 1), 2) into :tra1;
   rext = :tra1 || :rext;                    -- Coloco na sobra
   select r_Copy from Fu_Copy(:r_ext1, 1, (:var2 - 2)) into :r_ext1;  -- Tiro daqui
   var1 = 0;                        -- Fazer o passo (while) novamente
   end
   -- Verifico a separação silábica com três casas
   select r_Len from Fu_Len(:r_ext1) into :var2;
   select r_Copy from Fu_Copy(:r_ext1, (:var2 - 2), 3) into :tra1;
   select result From Fu_Pos(:tra1, :nao3) into :var3;
 if (:var3 > 0) then begin
   select r_Copy from Fu_Copy(:r_ext1, (:var2 - 2), 3) into :tra1;
   rext = :tra1 || :rext;            -- Coloco na sobra
   select r_Copy from Fu_Copy(:r_ext1, 1, (:var2 - 3)) into :r_ext1;  -- Tiro daqui
   var1 = 0;                         -- Fazer o passo (while) novamente
   end
   -- Verifico a separação silábica com quatro casas
   select r_Len from Fu_Len(:r_ext1) into :var2;
   select r_Copy from Fu_Copy(:r_ext1, (:var2 - 3), 4) into :tra1;
   select result From Fu_Pos(:tra1, :nao4) into :var3;
 if (:var3 > 0) then begin
   select r_Copy from Fu_Copy(:r_ext1, (:var2 - 3), 4) into :tra1;
   rext = :tra1 || :rext;            -- Coloco na sobra
   select r_Copy from Fu_Copy(:r_ext1, 1, (:var2 - 4)) into :r_ext1;   -- Tiro daqui
   var1 = 0;                         -- Fazer o passo (while) novamente
   end
   end
   -- Ajustando o tamanho da primeira
   select r_Len from Fu_Len(:r_ext1) into :var2;
 if (:var2 < :lin1) then begin
   select r_Dstr From Fu_DStr(:r_ext1, :lin1) into :r_ext1;
   select r_Copy from Fu_Copy(:r_ext1, :lin1, 1) into :tra1;
 if (:tra1 <> ' ') then begin
   select r_Copy from Fu_Copy(:r_ext1, 1, (:lin1 - 1)) into :r_ext1;
   r_ext1 = :r_ext1 || '-';
   end
   end
   -- Preparando a segunda variável (sempre existirá)
   select r_Len from Fu_Len(:rext) into :var2;               -- Apuro o comprimento da sobra
 if (:var2 <= :lin2) then     -- Se não houver a terceira string igualo e completo
   begin
   r_ext2 = :rext;
   select r_Replicate from Fu_Replicate((:lin2 - :var2), '*') into :rext;
   r_ext2 = :r_ext2 || :rext;
   end
   else begin                                                -- Tem terceira variável
   -- Preparo a segunda
   var1 = 0;
   select r_Copy from Fu_Copy(:rext, 1, :lin2) into :r_ext2;   -- Copio novo conteúdo
   select r_Copy from Fu_Copy(:rext, (:lin2 + 1), :lin2) into :rext;  -- sobrou
   select r_RTrim from Fu_RTrim(:r_ext2) into :r_ext2;         -- Retiro espaços
 while (:var1 = 0) do begin
   var1 = 1;
   select r_Len from Fu_Len(:r_ext2) into :var2;
   select r_Copy from Fu_Copy(:r_ext2, :var2, 1) into :tra1;
   select result From Fu_Pos(:tra1, :nao1) into :var3;
 if (:var3 > 0) then begin
   select r_Copy from Fu_Copy(:r_ext2, :var2, 1) into :tra1;
   rext = :tra1 || :rext;
   select r_Copy from Fu_Copy(:r_ext2, 1, (:var2 - 1)) into :r_ext2;
   var1 = 0;
   end
 select r_Len from Fu_Len(:r_ext2) into :var2;
   select r_Copy from Fu_Copy(:r_ext2, (:var2 -1), 2) into :tra1;
   select result From Fu_Pos(:tra1, :nao2) into :var3;
 if (:var3 > 0) then begin
   select r_Copy from Fu_Copy(:r_ext2, (:var2 - 1), 2) into :tra1;
   rext = :tra1 || :rext;
   select r_Copy from Fu_Copy(:r_ext2, 1, (:var2 - 2)) into :r_ext2;
   var1 = 0;
   end
 select r_Len from Fu_Len(:r_ext2) into :var2;
   select r_Copy from Fu_Copy(:r_ext2, (:var2 - 2), 3) into :tra1;
   select result From Fu_Pos(:tra1, :nao3) into :var3;
 if (:var3 > 0) then begin
   select r_Copy from Fu_Copy(:r_ext2, (:var2 - 2), 3) into :tra1;
   rext = :tra1 || :rext;
   select r_Copy from Fu_Copy(:r_ext2, 1, (:var2 - 3)) into :r_ext2;
   var1 = 0;
   end
 select r_Len from Fu_Len(:r_ext2) into :var2;
   select r_Copy from Fu_Copy(:r_ext2, (:var2 - 3), 4) into :tra1;
   select result From Fu_Pos(:tra1, :nao4) into :var3;
 if (:var3 > 0) then begin
   select r_Copy from Fu_Copy(:r_ext2, (:var2 - 3), 4) into :tra1;
   rext = :tra1 || :rext;
   select r_Copy from Fu_Copy(:r_ext2, 1, (:var2 - 4)) into :r_ext2;
   var1 = 0;
   end
   -- Ajustando o tamanho da segunda
   select r_Len from Fu_Len(:r_ext2) into :var2;
 if (:var2 < :lin2) then begin
   select r_Dstr From Fu_DStr(:r_ext2, :lin2) into :r_ext2;
   select r_Copy from Fu_Copy(:r_ext2, :lin1, 1) into :tra1;
 if (:tra1 <> ' ') then begin
   select r_Copy from Fu_Copy(:r_ext2, 1, (:lin2 - 1)) into :r_ext2;
   r_ext2 = :r_ext2 || '-';
   end
   end
   -- Preparando a terceira variável (sempre existirá)
   select r_Len from Fu_Len(:rext) into :var2;
   select r_Replicate from Fu_Replicate((:lin2 - :var2), '*') into :r_ext3;
   r_ext3 = :rext || :r_ext3;
   end
   end
   end
if (substring(:r_ext2 from 1 for 4) = 's***') then begin
   r_ext1 = :r_ext1 || 's';
   r_ext2 = '*' || substring(:r_ext2 from 2 for 125);
   end
r_ext1 = upper(substring(:r_ext1 from 1 for 1)) || substring(:r_ext1 from 2 for 125);
suspend;
   end
==================================================
   CREATE PROCEDURE FU_EXT_TESTA1(
   WEXT VARCHAR(255),
   VAR1 INTEGER,
   VAR2 INTEGER,
   VAR3 INTEGER)
   RETURNS (
   R_EXT_1 VARCHAR(255))
   AS
   begin
   /*
   Auxiliar de FU_EXTENSO
   */
   if (:var1 = 1) then
   begin
   if (:var2 + :var3 = 0) then
   wext = :wext || 'cem';
   else
   wext = :wext || 'cento';
   end
   else if (:var1 = 2) then
   wext = :wext || 'duzentos';
   else if (:var1 = 3) then
   wext = :wext || 'trezentos';
   else if (:var1 = 4) then
   wext = :wext || 'quatrocentos';
   else if (:var1 = 5) then
   wext = :wext || 'quinhentos';
   else if (:var1 = 6) then
   wext = :wext || 'seiscentos';
   else if (:var1 = 7) then
   wext = :wext || 'setecentos';
   else if (:var1 = 8) then
   wext = :wext || 'oitocentos';
   else if (:var1 = 9) then
   wext = :wext || 'novecentos';
if (:var2 + :var3 > 0) then
   wext = :wext || ' e ';
r_ext_1 = :wext;
   suspend;
   end
===========================================
   CREATE PROCEDURE FU_EXT_TESTA2(
   WEXT VARCHAR(255),
   VAR2 INTEGER,
   VAR3 INTEGER)
   RETURNS (
   R_EXT_2 VARCHAR(255))
   AS
   begin
   /*
   Auxiliar de FU_EXTENSO
   */
   if (:var2 = 1) then
   begin
   if (:var3 = 0) then
   wext = :wext || 'dez';
   else if (:var3 = 1) then
   wext = :wext || 'onze';
   else if (:var3 = 2) then
   wext = :wext || 'doze';
   else if (:var3 = 3) then
   wext = :wext || 'treze';
   else if (:var3 = 4) then
   wext = :wext || 'quatorze';
   else if (:var3 = 5) then
   wext = :wext || 'quinze';
   else if (:var3 = 6) then
   wext = :wext || 'dezesseis';
   else if (:var3 = 7) then
   wext = :wext || 'dezessete';
   else if (:var3 = 8) then
   wext = :wext || 'dezoito';
   else if (:var3 = 9) then
   wext = :wext || 'dezenove';
   end
   else if (:var2 = 2) then
   wext = :wext || 'vinte';
   else if (:var2 = 3) then
   wext = :wext || 'trinta';
   else if (:var2 = 4) then
   wext = :wext || 'quarenta';
   else if (:var2 = 5) then
   wext = :wext || 'cinquenta';
   else if (:var2 = 6) then
   wext = :wext || 'sessenta';
   else if (:var2 = 7) then
   wext = :wext || 'setenta';
   else if (:var2 = 8) then
   wext = :wext || 'oitenta';
   else if (:var2 = 9) then
   wext = :wext || 'noventa';
if (:var2 <> 1) then begin
   if (:var3 > 0) then begin
   if (:var2 > 0) then
   wext = :wext || ' e ';
 if (:var3 = 1) then
   wext = :wext || 'um';
   else if (:var3 = 2) then
   wext = :wext || 'dois';
   else if (:var3 = 3) then
   wext = :wext || 'três';
   else if (:var3 = 4) then
   wext = :wext || 'quatro';
   else if (:var3 = 5) then
   wext = :wext || 'cinco';
   else if (:var3 = 6) then
   wext = :wext || 'seis';
   else if (:var3 = 7) then
   wext = :wext || 'sete';
   else if (:var3 = 8) then
   wext = :wext || 'oito';
   else if (:var3 = 9) then
   wext = :wext || 'nove';
   end
   end
r_ext_2 = :wext;
suspend;
   end
=====================================
   CREATE PROCEDURE FU_EXTRACT_STR(
   WSUB VARCHAR(8192),
   WSTR VARCHAR(8192))
   RETURNS (
   WRET VARCHAR(8192))
   AS
   declare variable wlen smallint;
   declare variable wint smallint;
   declare variable wpos smallint;
   declare variable wvar varchar(8192);
   begin
   /*
   Retira de "WSTR" uma "WSUB" Encontrada
   */
   select r_Len  from Fu_Len(:wsub)        into :wlen;
   select r_Len  from Fu_Len(:wstr)        into :wint;
   select result from Fu_Pos(:wsub, :wstr) into :wpos;
if (:wpos = 0) then
   wret = :wstr;
   else begin
   select r_Copy from Fu_Copy(:wstr, 1, (:wpos - 1))       into :wret;
   select r_Copy from Fu_Copy(:wstr, (:wpos + :wlen), 8191) into :wvar;
   wret = :wret || :wvar;
   end
suspend;
   end
==========================================
   CREATE PROCEDURE FU_FERIADOS_DATAS(
   WDAT DATE)
   RETURNS (
   WTIP CHAR(1))
   AS
   declare variable c integer;
   declare variable d integer;
   declare variable g integer;
   declare variable h integer;
   declare variable i integer;
   declare variable j integer;
   declare variable l integer;
   declare variable m integer;
   declare variable w integer;
   declare variable de date;
   declare variable ds date;
   declare variable dp date;
   declare variable cc date;
   declare variable wano integer;
   declare variable wfer varchar(40) = '0101,0421,0501,0907,1012,1102,1115,1225';
   declare variable trab varchar(5);
   begin
   /*
   Localiza feriados nacionais e religiosos de um ano
   */
   wtip = 'U';
if (:wdat is not null) then begin
   w = extract(weekday from :wdat);
 if (:w = 0) then
   wtip = 'D';
   else if (:w = 6) then
   wtip = 'B';
 trab = substring(cast(:wdat as varchar(10)) from 6 for 2) ||
   substring(cast(:wdat as varchar(10)) from 9 for 2);
 select result from Fu_pos(:trab, :wfer) into i;
 if (:i > 0) then           -- Feriado Indicado em WFER
   wtip = 'F';
   end
-- Ver se é Páscoa
   select rdia, rmes, rano from Fu_decode_date(:wdat) into :d, :m, :wano;
   select r_mod from Fu_Mod(:wano,  19) into :g;
   select r_div from Fu_Div(:wano, 100) into :c;
-- Cálculo de H (C - C div 4 - (8 * C + 13) div 25 + 19 * G + 15) mod 30;)
   select r_div from Fu_Div(:c, 4) into :w;
   h = c - w;
   w = (8 * :c) + 13;
   select r_div from Fu_Div(:w, 25) into :w;
   h = :h - :w + (19 * :g) + 15;
   select r_mod from Fu_Mod(:h, 30) into :h;
-- Cálculo de i (H - (H div 28) * (1 - (H div 28) * (29 div (H + 1)) * ((21 - G) div 11)) )
   select r_div from Fu_Div(:h, 28) into :w;        --  H DIV 28
   select r_div from Fu_Div(29, (:h + 1)) into :m;  -- 29 DIV (h + 1)
   select r_div from Fu_Div((21 - :g), 11) into :l; -- ((21 - G) div 11)
   i = (:h - :w) *  1 - (:w * :m * :l);
-- Cálculo de j ((ano + ano div 4 + I + 2 - C + C div 4) mod 7)
   select r_div from Fu_Div(:wano, 4) into :w;
   select r_div from Fu_Div(:c, 4) into :l;
   select r_mod from Fu_Mod(:wano + :w + :i + 2 - :c + :l, 7) into :j;
l = :i - :j;
-- Cálculo de m (3 + (L + 40) div 44)
   select r_div from Fu_Div((:l + 40), 44) into :w;
   m = 3 + :w;
-- Cálculo de d (L + 28 - 31 * (m div 4))
   select r_div from Fu_Div((:m + 44), 44) into :w;
   d = (:l + 28) - 31 * :w;
-- Finalmente acha DE (Como o domingo de Páscoa)
   if (:d < 10) then
   de = cast(substring(cast(:wdat as varchar(10)) from 1 for 5) ||
   '0' || cast(:m as char(1)) || '-0' || cast(:d as char(1)) as date);
   else
   de = cast(substring(cast(:wdat as varchar(10)) from 1 for 5) ||
   '0' || cast(:m as char(1)) || '-' || cast(:d as char(2)) as date);
-- Páscoa
   dp = :de;
w = extract(weekday from :de);
while (:w > 1) do begin
   de = :de + 1;
   w = extract(weekday from :de);
   end
-- Sexta-Feira Santa
   ds = :de - 2;
-- Corpus Christi
   cc = :ds + 62;
-- Carnaval
   de = :de - 47;
if (:wdat = :de) then        -- È Carnaval
   wtip = 'C';
   else if (:wdat = :ds) then   -- É Sexta-Feira Santa
   wtip = 'S';
   else if (:wdat = :dp) then   -- É Páscoa
   wtip = 'P';
   else if (:wdat = :cc) then   -- É Corpus Christi
   wtip = 'T';
suspend;
   end
============================================
   CREATE PROCEDURE FU_FORMATAR(
   WVLR DECIMAL(15,4),
   WMOD VARCHAR(32))
   RETURNS (
   R_FORMATAR VARCHAR(32))
   AS
   declare variable vls varchar(44);
   declare variable dcm SmallInt;
   declare variable vir SmallInt;
   declare variable win SmallInt;
   declare variable tam SmallInt;
   declare variable npo smallint;
   declare variable trb varchar(2);
   begin
   /*
   Recebe um decimal e um modelo de máscara e devolve
   uma forma adequada p/ impressão.
   Ex: 1234,56 e "###.##0,00" devolve "  1.234,56" ou ainda
   -1234,56 e "###.##0,00" devolve " -1.234,56" ou ainda
   -1234,56 e "A##.##0,00" devolve "  1.234,56" ou ainda (valor absoluto) ou ainda
   1234,56 e '***.**0,00" devolve "**1.234,56"
   */
   if ((substring(:wmod from 1 for 1) = 'A') and (:wvlr < 0)) then begin  -- Se for valor absoluto
   select r_abs from fu_abs(:wvlr) into :wvlr;
   select result from Fu_pos('*', :wmod) into :npo;
 if (:npo > 0) then
   wmod = '*' || substring(:wmod from 2);
   else begin
   select result from Fu_pos('$', :wmod) into :npo;
 if (:npo > 0) then
   wmod = '$' || substring(:wmod from 2);
   else
   wmod = '#' || substring(:wmod from 2);
   end
   end
vls = cast(:wvlr as varchar(32));                    -- Valor como String
   select r_len from Fu_len(:vls) into :tam;               -- Tamanho do Valor como String
   select r_len from Fu_len(:wmod) into :win;              -- Tamanho da Máscara
   select result from Fu_pos(',', :wmod) into :dcm;
   dcm = :win - :dcm;
   select wret from Fu_replace_all_str(:vls, '.', ',') into :vls;
   select r_len from Fu_len(:vls) into :tam;               -- Tamanho do Valor como String
   select result from Fu_pos(',', :vls) into :vir;
   vir = :tam - :vir;
while (:vir > :dcm) do begin
   tam = :tam - 1;
   select r_copy from Fu_copy(:vls, 1, :tam) into vls;
   vir = :vir - 1;
   end
if (:dcm > 4) then begin
   while (:vir < :dcm) do begin
   vls = :vls || '0';
   vir = :vir + 1;
   end
   end
select r_len from Fu_Len(:vls) into :tam;               -- Tamanho do Valor como String
   r_formatar = '';
while ((:win > 0) or (:tam > 0))  do begin
   if ((:win = 0) and (:tam > 0)) then
   begin
   select r_copy from Fu_copy(:vls, :tam, 1) into :trb;
   r_formatar = :trb || :r_formatar;
   tam = :tam - 1;
   end
   else begin
   select r_sright from Fu_s_right(:wmod, 1) into :trb;
   select r_copy from Fu_copy(:wmod, 1, (:win -1)) into :wmod;
 if (:tam = 0) then
   begin
   if (:trb in ('#', 'A', '.')) then
   r_formatar = ' ' || :r_formatar;
   else
   r_formatar = :trb || :r_formatar;
   end
   else begin
   if (:trb = '.') then
   r_formatar = '.' || r_formatar;
   else begin
   select r_copy from Fu_copy(:vls, :tam, 1) into :trb;
   r_formatar = :trb || :r_formatar;
   tam = :tam - 1;
   select r_copy from Fu_copy(:vls, 1, :tam) into :vls;
   end
   end
 win = :win - 1;
   end
   end
select result from fu_pos('-.', :r_formatar) into :dcm;
if (:dcm > 0) then
   select wret from fu_replace_str(' -', :r_formatar, :dcm) into :r_formatar;
   else if (substring(:r_formatar from 1 for 1) = '.') then
   select wret from fu_replace_str(' ', :r_formatar, 1) into :r_formatar;
   else begin
   select result from fu_pos(' .', :r_formatar) into :dcm;
 if (:dcm > 0) then
   select wret from fu_replace_str('  ', :r_formatar, :dcm) into :r_formatar;
   end
suspend;
   end
===============================================
   CREATE PROCEDURE FU_HORA_DECIMAL(
   FHOR VARCHAR(8))
   RETURNS (
   WDEC DECIMAL(10,2))
   AS
   declare variable whor integer;
   declare variable wmin integer;
   declare variable wint integer;
   declare variable wtam integer;
   declare variable trab varchar(10);
   begin
   /*
   recebe uma hora tipo HH:MM e devolve em decimal
   Ex: Recebe 3:23 e devolve 3,38
   */
   select result from Fu_pos(':', :fhor) into :wint;
   select r_len from Fu_len(:fhor) into :wtam;
if (:wint = 0) then
   begin
   wmin = 0;
   select r_onlydigit from Fu_onlydigit(:fhor) into :trab;
   wdec = cast(:trab as decimal(10, 2));
   end
   else begin
   select r_copy from Fu_copy(:fhor, :wint + 1, :wtam - :wint) into :trab;
   wmin = cast(:trab as integer);
   select r_copy from Fu_copy(:fhor, 1, :wint - 1) into :trab;
   whor = cast(:trab as integer);
 while (:wmin > 60) do begin
   wmin = :wmin - 60;
   whor = :whor + 1;
   end
 wdec = cast((:wmin / 60.00) as decimal(10, 2));
   wdec = cast(:whor + :wdec as decimal(10, 2));
   end
suspend;
   end
=============================================
   CREATE PROCEDURE FU_INC_DEC_MES(
   WDAT DATE,
   WQTD SMALLINT)
   RETURNS (
   R_INC_DEC_MES DATE)
   AS
   DECLARE VARIABLE WDIA SMALLINT;
   DECLARE VARIABLE WMES SMALLINT;
   DECLARE VARIABLE WANO SMALLINT;
   DECLARE VARIABLE WINT SMALLINT;
   DECLARE VARIABLE WTRM CHAR(2);
   DECLARE VARIABLE WTRD CHAR(2);
   begin
   /*
   Incrementa ou decrementa meses em uma data
   Se "WQTD" > 0 incrementa senão decrementa
   */
   wdia = extract(day   from :wdat);
   wmes = extract(month from :wdat);
   wano = extract(year  from :wdat);
wmes = :wmes + :wqtd;
if (:wqtd > 0) then
   begin
   while (:wmes > 12) do begin
   wano = :wano + 1;
   wmes = :wmes - 12;
   end
   end
   else begin
   while (:wmes < 1) do begin
   wano = :wano - 1;
   wmes = :wmes + 12;
   end
   end
if ((:wmes = 2) and (:wdia > 28)) then
   begin
   select r_mod from Fu_mod(:wano, 4) into :wint;
 if      ((:wint = 0) and (:wdia > 29)) then
   wdia = 29;
   else if ((:wint > 0) and (:wdia > 28)) then
   wdia = 28;
   end
   else if (:wdia > 30) then begin
   if ((:wmes = 4) or (:wmes = 6) or (:wmes = 9) or (:wmes = 11)) then
   wdia = 30;
   end
select r_IntZero from Fu_IntZero(:wdia, 2) into :wtrd;
   select r_IntZero from Fu_IntZero(:wmes, 2) into :wtrm;
r_Inc_Dec_Mes = cast(cast(:wano as varchar(4)) || '-' ||
   :wtrm || '-' || :wtrd as date);
suspend;
   end
=============================================
   CREATE PROCEDURE FU_INC_DEC_PERI(
   WPER VARCHAR(7),
   WQTD SMALLINT)
   RETURNS (
   R_INC_DEC_PERI VARCHAR(7))
   AS
   DECLARE VARIABLE WMES SMALLINT;
   DECLARE VARIABLE WANO SMALLINT;
   begin
   /*
   Incrementa ou decrementa meses em um mês e ano.
   Se "WQTD" > 0 incrementa senão decrementa
   */
   wmes = cast(substring(:wper from 1 for 2) as SmallInt) + :wqtd;
   wano = cast(substring(:wper from 4 for 4) as SmallInt);
if (:wqtd < 0) then
   begin
   while (:wmes < 1) do begin
   wmes = :wmes + 12;
   wano = :wano - 1;
   end
   end
   else begin
   while (:wmes > 12) do begin
   wmes = :wmes - 12;
   wano = :wano + 1;
   end
   end
select r_IntZero from Fu_IntZero(:wmes, 2) into r_Inc_Dec_peri;
   r_Inc_Dec_Peri = :r_inc_dec_peri || '/' || cast(:wano as varchar(4));
suspend;
   end
==============================================
   CREATE PROCEDURE FU_INSERT_STR(
   WSUB VARCHAR(2048),
   WSTR VARCHAR(2048),
   WPOS SMALLINT)
   RETURNS (
   WRET VARCHAR(4096))
   AS
   declare variable wlen smallint;
   declare variable wvar varchar(255);
   begin
   /*
   Insere um string em outro na posição "WPOS"
   */
   select r_Len from Fu_Len(:wstr) into :wlen;
if (:wlen <= :wpos) then
   wret = :wstr || :wsub;
   else begin
   select r_Copy from Fu_Copy(:wstr, 1, (:wpos - 1)) into :wret;
   select r_Copy from Fu_Copy(:wstr, :wpos, 255) into :wvar;
   wret = :wret || :wsub || :wvar;
   end
suspend;
   end
===========================================
   CREATE PROCEDURE FU_INTBRANCOS(
   WINT BIGINT,
   WTAM INTEGER)
   RETURNS (
   R_INTBRANCOS VARCHAR(36))
   AS
   begin
   /*
   Recebe um inteiro e devolve um string com brancos à esquerda no
   tamanho "WTAM"
   */
   if (:wint is null) then
   select r_replicate from Fu_replicate(:wtam, ' ') into r_IntBrancos;
   else
   select r_Sright from Fu_S_Right('                  ' || cast(:wint as varchar(18)), :wtam) into :r_intbrancos;
suspend;
   end
========================================
   CREATE PROCEDURE FU_INTZERO(
   WINT BIGINT,
   WTAM INTEGER)
   RETURNS (
   R_INTZERO VARCHAR(8192))
   AS
   begin
   /*
   Recebe um inteiro e devolve um string com zeros à esquerda no tamanho "WTAM"
   */
   if (:wint is null) then
   select r_replicate from Fu_replicate(:wtam, ' ') into r_IntZero;
   else begin
   select r_abs from fu_abs(:wint) into :wint;
   select r_Sright from Fu_S_Right('000000000000000000' || cast(:wint as varchar(18)), :wtam) into :r_intzero;
   end
suspend;
   end
=====================================
   CREATE PROCEDURE FU_LASTDAY(
   WANO SMALLINT,
   WMES SMALLINT)
   RETURNS (
   R_LASTDAY SMALLINT)
   AS
   declare variable i integer;
   begin
   /*
   Recebe um ano e um mês e devolve o último dia do mês daquele ano
   */
   if ((:wmes = 1) or (:wmes = 3) or (:wmes = 5) or (:wmes = 7) or  (:wmes = 8) or  (:wmes = 10) or (:wmes = 12)) then
   r_Lastday = 31;
   else if (:wmes = 2) then
   begin
   select r_mod from Fu_Mod(:wano, 4) into :i;
 if (:i = 0) then
   r_Lastday = 29;
   else
   r_Lastday = 28;
   end
   else
   r_Lastday = 30;
suspend;
   end
=========================================
   CREATE PROCEDURE FU_LAST_POS(
   WSUB VARCHAR(8192),
   WSTR VARCHAR(8192))
   RETURNS (
   R_LAST_POS SMALLINT)
   AS
   declare variable wtam smallint;
   declare variable trab varchar(8192);
   declare variable wint smallint = 1;
   begin
   /*
   Devolve a última posição do "WSUB" dentro do "WSTR"
   */
   r_last_pos = 0;
if ((:wsub is not null) and (:wstr is not null)) then begin
   select r_len from Fu_len(:wsub) into :wtam;
 while (:wstr <> '') do begin
   select r_copy from Fu_copy(:wstr, 1, :wtam) into :trab;
 if (:trab = :wsub) then
   r_last_pos = :wint;
 wint = :wint + 1;
   wstr = substring(:wstr from 2);
   end
   end
suspend;
   end
===========================================
   CREATE PROCEDURE FU_LEN(
   WSTR VARCHAR(8192))
   RETURNS (
   R_LEN SMALLINT)
   AS
   DECLARE VARIABLE L varchar(10);
   begin
   /*
   Devolve o tamanho em bytes de um string
   no FB 2 não é mais necessário
   */
   if (:wstr = 'MithBuster') then
   r_Len = 10;
   else begin
   wstr  = :wstr || 'MithBuster';
   r_Len = 0;
   l = substring(:wstr from 1 for 10);
 while (:l <> 'MithBuster') do begin
   r_Len = :r_Len + 1;
   wstr  = substring(:wstr from 2);
   l     = substring(:wstr from 1 for 10);
   end
   end
suspend;
   end
==============================================
   CREATE PROCEDURE FU_LTRIM(
   WVAR VARCHAR(8192))
   RETURNS (
   R_LTRIM VARCHAR(8192))
   AS
   DECLARE VARIABLE J INTEGER;
   DECLARE VARIABLE K INTEGER;
   begin
   /*
   Devolve um string sem espaços à esquerda
   */
   j = 0;
   select r_Len from Fu_Len(:wvar) into :k;
   r_ltrim = '';
while ((:wvar is not null) and (:k > 0)) do begin
   if (:j > 0) then
   r_ltrim = r_ltrim || substring(:wvar from 1 for 1);
   else if (substring(:wvar from 1 for 1) <> ' ') then begin
   r_ltrim = r_ltrim || substring(:wvar from 1 for 1);
   j = 1;
   end
 wvar = substring(:wvar from 2 for 8191);
   k = :k - 1;
   end
suspend;
   end
==========================================
   CREATE PROCEDURE FU_MES_EXT(
   WMES SMALLINT,
   WCEN CHAR(1),
   WTIP CHAR(1))
   RETURNS (
   R_MES_EXT VARCHAR(9))
   AS
   begin
   /*
   Devolve o mês por extenso (WMES) conforme o modelo desejado (WTIP)
   */
   if (:wtip = 'R') then
   begin
   if      (:wmes =  1) then r_mes_ext = 'JAN';
   else if (:wmes =  2) then r_mes_ext = 'FEV';
   else if (:wmes =  3) then r_mes_ext = 'MAR';
   else if (:wmes =  4) then r_mes_ext = 'ABR';
   else if (:wmes =  5) then r_mes_ext = 'MAI';
   else if (:wmes =  6) then r_mes_ext = 'JUN';
   else if (:wmes =  7) then r_mes_ext = 'JUL';
   else if (:wmes =  8) then r_mes_ext = 'AGO';
   else if (:wmes =  9) then r_mes_ext = 'SET';
   else if (:wmes = 10) then r_mes_ext = 'OUT';
   else if (:wmes = 11) then r_mes_ext = 'NOV';
   else if (:wmes = 12) then r_mes_ext = 'DEZ';
   end
   else if (:wcen = 'S') then
   begin
   if      (:wmes =  1) then r_mes_ext = ' JANEIRO ';
   else if (:wmes =  2) then r_mes_ext = 'FEVEREIRO';
   else if (:wmes =  3) then r_mes_ext = '  MARÇO  ';
   else if (:wmes =  4) then r_mes_ext = '  ABRIL  ';
   else if (:wmes =  5) then r_mes_ext = '   MAIO  ';
   else if (:wmes =  6) then r_mes_ext = '  JUNHO  ';
   else if (:wmes =  7) then r_mes_ext = '  JULHO  ';
   else if (:wmes =  8) then r_mes_ext = '  AGOSTO ';
   else if (:wmes =  9) then r_mes_ext = 'SETEMBRO ';
   else if (:wmes = 10) then r_mes_ext = ' OUTUBRO ';
   else if (:wmes = 11) then r_mes_ext = 'NOVEMBRO ';
   else if (:wmes = 12) then r_mes_ext = 'DEZEMBRO ';
   end
   else begin
   if      (:wmes =  1) then r_mes_ext = 'JANEIRO';
   else if (:wmes =  2) then r_mes_ext = 'FEVEREIRO';
   else if (:wmes =  3) then r_mes_ext = 'MARÇO';
   else if (:wmes =  4) then r_mes_ext = 'ABRIL';
   else if (:wmes =  5) then r_mes_ext = 'MAIO';
   else if (:wmes =  6) then r_mes_ext = 'JUNHO';
   else if (:wmes =  7) then r_mes_ext = 'JULHO';
   else if (:wmes =  8) then r_mes_ext = 'AGOSTO';
   else if (:wmes =  9) then r_mes_ext = 'SETEMBRO';
   else if (:wmes = 10) then r_mes_ext = 'OUTUBRO';
   else if (:wmes = 11) then r_mes_ext = 'NOVEMBRO';
   else if (:wmes = 12) then r_mes_ext = 'DEZEMBRO';
   end
suspend;
   end
=========================================
   CREATE PROCEDURE FU_MINUTESBETWEEN(
   WD1 TIMESTAMP,
   WD2 TIMESTAMP)
   RETURNS (
   R_MINUTESBETWEEN INTEGER)
   AS
   begin
   /*
   Minutos entre dois TS
   */
   r_MinutesBetween =
   (cast(substring(cast(:wd2 as varchar(24)) from 15 for 2) as integer) +
   (cast(substring(cast(:wd2 as varchar(24)) from 12 for 2) as integer) * 60)) -
   (cast(substring(cast(:wd1 as varchar(24)) from 15 for 2) as integer) +
   (cast(substring(cast(:wd1 as varchar(24)) from 12 for 2) as integer) * 60)) +
   cast((:wd2 - :wd1) as integer) * 1440;
   suspend;
   end
=============================================
   CREATE PROCEDURE FU_MOD(
   WRAD INTEGER,
   WDIV INTEGER)
   RETURNS (
   R_MOD INTEGER)
   AS
   begin
   /*
   Resto da divisão entre inteiros
   */
   if(:wrad < :wdiv) then
   r_mod = :wdiv;
   else
   R_MOD = :WRAD - ((:WRAD / :WDIV) * :WDIV);
suspend;
   end
===========================================
   CREATE PROCEDURE FU_ONLYCHAR(
   WVAR VARCHAR(255))
   RETURNS (
   R_ONLYCHAR VARCHAR(255))
   AS
   DECLARE VARIABLE K INTEGER;
   declare variable i integer;
   begin
   /*
   A partir de um string devolve somente o que não for números
   */
   select r_Len from Fu_Len(:wvar) into :k;
   r_onlychar = '';
while (:k > 0) do begin
   select result from Fu_Pos(substring(:wvar from 1 for 1), '0123456789') into :i;
 if (:i = 0) then
   r_onlychar = r_onlychar || substring(:wvar from 1 for 1);
 wvar = substring(:wvar from 2 for 255);
   k = :k - 1;
   end
suspend;
   end
==========================================
   CREATE PROCEDURE FU_ONLYDIGIT(
   WVAR VARCHAR(255))
   RETURNS (
   R_ONLYDIGIT VARCHAR(255))
   AS
   DECLARE VARIABLE K INTEGER;
   DECLARE VARIABLE I INTEGER;
   begin
   /*
   A partir de um string devolve apenas o que for número
   */
   select r_Len from Fu_Len(:wvar) into :k;
   r_onlydigit = '';
while (:k > 0) do begin
   select result from Fu_Pos(substring(:wvar from 1 for 1), '0123456789') into :i;
 if (:i > 0) then
   r_onlydigit = r_onlydigit || substring(:wvar from 1 for 1);
 wvar = substring(:wvar from 2 for 254);
   k = :k - 1;
   end
suspend;
   end
=======================================
   CREATE PROCEDURE FU_POS(
   SUB VARCHAR(8192),
   STR VARCHAR(8192))
   RETURNS (
   RESULT SMALLINT)
   AS
   DECLARE VARIABLE SUB2 VARCHAR(8192);
   DECLARE VARIABLE TMP  VARCHAR(8192);
   BEGIN
   /*
   Devolve a primeira posição de "SUB" dentro de "STR"
   */
   if ((Sub is null) or (Str is null)) then begin
   result = 0;
   exit;
   end
Sub2   = Sub || '%';
   Tmp    = '';
   result = 1;
while ((Str not like Sub2) and (Str not like Tmp)) do begin
   Sub2    = '_' || Sub2;
   Tmp     = Tmp || '_';
   result  = :result + 1;
   end
if (Str like Tmp) then
   result = 0;
suspend;
   end
==============================================
   CREATE PROCEDURE FU_QUEBRA_LINHA(
   WVAR VARCHAR(8192),
   WTAM SMALLINT)
   RETURNS (
   WLIN1 VARCHAR(8192),
   WLIN2 VARCHAR(8192))
   AS
   declare variable wini SmallInt;
   declare variable wstr char(1);
   begin
   /*
   WVAR = um string supostamente maior que uma linha de impressão desejada
   WTAM = O tamanho do espaço (linha) de impressão desejada
   OBS: Quando se digitar em tela um varchar digamos de 900 bytes se for pressionado um ENTER
   Em qualquer tempo antes do final então devemos gravar "<BR>" <-- = à quebra de linha no HTML
Então enviamos o Stringão e o tamanho e serão devolvidas linhas com até WTAM em bytes respeitando
   sempre uma quebra com espaços ou <BR>. Sem quebrar uma aplavra pelo meio
   Devolve WLIN1 com o string a ser impresso e WLIN2 com o resto até que WLIN2 seja NULL 
   */
   if (:wvar is not null) then begin                                 -- A variável está definida
   if ((:wtam is null) or (:wtam = 0)) then                         -- Tamamho não definido (só copia)
   wlin1 = :wvar;
   else begin                                                       -- Tamanho está definido
   if (substring(:wvar from 1 for 4) = '<BR>') then
   begin
   wlin1 = '';
   wlin2 = substring(:wvar from 5 for 8188);
   end
   else begin
   select result from Fu_Pos('<BR>', :wvar) into :wini;
 if (:wini > 0) then
   begin
   if (:wini > :wtam) then
   begin
   select r_copy from Fu_Copy (:wvar, 1, :wtam) into :wlin1;
   select r_copy from Fu_Copy (:wvar, (:wtam + 1), (8192 - :wtam)) into :wlin2;
   end
   else begin
   select r_copy from  Fu_copy  (:wvar, 1, (:wini - 1)) into :wlin1;
   select r_copy from  Fu_copy  (:wvar, (:wini + 4), (8192 - (:wini + 4))) into :wlin2;
   end
   end
   else begin
   select r_copy from  Fu_copy (:wvar, 1, :wtam) into :wlin1;
   select r_copy from  Fu_copy (:wvar, (:wtam + 1), (8192 - :wtam)) into :wlin2;
   end
 select r_rtrim from Fu_rtrim (:wlin1) into :wlin1;
   select r_len   from Fu_len   (:wlin1) into :wini;
 if (:wini = :wtam) then begin
   select result from Fu_pos(' ', :wlin1) into :wini;
 if (:wini > 0) then begin
   select r_sright from Fu_s_right(:wlin1, 1) into :wstr;
   select r_len   from Fu_len   (:wlin1) into :wtam;
 while ((:wstr <> ' ') and (:wtam > 0)) do begin
   select r_copy from Fu_Copy(:wlin1, 1, (:wtam - 1)) into :wlin1;
   wlin2 = :wstr || :wlin2;
   select r_sright from Fu_s_right(:wlin1, 1) into :wstr;
   wtam = :wtam - 1;
   end
   end
   end
   end     -- O tamanho é superior ao solicitado (quebra foi necessária)
   end      -- O tamanho estava definido
   end       -- A variável estava definida 
if (:wlin2 = '') then
   wlin2 = null;
if (:wlin2 is not null) then
   select r_ltrim from Fu_ltrim(:wlin2) into :wlin2;
   else
   wlin2 = null;
suspend;
   end
====================================================
   CREATE PROCEDURE FU_REPLACE_ALL_STR(
   WSTR VARCHAR(2048),
   OSTR VARCHAR(128),
   NSTR VARCHAR(128))
   RETURNS (
   WRET VARCHAR(8192))
   AS
   declare variable wlen smallint;
   declare variable part varchar(128);
   begin
   /*
   Troca wm WSTR tudo que encontrar igual a OSTR(OLD)  por NSTR (NEW)
   */
   select r_len from Fu_len(:ostr) into :wlen;
   wret = '';
while (:wstr <> '') do begin
   select r_copy from Fu_copy(:wstr, 1, :wlen) into :part;
 if (:part <> :ostr) then
   begin
   wret = :wret || substring(:wstr from 1 for 1);
   wstr = substring(:wstr from 2);
   end
   else begin
   wret = :wret || :nstr;
   select r_copy from Fu_copy(:wstr, :wlen + 1, 2047) into :wstr;
   end
   end
suspend;
   end
============================================
   CREATE PROCEDURE FU_REPLACE_STR(
   WSUB VARCHAR(2048),
   WSTR VARCHAR(2048),
   WPOS SMALLINT)
   RETURNS (
   WRET VARCHAR(4096))
   AS
   declare variable wlen smallint;
   declare variable wint smallint;
   begin
   /*
   Troca WSUB em WSTR na posição WPOS
   */
   select r_Len from Fu_Len(:wstr) into :wint;
if (:wint <= :wpos) then
   begin
   select r_DStr from Fu_DStr(:wstr, :wpos -1) into :wret;
   wret = :wret || :wsub;
   end
   else begin
   select r_Len from Fu_Len(:wsub) into :wlen;
   select r_Copy from Fu_Copy(:wstr, 1, (:wpos - 1)) into :wret;
   wret = :wret || :wsub;
   select r_Len from Fu_Len(:wret) into :wlen;
   select r_Copy from Fu_Copy(:wstr, :wlen + 1, :wint - :wlen) into :wstr;
   wret = :wret || :wstr;
   end
suspend;
   end
=======================================
   CREATE PROCEDURE FU_REPLICATE(
   WQTD INTEGER,
   WVAR VARCHAR(255))
   RETURNS (
   R_REPLICATE VARCHAR(8192))
   AS
   begin
   /*
   Replica WQTD caracteres ou strings em WVAR
   */
   r_replicate = '';
while (:wqtd > 0) do begin
   r_replicate = r_replicate || :wvar;
   wqtd = :wqtd - 1;
   end
suspend;
   end
=========================================
   CREATE PROCEDURE FU_RTRIM(
   WVAR VARCHAR(8192))
   RETURNS (
   R_RTRIM VARCHAR(8192))
   AS
   DECLARE VARIABLE I INTEGER;
   declare variable s varchar(1);
   begin
   /*
   Retira os espaços à direita de um string
   */
   select r_Len from Fu_Len(:wvar) into :i;
if ((:i < 2) or (:wvar = ' ')) then
   r_rtrim = '';
   else begin
   while ((:i > 0) and (:wvar is not null)) do begin
   select r_Sright from Fu_S_Right(:wvar, 1) into :s;
 if (:s = ' ') then
   begin
   select r_copy from Fu_copy(:wvar, 1, (:i - 1)) into :wvar;
   i = :i - 1;
   end
   else
   break;
   end
 r_rtrim = :wvar;
   end
suspend;
   end
================================================
   CREATE PROCEDURE FU_SEM_ACENTOS(
   WSTR VARCHAR(1024))
   RETURNS (
   R_SEM_ACENTOS VARCHAR(1024))
   AS
   DECLARE VARIABLE CA VARCHAR(53);
   DECLARE VARIABLE SA VARCHAR(53);
   DECLARE VARIABLE WI SMALLINT;
   DECLARE VARIABLE WT SMALLINT;
   declare variable i integer;
   DECLARE VARIABLE WS VARCHAR(2);
   begin
   /*
   Substitui caracteres acentuados de um string pelo correspondente sem acento.
   Útil para enviarmos string para impressoras matriciais ou Arquivos eletrônicos
   */
   if (:wstr is null) then
   wstr = '';
ca = '%°ºáàâãäéèêëíìîïóòôõöúùûüçÁÀÂÃÄÉÈÊËÍÌÎÏÓÒÔÕÖÚÙÛÜÇâÂñÑ';
   sa = '%rºaaaaaeeeeiiiiooooouuuucAAAAAEEEEIIIIOOOOOUUUUCaAhH';
   select r_Len from Fu_Len(:wstr) into :wt;
   wi = 1; 
   r_sem_acentos = '';
while (:wt > 0) do begin
   select r_Copy from Fu_Copy(:wstr, :wi, 1) into :ws;
 if (:ws <> ' ') then begin
   select result from Fu_Pos(:ws, :ca) into :i;
 if (:i > 0) then begin
   if (:ws = 'ñ') then
   ws = 'nh';
   else if (:ws = 'Ñ') then
   ws = 'NH';
   else
   select r_Copy from Fu_Copy(:sa, :i, 1) into :ws;
   end
   end
 r_sem_acentos = :r_sem_acentos || :ws;
   wt = :wt - 1;
   wi = :wi + 1;
   end
suspend;
   end
==========================================
   CREATE PROCEDURE FU_SORT_B(
   WSTR VARCHAR(8192),
   WDEL CHAR(1),
   WORD CHAR(1))
   RETURNS (
   WRET VARCHAR(8192))
   AS
   declare variable tra1 varchar(8192);
   declare variable wpos smallint;
   begin
   /*
   Classifica um string delimitado por WDEL na ordem WORD (A,D)
   */
   select result from Fu_pos(:wdel, :wstr) into :wpos;                 -- Primeiro delimitador
   select r_copy from Fu_copy(:wstr, 1, (:wpos -1)) into :tra1;        -- Primeira String
   wret = :tra1;                                                    -- Primeiro retorno = String
   select r_copy from Fu_copy(:wstr, (:wpos + 1), 8191) into :wstr;    -- STR resultante
while (:wstr <> '') do begin                                     -- Enquanto houver uma String...
   select result from Fu_pos(:wdel, :wstr) into :wpos;                -- Primeiro delimitador da STR resultante
 if (:wpos = 0) then                                             -- Se não tem mais...
   begin
   tra1 = :wstr;                                                 -- Inicializo :TRA1
   wstr = '';                                                    -- Esvazio STR resultante
   end
   else                                                            -- Senão...
   select r_copy from Fu_copy(:wstr, 1, (:wpos - 1)) into :tra1;     -- Primeira String
 select r_ret from Fu_class(:wret, :tra1, :wdel, :word) into :wret; -- Rotina de Classificação
   select r_copy from Fu_copy(:wstr, (:wpos + 1), 8191) into :wstr;   -- String resultante
   end
suspend;
   end
============================================
   CREATE PROCEDURE FU_SPACES(
   WQTD INTEGER)
   RETURNS (
   R_SPACES VARCHAR(8192))
   AS
   begin
   /*
   devolve WQTD espaços em um string
   */
   r_spaces = '';
while (:wqtd > 0) do begin
   r_spaces = r_spaces || ' ';
   wqtd = :wqtd - 1;
   end
suspend;
   end
===========================================
   CREATE PROCEDURE FU_SQRT(
   NUM DOUBLE PRECISION)
   RETURNS (
   SQR DOUBLE PRECISION)
   AS
   declare variable inc integer = 1;
   declare variable pas integer;
   declare variable nua double precision;
   begin
   /*
   Devolve a Raiz Quadrade de um número
   Há uma tolerância ou margem de erro para raizes inaxatas
   */
   pas = 0;                                         -- Passos (= SQR)
   nua = :num;                                      -- Salvando caso não seja inteiro
while (:num > 0) do begin
   num = :num - :inc;
   inc = :inc + 2;
   pas = :pas + 1;
   end
if (:num = 0) then
   sqr = :pas;                                     -- Quadrado perfeito
   else begin                                       -- Há fração
   sqr = :pas -1;                                  -- Maior quadrado que não ultrapasse
   sqr = cast((:sqr + 0.0001) as double precision);
 -- Otimizando de Quartas em Quartas partes (Divide o tempo de processamento por 4)
   if ((:sqr * :sqr) < :nua) then begin
   sqr = :sqr + 0.2500;                           -- Primeiro Quarto
 if ((:sqr * :sqr) > :nua) then
   begin
   sqr = :sqr - 0.2500;
 while ((:sqr * :sqr) <= :nua) do begin
   sqr = :sqr + 0.0001;
   end
   end
   else begin
   sqr = :sqr + 0.2500;                          -- Segundo Quarto
 if ((:sqr * :sqr) > :nua) then
   begin
   sqr = :sqr - 0.2500;
 while ((:sqr * :sqr) <= :nua) do begin
   sqr = :sqr + 0.0001;
   end
   end
   else begin                                    -- Terceiro Quarto
   sqr = :sqr + 0.2500;
 while ((:sqr * :sqr) > :nua) do begin
   sqr = :sqr - 0.0500;
   end
 while ((:sqr * :sqr) <= :nua) do begin
   sqr = :sqr + 0.0001;
   end
   end
   end
   end
 if ((:sqr * :sqr) > :nua) then
   sqr = :sqr - 0.0001;
   end
suspend;
   end
========================================
   CREATE PROCEDURE FU_STRZERO(
   WVAR VARCHAR(8192),
   WTAM INTEGER)
   RETURNS (
   R_STRZERO VARCHAR(8192))
   AS
   declare variable wint integer;
   begin
   /*
   Devolve WVAR com tamanho WTAM só que com zeros à esquerda
   */
   select r_Len from Fu_Len(:wvar) into :wint;
   wint = 255 - :wint;
   select r_Replicate from Fu_Replicate(:wint, '0') into r_StrZero;
   r_StrZero = r_StrZero || :wvar;                -- 255 Bytes
   select r_Sright from Fu_S_Right(:r_strzero, :wtam) into :r_strzero;
   suspend;
   end
======================================================
   CREATE PROCEDURE FU_S_LEFT(
   WVAR VARCHAR(8192),
   WQTD INTEGER)
   RETURNS (
   R_SLEFT VARCHAR(8192))
   AS
   DECLARE VARIABLE K INTEGER;
   begin
   /*
   Devolve WQTD caracteres à esquerda de um string
   */
   select r_Len from Fu_Len(:wvar) into :k;
   r_sleft = '';
while ((:wvar is not null) and (:k > 0) and (:wqtd > 0)) do begin
   r_sleft = r_sleft || substring(:wvar from 1 for 1);
   wvar = substring(:wvar from 2 for 8191);
   k    = :k - 1;
   wqtd = :wqtd - 1;
   end
suspend;
   end
================================================
   CREATE PROCEDURE FU_S_RIGHT(
   WVAR VARCHAR(8192),
   WQTD INTEGER)
   RETURNS (
   R_SRIGHT VARCHAR(8192))
   AS
   DECLARE VARIABLE K INTEGER;
   begin
   /*
   Devolve WQTD caracteres à direita de um string
   */
   if (:wvar is not null) then begin
   select r_Len from Fu_Len(:wvar) into :k;
 if (:wqtd >= :k) then
   r_sright = :wvar;
   else
   select r_Copy from Fu_Copy(:wvar, ((:k - :wqtd) + 1), :wqtd) into :r_sright;
   end
suspend;
   end
=============================================
   CREATE PROCEDURE FU_TEMPO_BETWEEN(
   INI TIMESTAMP,
   FIM TIMESTAMP)
   RETURNS (
   DIAS INTEGER,
   HORA INTEGER,
   MINU INTEGER,
   SEGU INTEGER)
   AS
   DECLARE VARIABLE TEMP NUMERIC(18,7);
   BEGIN
   /*
   Devolve dias, horas, minutos e segundos entre 2 TS
   */
   -- Inicializa variáveis
   dias = 0;
   hora = 0;
   minu = 0;
   segu = 0;
   -- Temp armazena a diferenca do periodo, em dias e frações de dias
   temp = (fim - ini);
   -- Pega o numero de dias - parte inteira
   if (:temp > 0) then
   dias = temp - 0.5;
   else
   dias = temp;
   -- extraí os dias do timestamp, deixando apenas hora/min/seg'
   temp = temp - dias;
   -- Um dia tem 86.400 segundos, assim transformamos o valor
   -- que temos em total em segundos
   temp = temp * 86400;
   -- Uma hora tem 3.600 segundos
   hora = (temp / 3600);
if (hora > 0) then
   hora = hora - 0.5;
   -- Temp vale agora minutos e segundos
   temp = temp - (hora * 3600);
   -- Um minuto tem 60 segundos
   minu = (temp / 60);
if (minu > 0) then
   minu = minu - 0.5;
   -- Para finalizar extrai os segundos
   segu = temp - (minu * 60);
suspend;
   end
===========================================
   CREATE PROCEDURE FU_TRIM(
   WVAR VARCHAR(8192))
   RETURNS (
   R_TRIM VARCHAR(8192))
   AS
   DECLARE VARIABLE J INTEGER;
   DECLARE VARIABLE K INTEGER;
   DECLARE VARIABLE I INTEGER;
   declare variable s varchar(1);
   begin
   /*
   Retira espaços à direita e à esquerda de um string
   */
   j = 0;
   select r_Len from Fu_Len(:wvar) into :k;
   r_trim = '';
while ((:wvar is not null) and (:k > 0)) do begin
   if (:j > 0) then
   r_trim = r_trim || substring(:wvar from 1 for 1);
   else if (substring(:wvar from 1 for 1) <> ' ') then begin
   r_trim = r_trim || substring(:wvar from 1 for 1);
   j = 1;
   end
 wvar = substring(:wvar from 2 for 8191);
   k = :k - 1;
   end
wvar = :r_trim;
select r_Len from Fu_Len(:wvar) into :i;
if ((:i < 2) or (:wvar = ' ')) then
   r_trim = '';
   else begin
   while ((:i > 0) and (:wvar is not null)) do begin
   select r_Sright from Fu_S_Right(:wvar, 1) into :s;
 if (:s = ' ') then
   begin
   select r_copy from Fu_copy(:wvar, 1, (:i - 1)) into :wvar;
   i = :i - 1;
   end
   else
   break;
   end
 r_trim = :wvar;
   end
suspend;
   end
====================================================
   CREATE PROCEDURE FU_TROCA_BYTES(
   WSTR VARCHAR(1024),
   WSUB VARCHAR(255),
   WTRO VARCHAR(255))
   RETURNS (
   R_TROCA_BYTES VARCHAR(1024))
   AS
   declare variable trab varchar(1024);
   declare variable xtra varchar(1024);
   declare variable wtra varchar(1024);
   declare variable wint smallint;
   declare variable tsub smallint;
   declare variable tstr smallint;
   begin
   /*
   Troca em WSTR todas as ocorrências de WSUB por WTRO encontradas
   */
   if (:wsub = :wtro) then
   r_troca_bytes = :wstr;
   else if (:wtro is null) then
   r_troca_bytes = :wstr;
   else if (:wsub is null) then
   r_troca_bytes = :wtro;
   else begin
   select r_len from Fu_len(:wstr) into :tstr;
   select r_len from Fu_len(:wsub) into :tsub;
   wtra = :wstr;
   wint = 1;
 if (:tsub > 255) then begin
   tsub = 255;
   wsub = substring(:wsub from 1 for 255);
   wtro = substring(:wtro from 1 for 255);            -- 1234567890
   end                                                 -- xxxxyyxxxx
 while (:wint > 0) do begin
   select result from Fu_pos(:wsub, :wtra) into :wint;
 if (:wint > 0) then begin
   select r_copy from Fu_copy(:wtra, 1, (:wint - 1)) into :trab;
   select r_copy from Fu_copy(:wtra, (:wint + :tsub), 1024) into :xtra;
   wtra = :trab || :wtro || :xtra;
   end
   end
 r_troca_bytes = :wtra;
   end
suspend;
   end
=================================================
   CREATE PROCEDURE FU_VALIDACGC(
   WCGC VARCHAR(14))
   RETURNS (
   OK CHAR(1))
   AS
   declare variable trab varchar(2);
   declare variable wcal varchar(12);
   declare variable wsom integer;
   declare variable wdig smallint;
   declare variable wint smallint;
   begin 
   /*
   Valida um CNPJ
   */
   select r_OnlyDigit from Fu_OnlyDigit(:wcgc) into :wcgc;
   wsom = 0;
   wcal = substring(:wcgc from 1 for 12);
   wint = 1;
while (:wint <= 4) do begin
   select r_Copy from Fu_Copy(:wcgc, :wint, 1) into :trab;
   wsom = :wsom + cast(:trab as smallint) * (6 - :wint);
   wint = :wint + 1;
   end
wint = 1;
while (:wint <= 8) do begin
   select r_Copy from Fu_Copy(:wcgc, (:wint + 4), 1) into :trab;
   wsom = :wsom + cast(:trab as smallint) * (10 - :wint);
   wint = :wint + 1;
   end
select r_mod from Fu_mod(:wsom, 11) into :wdig;
   wdig = 11 - :wdig;
if ((:wdig = 10) or (:wdig = 11)) then
   wcal = :wcal || '0';
   else
   wcal = :wcal || cast(:wdig as char(1));
wsom = 0;
   wint = 1;
while (:wint <= 5) do begin
   select r_Copy from Fu_Copy(:wcgc, :wint, 1) into :trab;
   wsom = :wsom + cast(:trab as smallint) * (7 - :wint);
   wint = :wint + 1;
   end
wint = 1;
while (:wint <= 8) do begin
   select r_Copy from Fu_Copy(:wcgc, (:wint + 5), 1) into :trab;
   wsom = :wsom + cast(:trab as smallint) * (10 - :wint);
   wint = :wint + 1;
   end
select r_mod from Fu_mod(:wsom, 11) into :wdig;
   wdig = 11 - :wdig;
if ((:wdig = 10) or (:wdig = 11)) then
   wcal = :wcal || '0';
   else
   wcal = :wcal || cast(:wdig as char(1));
if (:wcgc <> :wcal) then
   ok = 'N';
   else
   ok = 'S';
suspend;
   end
============================================
   CREATE PROCEDURE FU_VALIDACPF(
   WCPF VARCHAR(11))
   RETURNS (
   OK CHAR(1))
   AS
   declare variable trab varchar(2);
   declare variable wcal varchar(12);
   declare variable wsom integer;
   declare variable wdig smallint;
   declare variable wint smallint;
   begin 
   /*
   Valida um CPF
   */
   select r_OnlyDigit from Fu_OnlyDigit(:wcpf) into :wcpf;
   wsom = 0;
   wcal = substring(:wcpf from 1 for 9);
   wint = 1;
while (:wint <= 9) do begin
   select r_Copy from Fu_Copy(:wcpf, :wint, 1) into :trab;
   wsom = :wsom + cast(:trab as smallint) * (11 - :wint);
   wint = :wint + 1;
   end
select r_mod from Fu_mod(:wsom, 11) into :wdig;
   wdig = 11 - :wdig;
if ((:wdig = 10) or (:wdig = 11)) then
   wcal = :wcal || '0';
   else
   wcal = :wcal || cast(:wdig as char(1));
wsom = 0;
   wint = 1;
while (:wint <= 10) do begin
   select r_Copy from Fu_Copy(:wcpf, :wint, 1) into :trab;
   wsom = :wsom + cast(:trab as smallint) * (12 - :wint);
   wint = :wint + 1;
   end
select r_mod from Fu_mod(:wsom, 11) into :wdig;
   wdig = 11 - :wdig;
if ((:wdig = 10) or (:wdig = 11)) then
   wcal = :wcal || '0';
   else
   wcal = :wcal || cast(:wdig as char(1));
if (:wcpf <> :wcal) then
   ok = 'N';
   else
   ok = 'S';
suspend;
   end
==============================================
   Os IIFs abaixo trabalham conforme o IIF do Delphi só que
   recebendo e devolvendo a natureza de cada variável........
   Use quem preferir
   ----------------------------------------------------------
   CREATE PROCEDURE FU_IIF_DEC(
   STR1 DECIMAL(16,4),
   WSIG VARCHAR(2),
   STR2 DECIMAL(16,4),
   STR3 DECIMAL(16,4),
   STR4 DECIMAL(16,4))
   RETURNS (
   R_DEC DECIMAL(16,4))
   AS
   begin
   if (:wsig = '=') then
   begin
   if (:str1 = :str2) then
   r_dec = :str3;
   else
   r_dec = :str4;
   end
   else if (:wsig = '<') then
   begin
   if (:str1 < :str2) then
   r_dec = :str3;
   else
   r_dec = :str4;
   end
   else if (:wsig = '>') then
   begin
   if (:str1 > :str2) then
   r_dec = :str3;
   else
   r_dec = :str4;
   end
   else if (:wsig = '>=') then
   begin
   if (:str1 >= :str2) then
   r_dec = :str3;
   else
   r_dec = :str4;
   end
   else if (:wsig = '<=') then
   begin
   if (:str1 <= :str2) then
   r_dec = :str3;
   else
   r_dec = :str4;
   end
   else if (:wsig = '<>') then begin
   if (:str1 <> :str2) then
   r_dec = :str3;
   else
   r_dec = :str4;
   end
suspend;
   end
=======================================
   CREATE PROCEDURE FU_IIF_INT(
   STR1 INTEGER,
   WSIG VARCHAR(2),
   STR2 INTEGER,
   STR3 INTEGER,
   STR4 INTEGER)
   RETURNS (
   R_INT INTEGER)
   AS
   begin
   if (:wsig = '=') then
   begin
   if (:str1 = :str2) then
   r_int = :str3;
   else
   r_int = :str4;
   end
   else if (:wsig = '<') then
   begin
   if (:str1 < :str2) then
   r_int = :str3;
   else
   r_int = :str4;
   end
   else if (:wsig = '>') then
   begin
   if (:str1 > :str2) then
   r_int = :str3;
   else
   r_int = :str4;
   end
   else if (:wsig = '>=') then
   begin
   if (:str1 >= :str2) then
   r_int = :str3;
   else
   r_int = :str4;
   end
   else if (:wsig = '<=') then
   begin
   if (:str1 <= :str2) then
   r_int = :str3;
   else
   r_int = :str4;
   end
   else if (:wsig = '<>') then begin
   if (:str1 <> :str2) then
   r_int = :str3;
   else
   r_int = :str4;
   end
suspend;
   end
============================================
   CREATE PROCEDURE FU_IIF_INT_DEC(
   STR1 INTEGER,
   WSIG VARCHAR(2),
   STR2 INTEGER,
   STR3 DECIMAL(16,4),
   STR4 DECIMAL(16,4))
   RETURNS (
   R_INT_DEC DECIMAL(16,4))
   AS
   begin
   if (:wsig = '=') then
   begin
   if (:str1 = :str2) then
   r_int_dec = :str3;
   else
   r_int_dec = :str4;
   end
   else if (:wsig = '<') then
   begin
   if (:str1 < :str2) then
   r_int_dec = :str3;
   else
   r_int_dec = :str4;
   end
   else if (:wsig = '>') then
   begin
   if (:str1 > :str2) then
   r_int_dec = :str3;
   else
   r_int_dec = :str4;
   end
   else if (:wsig = '>=') then
   begin
   if (:str1 >= :str2) then
   r_int_dec = :str3;
   else
   r_int_dec = :str4;
   end
   else if (:wsig = '<=') then
   begin
   if (:str1 <= :str2) then
   r_int_dec = :str3;
   else
   r_int_dec = :str4;
   end
   else if (:wsig = '<>') then begin
   if (:str1 <> :str2) then
   r_int_dec = :str3;
   else
   r_int_dec = :str4;
   end
suspend;
   end
=============================================
   CREATE PROCEDURE FU_IIF_INT_SMI(
   STR1 INTEGER,
   WSIG VARCHAR(2),
   STR2 INTEGER,
   STR3 SMALLINT,
   STR4 SMALLINT)
   RETURNS (
   R_INT_SMI SMALLINT)
   AS
   begin
   if (:wsig = '=') then
   begin
   if (:str1 = :str2) then
   r_int_smi = :str3;
   else
   r_int_smi = :str4;
   end
   else if (:wsig = '<') then
   begin
   if (:str1 < :str2) then
   r_int_smi = :str3;
   else
   r_int_smi = :str4;
   end
   else if (:wsig = '>') then
   begin
   if (:str1 > :str2) then
   r_int_smi = :str3;
   else
   r_int_smi = :str4;
   end
   else if (:wsig = '>=') then
   begin
   if (:str1 >= :str2) then
   r_int_smi = :str3;
   else
   r_int_smi = :str4;
   end
   else if (:wsig = '<=') then
   begin
   if (:str1 <= :str2) then
   r_int_smi = :str3;
   else
   r_int_smi = :str4;
   end
   else if (:wsig = '<>') then begin
   if (:str1 <> :str2) then
   r_int_smi = :str3;
   else
   r_int_smi = :str4;
   end
suspend;
   end
=======================================
   CREATE PROCEDURE FU_IIF_INT_STR(
   STR1 INTEGER,
   WSIG VARCHAR(2),
   STR2 INTEGER,
   STR3 VARCHAR(255),
   STR4 VARCHAR(255))
   RETURNS (
   R_INT_STR VARCHAR(255))
   AS
   begin
   if (:wsig = '=') then
   begin
   if (:str1 = :str2) then
   r_int_str = :str3;
   else
   r_int_str = :str4;
   end
   else if (:wsig = '<') then
   begin
   if (:str1 < :str2) then
   r_int_str = :str3;
   else
   r_int_str = :str4;
   end
   else if (:wsig = '>') then
   begin
   if (:str1 > :str2) then
   r_int_str = :str3;
   else
   r_int_str = :str4;
   end
   else if (:wsig = '>=') then
   begin
   if (:str1 >= :str2) then
   r_int_str = :str3;
   else
   r_int_str = :str4;
   end
   else if (:wsig = '<=') then
   begin
   if (:str1 <= :str2) then
   r_int_str = :str3;
   else
   r_int_str = :str4;
   end
   else if (:wsig = '<>') then begin
   if (:str1 <> :str2) then
   r_int_str = :str3;
   else
   r_int_str = :str4;
   end
suspend;
   end
===============================================
   CREATE PROCEDURE FU_IIF_SMI(
   STR1 SMALLINT,
   WSIG VARCHAR(2),
   STR2 SMALLINT,
   STR3 SMALLINT,
   STR4 SMALLINT)
   RETURNS (
   R_SMI SMALLINT)
   AS
   begin
   if (:wsig = '=') then
   begin
   if (:str1 = :str2) then
   r_smi = :str3;
   else
   r_smi = :str4;
   end
   else if (:wsig = '<') then
   begin
   if (:str1 < :str2) then
   r_smi = :str3;
   else
   r_smi = :str4;
   end
   else if (:wsig = '>') then
   begin
   if (:str1 > :str2) then
   r_smi = :str3;
   else
   r_smi = :str4;
   end
   else if (:wsig = '>=') then
   begin
   if (:str1 >= :str2) then
   r_smi = :str3;
   else
   r_smi = :str4;
   end
   else if (:wsig = '<=') then
   begin
   if (:str1 <= :str2) then
   r_smi = :str3;
   else
   r_smi = :str4;
   end
   else if (:wsig = '<>') then begin
   if (:str1 <> :str2) then
   r_smi = :str3;
   else
   r_smi = :str4;
   end
suspend;
   end
========================================
   CREATE PROCEDURE FU_IIF_SMI_DEC(
   STR1 SMALLINT,
   WSIG VARCHAR(2),
   STR2 SMALLINT,
   STR3 DECIMAL(16,4),
   STR4 DECIMAL(16,4))
   RETURNS (
   R_SMI_DEC DECIMAL(16,4))
   AS
   begin
   if (:wsig = '=') then
   begin
   if (:str1 = :str2) then
   r_smi_dec = :str3;
   else
   r_smi_dec = :str4;
   end
   else if (:wsig = '<') then
   begin
   if (:str1 < :str2) then
   r_smi_dec = :str3;
   else
   r_smi_dec = :str4;
   end
   else if (:wsig = '>') then
   begin
   if (:str1 > :str2) then
   r_smi_dec = :str3;
   else
   r_smi_dec = :str4;
   end
   else if (:wsig = '>=') then
   begin
   if (:str1 >= :str2) then
   r_smi_dec = :str3;
   else
   r_smi_dec = :str4;
   end
   else if (:wsig = '<=') then
   begin
   if (:str1 <= :str2) then
   r_smi_dec = :str3;
   else
   r_smi_dec = :str4;
   end
   else if (:wsig = '<>') then begin
   if (:str1 <> :str2) then
   r_smi_dec = :str3;
   else
   r_smi_dec = :str4;
   end
suspend;
   end
=========================================
   CREATE PROCEDURE FU_IIF_SMI_INT(
   STR1 SMALLINT,
   WSIG VARCHAR(2),
   STR2 SMALLINT,
   STR3 INTEGER,
   STR4 INTEGER)
   RETURNS (
   R_SMI_INT INTEGER)
   AS
   begin
   if (:wsig = '=') then
   begin
   if (:str1 = :str2) then
   r_smi_int = :str3;
   else
   r_smi_int = :str4;
   end
   else if (:wsig = '<') then
   begin
   if (:str1 < :str2) then
   r_smi_int = :str3;
   else
   r_smi_int = :str4;
   end
   else if (:wsig = '>') then
   begin
   if (:str1 > :str2) then
   r_smi_int = :str3;
   else
   r_smi_int = :str4;
   end
   else if (:wsig = '>=') then
   begin
   if (:str1 >= :str2) then
   r_smi_int = :str3;
   else
   r_smi_int = :str4;
   end
   else if (:wsig = '<=') then
   begin
   if (:str1 <= :str2) then
   r_smi_int = :str3;
   else
   r_smi_int = :str4;
   end
   else if (:wsig = '<>') then begin
   if (:str1 <> :str2) then
   r_smi_int = :str3;
   else
   r_smi_int = :str4;
   end
suspend;
   end
============================================
   CREATE PROCEDURE FU_IIF_SMI_STR(
   STR1 SMALLINT,
   WSIG VARCHAR(2),
   STR2 SMALLINT,
   STR3 VARCHAR(255),
   STR4 VARCHAR(255))
   RETURNS (
   R_SMI_STR VARCHAR(255))
   AS
   begin
   if (:wsig = '=') then
   begin
   if (:str1 = :str2) then
   r_smi_STR = :str3;
   else
   r_smi_STR = :str4;
   end
   else if (:wsig = '<') then
   begin
   if (:str1 < :str2) then
   r_smi_STR = :str3;
   else
   r_smi_STR = :str4;
   end
   else if (:wsig = '>') then
   begin
   if (:str1 > :str2) then
   r_smi_STR = :str3;
   else
   r_smi_STR = :str4;
   end
   else if (:wsig = '>=') then
   begin
   if (:str1 >= :str2) then
   r_smi_STR = :str3;
   else
   r_smi_STR = :str4;
   end
   else if (:wsig = '<=') then
   begin
   if (:str1 <= :str2) then
   r_smi_STR = :str3;
   else
   r_smi_STR = :str4;
   end
   else if (:wsig = '<>') then begin
   if (:str1 <> :str2) then
   r_smi_STR = :str3;
   else
   r_smi_STR = :str4;
   end
suspend;
   end
=============================================
   CREATE PROCEDURE FU_IIF_STR(
   STR1 VARCHAR(255),
   WSIG VARCHAR(2),
   STR2 VARCHAR(255),
   STR3 VARCHAR(255),
   STR4 VARCHAR(255))
   RETURNS (
   R_STR VARCHAR(255))
   AS
   begin
   if (:wsig = '=') then
   begin
   if (:str1 = :str2) then
   r_str = :str3;
   else
   r_str = :str4;
   end
   else if (:wsig = '<') then
   begin
   if (:str1 < :str2) then
   r_str = :str3;
   else
   r_str = :str4;
   end
   else if (:wsig = '>') then
   begin
   if (:str1 > :str2) then
   r_str = :str3;
   else
   r_str = :str4;
   end
   else if (:wsig = '>=') then
   begin
   if (:str1 >= :str2) then
   r_str = :str3;
   else
   r_str = :str4;
   end
   else if (:wsig = '<=') then
   begin
   if (:str1 <= :str2) then
   r_str = :str3;
   else
   r_str = :str4;
   end
   else if (:wsig = '<>') then begin
   if (:str1 <> :str2) then
   r_str = :str3;
   else
   r_str = :str4;
   end
suspend;
   end
============================================
   CREATE PROCEDURE FU_IIF_STR_DEC(
   STR1 VARCHAR(255),
   WSIG VARCHAR(2),
   STR2 VARCHAR(255),
   STR3 DECIMAL(16,4),
   STR4 DECIMAL(16,4))
   RETURNS (
   R_STR_DEC DECIMAL(16,4))
   AS
   begin
   if (:wsig = '=') then
   begin
   if (:str1 = :str2) then
   r_str_dec = :str3;
   else
   r_str_dec = :str4;
   end
   else if (:wsig = '<') then
   begin
   if (:str1 < :str2) then
   r_str_dec = :str3;
   else
   r_str_dec = :str4;
   end
   else if (:wsig = '>') then
   begin
   if (:str1 > :str2) then
   r_str_dec = :str3;
   else
   r_str_dec = :str4;
   end
   else if (:wsig = '>=') then
   begin
   if (:str1 >= :str2) then
   r_str_dec = :str3;
   else
   r_str_dec = :str4;
   end
   else if (:wsig = '<=') then
   begin
   if (:str1 <= :str2) then
   r_str_dec = :str3;
   else
   r_str_dec = :str4;
   end
   else if (:wsig = '<>') then begin
   if (:str1 <> :str2) then
   r_str_dec = :str3;
   else
   r_str_dec = :str4;
   end
suspend;
   end
====================================================
   CREATE PROCEDURE FU_IIF_STR_INT(
   STR1 VARCHAR(255),
   WSIG VARCHAR(2),
   STR2 VARCHAR(255),
   STR3 INTEGER,
   STR4 INTEGER)
   RETURNS (
   R_STR_INT INTEGER)
   AS
   begin
   if (:wsig = '=') then
   begin
   if (:str1 = :str2) then
   r_str_int = :str3;
   else
   r_str_int = :str4;
   end
   else if (:wsig = '<') then
   begin
   if (:str1 < :str2) then
   r_str_int = :str3;
   else
   r_str_int = :str4;
   end
   else if (:wsig = '>') then
   begin
   if (:str1 > :str2) then
   r_str_int = :str3;
   else
   r_str_int = :str4;
   end
   else if (:wsig = '>=') then
   begin
   if (:str1 >= :str2) then
   r_str_int = :str3;
   else
   r_str_int = :str4;
   end
   else if (:wsig = '<=') then
   begin
   if (:str1 <= :str2) then
   r_str_int = :str3;
   else
   r_str_int = :str4;
   end
   else if (:wsig = '<>') then begin
   if (:str1 <> :str2) then
   r_str_int = :str3;
   else
   r_str_int = :str4;
   end
suspend;
   end
================================================
   CREATE PROCEDURE FU_IIF_STR_SMI(
   STR1 VARCHAR(255),
   WSIG VARCHAR(2),
   STR2 VARCHAR(255),
   STR3 SMALLINT,
   STR4 SMALLINT)
   RETURNS (
   R_STR_SMI SMALLINT)
   AS
   begin
   if (:wsig = '=') then
   begin
   if (:str1 = :str2) then
   r_str_smi = :str3;
   else
   r_str_smi = :str4;
   end
   else if (:wsig = '<') then
   begin
   if (:str1 < :str2) then
   r_str_smi = :str3;
   else
   r_str_smi = :str4;
   end
   else if (:wsig = '>') then
   begin
   if (:str1 > :str2) then
   r_str_smi = :str3;
   else
   r_str_smi = :str4;
   end
   else if (:wsig = '>=') then
   begin
   if (:str1 >= :str2) then
   r_str_smi = :str3;
   else
   r_str_smi = :str4;
   end
   else if (:wsig = '<=') then
   begin
   if (:str1 <= :str2) then
   r_str_smi = :str3;
   else
   r_str_smi = :str4;
   end
   else if (:wsig = '<>') then begin
   if (:str1 <> :str2) then
   r_str_smi = :str3;
   else
   r_str_smi = :str4;
   end
suspend;
   end