Club Delphi  
    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 13-12-2015
mRoman mRoman is offline
Miembro
 
Registrado: Nov 2003
Posts: 352
Poder: 15
mRoman Va por buen camino
Parametros en IN del Where

Hola amigos buenas noches.

Uso DELPHI6, FireBird 2.0

Estoy tratanto de pasar como parametro una cadena tipo VarChar de 300 en un store procedure. Este el SP estoy construyendo:
Código SQL [-]
CREATE PROCEDURE MOVTOS_MASIVOS_DOTACIONES(
  I_FECHA_INI DATE,
  I_FECHA_FIN DATE,
  I_PORCENTAJE SMALLINT,
  I_LECHERIAS VARCHAR(300))
AS
DECLARE VARIABLE V_NVA_DOT_LTS INTEGER;
DECLARE VARIABLE V_NVA_DOT_CANAST INTEGER;
DECLARE VARIABLE V_LECHERIA NUMERIC(10, 2);
DECLARE VARIABLE V_DOT_ACTUAL_LTS INTEGER;
DECLARE VARIABLE V_DOT_ACTUAL_CANAST INTEGER;
DECLARE VARIABLE V_FECHA_DISTR DATE;
DECLARE VARIABLE V_FECHA_VENTA DATE;
DECLARE VARIABLE V_CANAST_NUEVAS INTEGER;
DECLARE VARIABLE V_LTS_NUEVOS INTEGER;
DECLARE VARIABLE V_CANAST_AFECTADAS INTEGER;
DECLARE VARIABLE V_PIEZAS SMALLINT;
DECLARE VARIABLE V_EQ_LITROS SMALLINT;
BEGIN
     DELETE FROM MOVTOS_MASIVOS_DOTAC;
     FOR SELECT a.FECHA_DISTRIBUCION,
             a.FECHA_VENTA,
            a.lecher,
            a.dotacion_programada,
            ROUND(a.dotacion_programada/(c.piezas*c.equivalente_litros)),
                C.PIEZAS,
                C.EQUIVALENTE_LITROS
       from guia_venta_diaria a,
          lecheria b,
          producto c
         where a.lecher=b.lecher
        and a.fecha_venta between :I_FECHA_INI and :I_FECHA_FIN
        and a.cve_producto=c.cve_producto
        and a.cve_producto like 'AS%'
              and a.LECHER IN (:I_LECHERIAS)
       order by a.fecha_venta,a.lecher
           INTO :V_FECHA_DISTR,
                :V_FECHA_VENTA,
                :V_LECHERIA,
                :V_DOT_ACTUAL_LTS,
                :V_DOT_ACTUAL_CANAST,
                :V_PIEZAS,
                :V_EQ_LITROS DO
                BEGIN
                    V_CANAST_AFECTADAS=round(ROUND(:V_DOT_ACTUAL_LTS/(:V_PIEZAS*:V_EQ_LITROS))*(:I_PORCENTAJE/100.00) );
                    V_CANAST_NUEVAS=:V_DOT_ACTUAL_CANAST-:V_CANAST_AFECTADAS;
                    V_LTS_NUEVOS=:V_CANAST_NUEVAS*(:V_PIEZAS*:V_EQ_LITROS);
                    
                    INSERT INTO MOVTOS_MASIVOS_DOTAC(   FECHA_DISTRIBUCION,
                            FECHA_VENTA,
                            LECHERIA,
                            CVE_PRODUCTO,
                            DOTACION_LTS_ACTUAL,
                            DOTACION_CANASTILLAS_ACTUAL,
                            PORCENTAJE,
                            DOTACION_LTS_NUEVOS,
                            DOTACION_CANASTILLAS_NUEVAS,
                            CANASTILLAS_AFECTADAS)
                                    values(  :V_FECHA_DISTR,
                                             :V_FECHA_VENTA,
                                             :V_LECHERIA,
                                             'AS-606-1315',
                                             :V_DOT_ACTUAL_LTS,
                                             :V_DOT_ACTUAL_CANAST,
                                             :I_PORCENTAJE,
                                             :V_LTS_NUEVOS,
                                             :V_CANAST_NUEVAS,
                                             :V_CANAST_AFECTADAS);

                END
END

Lo marcado en ROJO, se puede usar en un procedimiento almacenado?...o como le hago para se ejecute sin que marque error??

Dentro de Delphi, acumulo ciertos datos del tipo string en una variable, les pongo codigo:
Código Delphi [-]
procedure TfrmMovtosMasivos.BitBtn1Click(Sender: TObject);
var
   i:integer;
begin
    cLecherias:='';
    With lvLecherias do
    begin
         for i:=0 to lvLecherias.Items.Count-1 do
         begin
             if Items[i].Checked then
             begin
                 cLecherias:=cLecherias+Items[i].SubItems[0]+',';
             end;
         end;
    end;
    cLecherias:=copy(cLecherias,1,Length(cLecherias)-1);
    spcDotMasivas.Close;
    spcDotMasivas.ParamByName('i_fecha_ini').AsDate:=FechaInicial.Date;
    spcDotMasivas.ParamByName('i_fecha_fin').AsDate:=FechaFinal.Date;
    spcDotMasivas.ParamByName('i_porcentaje').AsString:=mskPorcentaje.Text;
    spcDotMasivas.ParamByName('i_lecherias').AsString:=cLecherias;
    spcDotMasivas.ExecProc;
end;

Donde en la sección q deje de rojo, intento pasarle una cadena como esta: 12309102,1029301902,109239013, pero marca un error a la hora de ejecutar el SP, el mensaje de error es el siguiente:

Código:
Arithmetic exception, numeric overflow, or string truncation.
At procedure 'MOVTOS_MASIVOS_DOTACIONES'.

Lo anterior es porque quiero pasarle todas las claves en una sola variable al SP, usando el COMANDO IN del WHERE, pero no he podido. Esto claro esta que se puede resolver si quito el FOR del SELECT....bueno quedaria asi:

Código SQL [-]
CREATE PROCEDURE MOVTOS_MASIVOS_DOTACIONES(
  I_FECHA_INI DATE,
  I_FECHA_FIN DATE,
  I_PORCENTAJE SMALLINT,
  I_LECHERIAS NUMERIC(10))
AS
DECLARE VARIABLE V_NVA_DOT_LTS INTEGER;
DECLARE VARIABLE V_NVA_DOT_CANAST INTEGER;
DECLARE VARIABLE V_LECHERIA NUMERIC(10, 2);
DECLARE VARIABLE V_DOT_ACTUAL_LTS INTEGER;
DECLARE VARIABLE V_DOT_ACTUAL_CANAST INTEGER;
DECLARE VARIABLE V_FECHA_DISTR DATE;
DECLARE VARIABLE V_FECHA_VENTA DATE;
DECLARE VARIABLE V_CANAST_NUEVAS INTEGER;
DECLARE VARIABLE V_LTS_NUEVOS INTEGER;
DECLARE VARIABLE V_CANAST_AFECTADAS INTEGER;
DECLARE VARIABLE V_PIEZAS SMALLINT;
DECLARE VARIABLE V_EQ_LITROS SMALLINT;
BEGIN
     DELETE FROM MOVTOS_MASIVOS_DOTAC;
     SELECT a.FECHA_DISTRIBUCION,
             a.FECHA_VENTA,
            a.lecher,
            a.dotacion_programada,
            ROUND(a.dotacion_programada/(c.piezas*c.equivalente_litros)),
                C.PIEZAS,
                C.EQUIVALENTE_LITROS
       from guia_venta_diaria a,
          lecheria b,
          producto c
         where a.lecher=b.lecher
        and a.fecha_venta between :I_FECHA_INI and :I_FECHA_FIN
        and a.cve_producto=c.cve_producto
        and a.cve_producto like 'AS%'
              and a.LECHER=:I_LECHERIAS
       order by a.fecha_venta,a.lecher
           INTO :V_FECHA_DISTR,
                :V_FECHA_VENTA,
                :V_LECHERIA,
                :V_DOT_ACTUAL_LTS,
                :V_DOT_ACTUAL_CANAST,
                :V_PIEZAS,
                :V_EQ_LITROS DO
                BEGIN
                    V_CANAST_AFECTADAS=round(ROUND(:V_DOT_ACTUAL_LTS/(:V_PIEZAS*:V_EQ_LITROS))*(:I_PORCENTAJE/100.00) );
                    V_CANAST_NUEVAS=:V_DOT_ACTUAL_CANAST-:V_CANAST_AFECTADAS;
                    V_LTS_NUEVOS=:V_CANAST_NUEVAS*(:V_PIEZAS*:V_EQ_LITROS);
                    
                    INSERT INTO MOVTOS_MASIVOS_DOTAC(   FECHA_DISTRIBUCION,
                            FECHA_VENTA,
                            LECHERIA,
                            CVE_PRODUCTO,
                            DOTACION_LTS_ACTUAL,
                            DOTACION_CANASTILLAS_ACTUAL,
                            PORCENTAJE,
                            DOTACION_LTS_NUEVOS,
                            DOTACION_CANASTILLAS_NUEVAS,
                            CANASTILLAS_AFECTADAS)
                                    values(  :V_FECHA_DISTR,
                                             :V_FECHA_VENTA,
                                             :V_LECHERIA,
                                             'AS-606-1315',
                                             :V_DOT_ACTUAL_LTS,
                                             :V_DOT_ACTUAL_CANAST,
                                             :I_PORCENTAJE,
                                             :V_LTS_NUEVOS,
                                             :V_CANAST_NUEVAS,
                                             :V_CANAST_AFECTADAS);

                END
END

La pregunta es la siguiente: Puedo hacer esto dentro del WHERE para usar IN, de esta forma:
ej.
where CODIGO IN (:CODIGOS)

Donde CODIGOS, puediera tener la siguientes cadena: 1234,5678,19281 ???

Espero haberme explicado, sino, comentenme para ser mas explicito. Saludos y gracias por su tiempo !.
__________________
Miguel Román

Afectuoso saludo desde tierras mexicanas....un aguachile?, con unas "cetaseas" bien "muertas"?, VENTE PUES !!

Última edición por mRoman fecha: 13-12-2015 a las 06:33:00.
Responder Con Cita
  #2  
Antiguo 13-12-2015
Avatar de AgustinOrtu
[AgustinOrtu] AgustinOrtu is offline
Miembro Premium
 
Registrado: Aug 2013
Ubicación: Argentina
Posts: 1.858
Poder: 10
AgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en bruto
Que yo sepa eso no se hace con parametros, en las versiones mas nuevas de de Delphi, con FireDAC incorporado creo que se puede hacer con algo que se llama "macro expand"

Pero en definitiva, lo que termina haciendo es sustituir el lugar indicado dentro del SQL por la secuencia de caracteres. No se como implementarlo dentro de un SP, pero si fuera que mandas un query desde delphi podes hacer algo asi:

Código Delphi [-]
procedure EjecutarSQL;
  procedure BuildStr;
  var
    I: Integer;
  begin
    Result := '';
    for I :=0 to lvLecherias.Items.Count - 1 do
      ...
  end;
begin
  SQL.Text := Format(' WHERE A.Lecher IN (%s) ', [BuildStr]);
  SQL.Open;
  ...
end;

Yo creo que el secreto esta en implementar esa logica dentro del stored, es decir, acumular dentro de una variable local la cadena que se va a usar en el operador IN
Responder Con Cita
  #3  
Antiguo 13-12-2015
mRoman mRoman is offline
Miembro
 
Registrado: Nov 2003
Posts: 352
Poder: 15
mRoman Va por buen camino
Execute Statement

Cita:
Empezado por AgustinOrtu Ver Mensaje
Que yo sepa eso no se hace con parametros, en las versiones mas nuevas de de Delphi, con FireDAC incorporado creo que se puede hacer con algo que se llama "macro expand"

Pero en definitiva, lo que termina haciendo es sustituir el lugar indicado dentro del SQL por la secuencia de caracteres. No se como implementarlo dentro de un SP, pero si fuera que mandas un query desde delphi podes hacer algo asi:

Código Delphi [-]
procedure EjecutarSQL;
  procedure BuildStr;
  var
    I: Integer;
  begin
    Result := '';
    for I :=0 to lvLecherias.Items.Count - 1 do
      ...
  end;
begin
  SQL.Text := Format(' WHERE A.Lecher IN (%s) ', [BuildStr]);
  SQL.Open;
  ...
end;

Yo creo que el secreto esta en implementar esa logica dentro del stored, es decir, acumular dentro de una variable local la cadena que se va a usar en el operador IN
Antes que nada muchas gracias por contestar y darte tiempo para decirme lo q escribiste.

Efectivamente aplicar una lógica como la q planteas, es lo q busco, y me parece que la solucion esta en esta instruccion:

EXECUTE STATEMENT

Aqui esta un ejemplo. No es otra cosa mas que construir la consulta dentro del SP y concatenar cadenas....y ahi es donde se pudiera hacer lo que busco.

Código SQL [-]
CREATE PROCEDURE MOVTOS_MASIVOS_DOTACIONES(
  I_FECHA_INI DATE,
  I_FECHA_FIN DATE,
  I_PORCENTAJE SMALLINT,
  I_LECHERIAS VARCHAR(300))
AS
DECLARE VARIABLE V_NVA_DOT_LTS INTEGER;
DECLARE VARIABLE V_NVA_DOT_CANAST INTEGER;
DECLARE VARIABLE V_LECHERIA NUMERIC(10, 2);
DECLARE VARIABLE V_DOT_ACTUAL_LTS INTEGER;
DECLARE VARIABLE V_DOT_ACTUAL_CANAST INTEGER;
DECLARE VARIABLE V_FECHA_DISTR DATE;
DECLARE VARIABLE V_FECHA_VENTA DATE;
DECLARE VARIABLE V_CANAST_NUEVAS INTEGER;
DECLARE VARIABLE V_LTS_NUEVOS INTEGER;
DECLARE VARIABLE V_CANAST_AFECTADAS INTEGER;
DECLARE VARIABLE V_PIEZAS SMALLINT;
DECLARE VARIABLE V_EQ_LITROS SMALLINT;
DECLARE VARIABLE V_SENTENCIA VARCHAR(1000);
BEGIN
     DELETE FROM MOVTOS_MASIVOS_DOTAC;
     V_SENTENCIA=' SELECT a.FECHA_DISTRIBUCION,a.FECHA_VENTA,
                  a.lecher,
                  a.dotacion_programada,
                  ROUND(a.dotacion_programada/(c.piezas*c.equivalente_litros)),
                      C.PIEZAS,
                      C.EQUIVALENTE_LITROS
             from guia_venta_diaria a,
               lecheria b,
               producto c
              where a.lecher=b.lecher
              and a.fecha_venta between '''||I_FECHA_INI||''' and '''||I_FECHA_FIN||'''
              and a.cve_producto=c.cve_producto
              and a.cve_producto like ''AS-606-1315''
                    and a.LECHER IN ('||I_LECHERIAS||') 
                    order by a.fecha_venta,a.lecher';
     FOR EXECUTE STATEMENT V_SENTENCIA
           INTO :V_FECHA_DISTR,
                :V_FECHA_VENTA,
                :V_LECHERIA,
                :V_DOT_ACTUAL_LTS,
                :V_DOT_ACTUAL_CANAST,
                :V_PIEZAS,
                :V_EQ_LITROS DO
                BEGIN
                    V_CANAST_AFECTADAS=round(ROUND(:V_DOT_ACTUAL_LTS/(:V_PIEZAS*:V_EQ_LITROS))*(:I_PORCENTAJE/100.00) );
                    V_CANAST_NUEVAS=:V_DOT_ACTUAL_CANAST-:V_CANAST_AFECTADAS;
                    V_LTS_NUEVOS=:V_CANAST_NUEVAS*(:V_PIEZAS*:V_EQ_LITROS);
                    
                    INSERT INTO MOVTOS_MASIVOS_DOTAC(   FECHA_DISTRIBUCION,
                            FECHA_VENTA,
                            LECHERIA,
                            CVE_PRODUCTO,
                            DOTACION_LTS_ACTUAL,
                            DOTACION_CANASTILLAS_ACTUAL,
                            PORCENTAJE,
                            DOTACION_LTS_NUEVOS,
                            DOTACION_CANASTILLAS_NUEVAS,
                            CANASTILLAS_AFECTADAS)
                                    values(  :V_FECHA_DISTR,
                                             :V_FECHA_VENTA,
                                             :V_LECHERIA,
                                             'AS-606-1315',
                                             :V_DOT_ACTUAL_LTS,
                                             :V_DOT_ACTUAL_CANAST,
                                             :I_PORCENTAJE,
                                             :V_LTS_NUEVOS,
                                             :V_CANAST_NUEVAS,
                                             :V_CANAST_AFECTADAS);

                END
END^

Pero me marca error al momento de ejecutarlo:
Código:
Variable type (position 6) in EXECUTE STATEMENT 'SELECT a.FECHA_DISTRIBUCION,
 ' INTO does not match returned column type.
At procedure 'MOVTOS_MASIVOS_DOTACIONES'.
__________________
Miguel Román

Afectuoso saludo desde tierras mexicanas....un aguachile?, con unas "cetaseas" bien "muertas"?, VENTE PUES !!

Última edición por mRoman fecha: 13-12-2015 a las 17:46:23.
Responder Con Cita
  #4  
Antiguo 14-12-2015
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: Dec 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.119
Poder: 30
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola mRoman.
Cita:
Empezado por mRoman Ver Mensaje
Hola amigos buenas noches.

Uso DELPHI6, FireBird 2.0

Estoy tratanto de pasar como parametro una cadena tipo VarChar de 300 en un store procedure. Este el SP estoy construyendo:
Código SQL [-]
...
              and a.LECHER IN (:I_LECHERIAS)
...

La pregunta es la siguiente: Puedo hacer esto dentro del WHERE para usar IN, de esta forma:
ej.
where CODIGO IN (:CODIGOS)

Donde CODIGOS, puediera tener la siguientes cadena: 1234,5678,19281 ???
...
Si interpreté bién tu problema, y estuvieras usando la versión Firebird 2.1, te sugeriría usar la función POSITION, la que podrías usar como en el ejemplo siguiente:
Código SQL [-]
SELECT *
FROM LA_TABLA
WHERE ... 
  AND (POSITION(EL_CAMPO IN :PARAMETRO) <> 0)
Pero lamentablemente en la versión 2.0 aún no está implementada.

De todos modos podes hacerte tu versión de la funcion como expongo en el mensaje #9 de este enlace: Buscar Valor dentro de una Cadena.

Y en ese caso podrías hacer:
Código SQL [-]
SELECT *
FROM LA_TABLA
WHERE ... 
  AND ((SELECT RESULT FROM POS(EL_CAMPO, :PARAMETRO)) <> 0)

Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #5  
Antiguo 16-12-2015
mRoman mRoman is offline
Miembro
 
Registrado: Nov 2003
Posts: 352
Poder: 15
mRoman Va por buen camino
Aplicare

Buenas noches.

Gracias ecfisa por contestar y por tu tiempo, haré una prueba con lo que me indicas y les comento como me fue

Saludos
__________________
Miguel Román

Afectuoso saludo desde tierras mexicanas....un aguachile?, con unas "cetaseas" bien "muertas"?, VENTE PUES !!
Responder Con Cita
  #6  
Antiguo 16-12-2015
Avatar de fjcg02
[fjcg02] fjcg02 is offline
Miembro Premium
 
Registrado: Dec 2003
Ubicación: Zamudio
Posts: 1.375
Poder: 16
fjcg02 Va camino a la fama
Hola,
en la procedure que pones, veo que puedes rener un error.

Intenta que la procedure te devuelva el texto de la select que ejecutas en el execute estatement. Luego la intentas ejecutar. Así podrás descubrir qué falla.

Por lo que observo, tienes
Código SQL [-]
and a.LECHER IN ('||I_LECHERIAS||')
tras sustituir por el valor quedaría
Código SQL [-]
and a.LECHER IN ('Lecheria01,lecheria02,Lecheria03')

Esto estaría mal. Lo correcto sería
Código SQL [-]
and a.LECHER IN ('Lecheria01','lecheria02','Lecheria03')

Al menos es lo que a mi me parece.

Un saludo
__________________
Cuando los grillos cantan, es que es de noche - viejo proverbio chino -
Responder Con Cita
  #7  
Antiguo 16-12-2015
mRoman mRoman is offline
Miembro
 
Registrado: Nov 2003
Posts: 352
Poder: 15
mRoman Va por buen camino
Gracias

Cita:
Empezado por fjcg02 Ver Mensaje
Hola,
en la procedure que pones, veo que puedes rener un error.

Intenta que la procedure te devuelva el texto de la select que ejecutas en el execute estatement. Luego la intentas ejecutar. Así podrás descubrir qué falla.

Por lo que observo, tienes
Código SQL [-]
and a.LECHER IN ('||I_LECHERIAS||')
tras sustituir por el valor quedaría
Código SQL [-]
and a.LECHER IN ('Lecheria01,lecheria02,Lecheria03')

Esto estaría mal. Lo correcto sería
Código SQL [-]
and a.LECHER IN ('Lecheria01','lecheria02','Lecheria03')

Al menos es lo que a mi me parece.

Un saludo
Gracias fjcg02 por contestar. Fijate que no he probado eso....efectivamente estoy pasando sin comillas simples el parámetro al store procedure, veré si esto esta afectando. En otra prueba que hice, realice esto:

Código SQL [-]
and a.LECHER IN (||I_LECHERIAS||)

Pero también marco error....bueno algo, pero sigo probando. Ahora haré una prueba con lo q me comentas.

Nuevamente les agradezco su interes en ayudarme. Saludos.
__________________
Miguel Román

Afectuoso saludo desde tierras mexicanas....un aguachile?, con unas "cetaseas" bien "muertas"?, VENTE PUES !!
Responder Con Cita
  #8  
Antiguo 16-12-2015
Avatar de fjcg02
[fjcg02] fjcg02 is offline
Miembro Premium
 
Registrado: Dec 2003
Ubicación: Zamudio
Posts: 1.375
Poder: 16
fjcg02 Va camino a la fama
Hola,

hacer
Código SQL [-]
and a.LECHER IN (||I_LECHERIAS||)

valdría si pones las comillas o en el parámetro o en la construcción de la cadena. La sustitución del parámetro generaría la cadena
Código SQL [-]
and a.LECHER IN (Lecheria01)
Estoy suponiendo que tu parámetro contiene "Lecheria01".

cuando debería ser
Código SQL [-]
and a.LECHER IN ('Lecheria01')

Por eso te digo que hagas que la función devuelva la select. Luego la recoges y la ejecutas en donde ejecutes las querys a pelo ( el ibexpprt o similar). Si funcionan, es que se generan correctamente.

Saludos
__________________
Cuando los grillos cantan, es que es de noche - viejo proverbio chino -
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
ADO con parámetros jonmendi Conexión con bases de datos 15 06-11-2011 16:18:26
UDF y parámetros ARPE Firebird e Interbase 1 07-10-2010 05:44:07
Parametros Opcionales no Parametros por defecto Velia Varios 7 19-08-2006 15:18:42
Parámetros en ADO Delfin Conexión con bases de datos 0 19-03-2005 00:02:36
Parametros BDE Red_Delphi Conexión con bases de datos 0 13-10-2003 10:18:05


La franja horaria es GMT +2. Ahora son las 16:51:12.


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