Diante da necessidade de gerar valores por extenso, pesquisando na web, deparei-me com a excelente procedure abaixo, para Firebird. Ela nao usa UDF s e consegue gerar extenso para valores de ate 8 (oito) quatrilhoes.Ela pode ignorar a geracao do extenso dos centavos, para o caso de um extenso para cheques (basta atribuir 'N' ao segundo parametro). Parabens ao Emersom, o autor dessa "belezura" !!!CREATE PROCEDURE EXTENSO ( valor numeric(18,2), cents char(1))returns ( valorextenso varchar(250))asdeclare variable cmoeda varchar(10);declare variable cmoedas varchar(10);declare variable ccentavo varchar(10);declare variable ccentavos varchar(10);declare variable cmil varchar(12);declare variable cmils varchar(12);declare variable cmilhao varchar(12);declare variable cmilhoes varchar(12);declare variable cbilhao varchar(12);declare variable cbilhoes varchar(12);declare variable ctrilhao varchar(12);declare variable ctrilhoes varchar(12);declare variable cquatrilhao varchar(12);declare variable cquatrilhoes varchar(12);declare variable cvalor varchar(100);declare variable nvalor smallint;declare variable cvalorint varchar(100);declare variable nvalorint integer;declare variable nvalordec numeric(6,3);declare variable i smallint;declare variable nconj integer;declare variable cletra varchar(1);declare variable caux varchar(200);declare variable extensocentavos varchar(100);declare variable separador varchar(3);declare variable extensoconj varchar(150);declare variable cdig1 varchar(10);declare variable cdig2 varchar(10);declare variable cdig3 varchar(10);declare variable centenas char(108) = 'CENTO DUZENTOS TREZENTOS QUATROCENTOSQUINHENTOS SEISCENTOS SETECENTOS OITOCENTOS NOVECENTOS ';declare variable dezenas char(79) = 'DEZ VINTE TRINTA QUARENTA CINQUENTASESSENTA SETENTA OITENTA NOVENTA ';declare variable unidades char(54) = 'UM DOIS TRES QUATROCINCO SEIS SETE OITO NOVE ';declare variable unid10 char(81) = 'ONZE DOZE TREZE QUATORZE QUINZE DEZESSEISDEZESSETEDEZOITO DEZENOVE ';declare variable extensounidade varchar(12);declare variable extensodezena varchar(12);declare variable extensocentena varchar(12);declare variable vlrextenso varchar(250);begin if (cents is null) then cents = 'S'; cents = UPPER(cents); -- poderia ter deixado esses valores fixos, -- mas preferi em variaveis cMil = 'MIL'; cMils = 'MIL'; cMilhao = 'MILHAO'; cMilhoes = 'MILHOES'; cBilhao = 'BILHAO'; cBilhoes = 'BILHOES'; cTrilhao = 'TRILHAO'; cTrilhoes = 'TRILHOES'; cQuatrilhao = 'QUATRILHAO'; cQuatrilhoes = 'QUATRILHOES'; cMoeda = 'REAL'; cMoedas = 'REAIS'; cCentavo = 'CENTAVO'; cCentavos = 'CENTAVOS'; Separador = ' '; -- valores a serem utilizados para geracao do extenso nValorInt = cast(valor/100*100 as integer); nValorDec = (Valor - Cast(nValorInt as numeric(18,3))) / 10; cAux = Cast(nValorDec as varchar(100)); cValorInt = Cast(nValorInt as varchar(100)) || Substring(cAux from 3 for 3); -- inverto o numero. assim fica mais facil trabalhar -- pois nao havera necessidade de UDF's cLetra = Substring(cValorInt from 1 for 1); cAux = cValorInt; cValorInt = ''; while (cAux <> '') do begin cValorInt = (cLetra || cValorInt); cAux = Substring(cAux from 2 for 100); cLetra = Substring(cAux from 1 for 1); if (cLetra = '') then cLetra = ' '; end -- obtenho os subconjuntos de numeros, de 3 em 3, -- para formar o extenso, que podera chegar aos quatrilhoes nConj = 1; extensocentavos = ''; vlrextenso = ''; if (Valor <> 0) then begin while (cValorInt <> '') do begin cValor = ''; i = 1; while (i <= 3) do begin cLetra = Substring(cValorInt from 1 for 1); if (cLetra = '') then cLetra = ' '; cValor = (cLetra || cValor); cValorInt = Substring(cValorInt from 2 for 100); i = (i + 1); end nValor = Cast(cValor as smallint); cDig1 = Substring(cValor from 1 for 1); cDig2 = Substring(cValor from 2 for 1); cDig3 = Substring(cValor from 3 for 1); extensounidade =