Club Delphi  
    Paypal   FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Bases de datos > Firebird e Interbase
Registrarse FAQ Miembros Calendario Guía de estilo Buscar Temas de Hoy Marcar Foros Como Leídos

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 30-09-2011
Avatar de defcon1_es
defcon1_es defcon1_es is offline
Miembro
 
Registrado: mar 2004
Ubicación: Cuenca - España
Posts: 533
Poder: 23
defcon1_es Va por buen camino
Hola. Varias cosas que yo tendría en cuenta:

1) Yo pondría en los uses a la unit ShareMem

Código Delphi [-]
unit Conversiones;  

interface  

uses Sharemem, ib_util, SysUtils, Classes;

Código Delphi [-]
library g_udf;

{ Important note about DLL memory management: ShareMem must be the
  first unit in your library's USES clause AND your project's (select
  Project-View Source) USES clause if your DLL exports any procedures or
  functions that pass strings as parameters or function results. This
  applies to all strings passed to and from your DLL--even those that
  are nested in records and classes. ShareMem is the interface unit to
  the BORLNDMM.DLL shared memory manager, which must be deployed along
  with your DLL. To avoid using BORLNDMM.DLL, pass string information
  using PChar or ShortString parameters. }

uses
  Sharemem,
  SysUtils,
  Classes,
  Conversiones in 'Conversiones.pas',
  ib_util in 'ib_util.pas';

{$R *.res}
  exports    
    NumeroALetra;

begin

end.

2) El fichero g_udf.dll debe estar en la carpeta UDF de Firebird

3) Borra la definición de la función de tu base de datos y vuelve a darla de alta tal como sugiere jhonny
__________________
Progress Openedge
https://abevoelker.com/progress_open...dered_harmful/


Delphi forever...
Responder Con Cita
  #2  
Antiguo 30-09-2011
Avatar de GustavoCruz
GustavoCruz GustavoCruz is offline
Miembro
 
Registrado: jul 2006
Ubicación: Sampués Sucre (Colombia)
Posts: 296
Poder: 20
GustavoCruz Va por buen camino
Hola amigo defcon1_es

esto es lo que me muestra ahora

Invalid data type, length, or value.
function A_LETRAS could not be matched.

la declaración en la base de datos es la siguiente:

Código SQL [-]
DECLARE EXTERNAL FUNCTION A_LETRAS
    DOUBLE PRECISION,
    CSTRING(10)
RETURNS CSTRING(600) FREE_IT
ENTRY_POINT 'NumeroALetra' MODULE_NAME 'g_udf';

Ya no se qué hacer...

Gracias por vuestro tiempo
Responder Con Cita
  #3  
Antiguo 30-09-2011
Avatar de Casimiro Noteví
Casimiro Noteví Casimiro Noteví is offline
Merodeador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.669
Poder: 10
Casimiro Noteví Tiene un aura espectacularCasimiro Noteví Tiene un aura espectacular
Por qué no nos escribes paso a paso, exactamente, todo lo que haces. Ya sabes, 4 ojos ven más que 2. Y en este caso 400 ojos ven más que 2
Responder Con Cita
  #4  
Antiguo 30-09-2011
Avatar de guillotmarc
guillotmarc guillotmarc is offline
Miembro
 
Registrado: may 2003
Ubicación: Huelva
Posts: 2.638
Poder: 26
guillotmarc Va por buen camino
Te sería mucho más cómodo traducir este código Delphi a Transact-SQL y así ponerlo en un procedimiento almacenado.

De esta forma no te tendrás que preocupar de UDF's, lo tendrás siempre disponible en tu base de datos. No te tendrás que preocupar de distribuirlo en nuevas instalaciones, de si tu servidor corre en Windows o en Linux, de si será compatible con nuevas versiones de Firebird, etc. ... ...

Claro que esa traducción no es trivial, pero las ventajas sobre una UDF valen la pena.
__________________
Marc Guillot (Hi ha 10 tipus de persones, els que saben binari i els que no).
Responder Con Cita
  #5  
Antiguo 30-09-2011
Avatar de GustavoCruz
GustavoCruz GustavoCruz is offline
Miembro
 
Registrado: jul 2006
Ubicación: Sampués Sucre (Colombia)
Posts: 296
Poder: 20
GustavoCruz Va por buen camino
Bueno listo...

1. Una vez compilado la udf. procedo a copiarla al directorio de UDF que está en la carpeta de Firebird.
2. paso siguiente reinicio el equipo; aunque con reiniciar el servicio es suficiente
3. inicio el IBExpert y borro la declaración previa de la udf
4. doy nuevamente de alta la función.
5. realizo una consulta cualquiera y no me funciona. me muestra los errores que ya he expuesto.

Nota:
No entiendo por qué me funciona en win7 y no así en win xp sp3
si fuese problema de la udf o del código no corriera en win7....

Gracias por vuestro tiempo
Responder Con Cita
  #6  
Antiguo 03-10-2011
cloayza cloayza is offline
Miembro
 
Registrado: may 2003
Ubicación: San Pedro de la Paz, Chile
Posts: 947
Poder: 25
cloayza Tiene un aura espectacularcloayza Tiene un aura espectacular
Cita:
Empezado por guillotmarc Ver Mensaje
Te sería mucho más cómodo traducir este código Delphi a Transact-SQL y así ponerlo en un procedimiento almacenado.

De esta forma no te tendrás que preocupar de UDF's, lo tendrás siempre disponible en tu base de datos. No te tendrás que preocupar de distribuirlo en nuevas instalaciones, de si tu servidor corre en Windows o en Linux, de si será compatible con nuevas versiones de Firebird, etc. ... ...

Claro que esa traducción no es trivial, pero las ventajas sobre una UDF valen la pena.
Tome tu idea, y comenze a buscar en la red algun codigo que realizara el trabajo de traducir numero a palabras. (Para que inventar la rueda ) ..y encontre esto Script de Oracle, especificamente este enlace Numeros a Palabras


Despues de analizar me puse manos a la obra y realizar la traduccion para Firebird...

La estuve probando (Firebird 2.5) y al parecer funciona bien, eso si que hay que seguir chequeando...Les dejo el script para la creacion de los procedimientos almacenados.

Cita:
/**************************************************************************************************** ******/
/* */
/* Procedure: NumberToWords */
/* Description: This package provides a function NumberToWords converting numbers to their */
/* English equivalent and returns it as a string. */
/* */
/* Version: 1.0.0 */
/* */
/* Required: Oracle Server Version 7.3 or higher. */
/* */
/* Example: */
/* */
/* SELECT NumberToWords.NumberToWords(1234567890) FROM DUAL; */
/* */
/* Written by: Material Dreams */
/* EMail: [email protected] */
/* WWW: http://www.materialdreams.com/oracle */
/* */
/* License: This script can be freely distributed as long as this header will not be removed and */
/* improvements and changes to this script will be reported to the author. */
/* */
/* Copyright (c) 1995-2004 by Material Dreams. All Rights Reserved. */
/* */
/**************************************************************************************************** ******/

/*
Traduccion a Firebird: Christian Loayza

SELECT * FROM NUMBER_EXECUTE(125425)
*/


SET TERM ^ ;
create procedure NUMBER_MILES (
THEVALUE integer)
returns (
ARESULT varchar(20))
as
begin
AResult='';
AResult=IIF(TheValue=1,' ',AResult);
AResult=IIF(TheValue=2,'mil',AResult);
AResult=IIF(TheValue=3,'millon',AResult);
AResult=IIF(TheValue=4,'billon',AResult);
AResult=IIF(TheValue=5,'trillon',AResult);
AResult=IIF(TheValue=6,'quatrillon',AResult);
AResult=IIF(TheValue=7,'quintillon',AResult);
AResult=IIF(TheValue=8,'sistillon',AResult);
AResult=IIF(TheValue=9,'septillion',AResult);
AResult=IIF(TheValue=10,'octillon',AResult);
AResult=IIF(TheValue=11,'nonillion',AResult);
AResult=IIF(TheValue=12,'decillion',AResult);
AResult=IIF(TheValue=13,'undecillion',AResult);
AResult=IIF(TheValue=14,'duodecillio',AResult);
AResult=IIF(TheValue=15,'tredecillion',AResult);
AResult=IIF(TheValue=16,'quintuordecillion',AResult);
AResult=IIF(TheValue=17,'sexdecillion',AResult);
AResult=IIF(TheValue=18,'septendecillion',AResult);
AResult=IIF(TheValue=19,'octodecillion',AResult);
AResult=IIF(TheValue=20,'novemdecillion',AResult);
AResult=IIF(TheValue=21,'vigintillion',AResult);
AResult=IIF(TheValue=22,'vigintillion',AResult);

end^

SET TERM ; ^

SET TERM ^ ;

create procedure NUMBER_NAME (
VALOR integer)
returns (
RESULT varchar(10))
as
begin
SELECT
CASE :Valor
WHEN 01 THEN 'cero'
WHEN 02 THEN 'uno'
WHEN 03 THEN 'dos'
WHEN 04 THEN 'tres'
WHEN 05 THEN 'cuatro'
WHEN 06 THEN 'cinco'
WHEN 07 THEN 'seis'
WHEN 08 THEN 'siete'
WHEN 09 THEN 'ocho'
WHEN 10 THEN 'nueve'
WHEN 11 THEN 'diez'
WHEN 12 THEN 'once'
WHEN 13 THEN 'doce'
WHEN 14 THEN 'trece'
WHEN 15 THEN 'catorce'
WHEN 16 THEN 'quince'
WHEN 17 THEN 'diesiseis'
WHEN 18 THEN 'diesisiete'
WHEN 19 THEN 'diesiocho'
WHEN 20 THEN 'diesinueve'
WHEN 21 THEN iif(MOD(:VALOR, 10)=0,'veinte','veinti')
WHEN 22 THEN 'treinta'
WHEN 23 THEN 'cuarenta'
WHEN 24 THEN 'cincuenta'
WHEN 25 THEN 'sesenta'
WHEN 26 THEN 'setenta'
WHEN 27 THEN 'ochenta'
WHEN 28 THEN 'noventa'
WHEN 29 THEN ''
END as Result
FROM
rdb$database
into :Result;

suspend;
end^

SET TERM ; ^

SET TERM ^ ;

create procedure NUMBER_VALUE (
VALOR integer)
returns (
RESULT integer)
as
begin
SELECT
CASE :Valor
WHEN 01 THEN 0
WHEN 02 THEN 1
WHEN 03 THEN 2
WHEN 04 THEN 3
WHEN 05 THEN 4
WHEN 06 THEN 5
WHEN 07 THEN 6
WHEN 08 THEN 7
WHEN 09 THEN 8
WHEN 10 THEN 9
WHEN 11 THEN 10
WHEN 12 THEN 11
WHEN 13 THEN 12
WHEN 14 THEN 13
WHEN 15 THEN 14
WHEN 16 THEN 15
WHEN 17 THEN 16
WHEN 18 THEN 17
WHEN 19 THEN 18
WHEN 20 THEN 19
WHEN 21 THEN 20
WHEN 22 THEN 30
WHEN 23 THEN 40
WHEN 24 THEN 50
WHEN 25 THEN 60
WHEN 26 THEN 70
WHEN 27 THEN 80
WHEN 28 THEN 90
WHEN 29 THEN 999
END as result
FROM
rdb$database
Into :Result;
SUSPEND;

end^

SET TERM ; ^

SET TERM ^ ;
create procedure NUMBER_DECENAS (
THEVALUE integer)
returns (
S varchar(80))
as
declare variable V integer;
declare variable I integer;
declare variable X integer;
declare variable CNAME varchar(10);
BEGIN
v = theValue;
i = 1;
s ='';
EXECUTE PROCEDURE NUMBER_VALUE(i) RETURNING_VALUES :x;
WHILE (x <= v) DO
BEGIN
i = i + 1;
EXECUTE PROCEDURE NUMBER_VALUE(i) RETURNING_VALUES :x;
END

EXECUTE PROCEDURE NUMBER_NAME(i-1) RETURNING_VALUES :cname;
EXECUTE PROCEDURE NUMBER_VALUE(i-1) RETURNING_VALUES :x;
v = v - x;
s=TRIM(cname);

IF (v > 0) THEN
BEGIN
EXECUTE PROCEDURE NUMBER_NAME(v+1) RETURNING_VALUES :cname;
IF (X<>20) THEN
s = s || ' y ' || TRIM(cname);
ELSE
s = s || IIF(s<>'',' ','') || TRIM(cname);
END
SUSPEND;
end^

SET TERM ; ^

SET TERM ^ ;

create procedure NUMBER_CENTENAS (
THEVALUE integer)
returns (
S varchar(80))
as
declare variable V integer;
declare variable N integer;
declare variable R integer;
declare variable M integer;
declare variable CNAME varchar(80);
BEGIN
v = theValue;
m = MOD(v, 100);
r = FLOOR(v / 100);
s = '';

IF (r > 0) THEN
BEGIN
s='';
s=IIF(r=1 and m=0,'cien',s);
s=IIF(r=1 and m>1,'ciento',s);
s=IIF(r=2,'doscientos',s);
s=IIF(r=3,'trescientos',s);
s=IIF(r=4,'cuatrocientos',s);
s=IIF(r=5,'quinientos',s);
s=IIF(r=6,'seiscientos',s);
s=IIF(r=7,'setecientos',s);
s=IIF(r=8,'ochocientos',s);
s=IIF(r=9,'novecientos',s);
END

IF (m > 0) THEN
BEGIN
EXECUTE PROCEDURE NUMBER_DECENAS(m) RETURNING_VALUES :cname;
s = s ||IIF(s<>'',' ','')||TRIM(cname);
END
SUSPEND;
END^

SET TERM ; ^

SET TERM ^ ;

create procedure NUMBER_EXECUTE (
THENUMBER integer)
returns (
WORD varchar(255))
as

declare variable TRUE integer;
declare variable FALSE integer;
declare variable VAL integer;
declare variable TRI integer;
declare variable PLACE integer;
declare variable NEG integer;
declare variable TEMP varchar(255);
declare variable PHRASE varchar(255);
declare variable S varchar(80);
begin
True=1; False=0; Tri=0; place=0; neg=0; Word='';
val=TheNumber;

-- check for 0
IF (val = 0) THEN
BEGIN
word = 'zero';
suspend;
exit;
END

-- check for negative int
IF (val < 0) THEN
BEGIN
neg= TRUE;
val= -val;
END

-- what we do now is break it up into sets of three, and add the appropriate denominations to each
WHILE (val > 0) DO
BEGIN
phrase = '';
tri = MOD(val, 1000); -- last tree digits
val = FLOOR(val / 1000); -- base 10 shift by 3
IF (tri > 0) THEN
BEGIN
EXECUTE PROCEDURE NUMBER_CENTENAS(tri) RETURNING_VALUES :s;
phrase = phrase || s;
END

IF ((place > 0) AND (tri > 0)) THEN
begin
EXECUTE PROCEDURE NUMBER_MILES(place+1) RETURNING_VALUES :s;

IF (MOD(Tri, 10)=1 ) THEN
phrase = SUBSTRING(phrase FROM 1 FOR CHAR_LENGTH(TRIM(phrase)))||' '|| s;
ELSE
phrase = phrase ||' '|| s ||IIF(place>=2,'es','');
end
place = place + 1;

-- got the phrase, now put in the string
temp = word;
IF ((val > 0) AND (tri > 0)) THEN
word = ' ' || phrase;
ELSE
word = phrase;

word = word || temp;
END

-- remember that minus sign
IF (neg=True) THEN
word = 'negative ' || word;

SUSPEND;
end
^
SET TERM ; ^


Saludos
Responder Con Cita
  #7  
Antiguo 03-10-2011
cloayza cloayza is offline
Miembro
 
Registrado: may 2003
Ubicación: San Pedro de la Paz, Chile
Posts: 947
Poder: 25
cloayza Tiene un aura espectacularcloayza Tiene un aura espectacular
Subi el script al FTP del Club

Números a Palabras Firebird

Chaito
Responder Con Cita
  #8  
Antiguo 03-10-2011
Avatar de Casimiro Noteví
Casimiro Noteví Casimiro Noteví is offline
Merodeador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.669
Poder: 10
Casimiro Noteví Tiene un aura espectacularCasimiro Noteví Tiene un aura espectacular
Interesante, hacerlo en la propia base de datos.
Gracias por el aporte.
Responder Con Cita
Respuesta


Herramientas Buscar en Tema
Buscar en Tema:

Búsqueda Avanzada
Desplegado

Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
funciona bien en windows 7 64b pero en XP no funciona ASAPLTDA Varios 5 06-05-2011 16:24:50
IDE funciona mal dfarias Varios 2 10-02-2009 11:04:26
No funciona PHP silviodp PHP 6 07-06-2008 21:51:29
¿Así funciona el BETWEEN? Faust Firebird e Interbase 4 13-05-2008 01:58:40
like no funciona ! dmasson Conexión con bases de datos 9 23-03-2004 14:10:50


La franja horaria es GMT +2. Ahora son las 04:03:11.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi