Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > OOP
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 25-11-2010
Avatar de GerTorresM
GerTorresM GerTorresM is offline
Miembro
 
Registrado: nov 2005
Ubicación: Tunja - Boyacá
Posts: 210
Poder: 19
GerTorresM Va por buen camino
Crear campos calculados en consulta

Hola a Tod@s:


Bien la situación del día de hoy es la siguiente:

Estoy trabajando con delphi 6 y como base de datos M$ Acce$$, quiero adicionar una serie de campo calculados en una consulta, ésto son de diversos tipos, la pregunta es como la puedo hacer.

agradezco de antemano el tiempo dedicado y la colaboración que me puedan prestar.


gertorresm
Colombia

Última edición por GerTorresM fecha: 25-11-2010 a las 17:08:31. Razón: Falta de información
Responder Con Cita
  #2  
Antiguo 25-11-2010
cloayza cloayza is offline
Miembro
 
Registrado: may 2003
Ubicación: San Pedro de la Paz, Chile
Posts: 913
Poder: 22
cloayza Tiene un aura espectacularcloayza Tiene un aura espectacular
Si los calculos no son demasiado complejos los puedes especificar en la misma consulta.

Por ejemplo:

Código SQL [-]
SELECT Precio, Iva,  (Precio*Iva) as Impuestos, (Precio+0.05) as Descuento
FROM TABLA

Espero te sirva, de lo contrario da un ejemplo de los calculos que requieres.

Saludos
Responder Con Cita
  #3  
Antiguo 25-11-2010
Avatar de GerTorresM
GerTorresM GerTorresM is offline
Miembro
 
Registrado: nov 2005
Ubicación: Tunja - Boyacá
Posts: 210
Poder: 19
GerTorresM Va por buen camino
Question Crear Campo Calculado

Gracias cloayza por tu tiempo la idea que tengo es la siguiente

Código Delphi [-]
function CrearCampoCalculado (pNombreCampo, pTipoCampo : String;  pDataset : TDataset) : TField;
var Campo_local : TField;
begin
  //Crea los campos Campos
  Campo_local := TFloatField.Create(pDataSet);
  Campo.FieldName:= pNombreCampo;
  Campo.FieldKind:= fkCalculated;
  Campo.DataSet:= pDataset;
  Result:= Campo_local;
end;

pero poder a su vez indicar en la función el tipo de dato que ha de manejar el campo ej.

TStringField,TSmallIntField, TIntegerField,
TBooleanField, TFloatField, TCurrencyField,
TDateField, TTimeField,TDateTimeField,
TVarBytesField, TBlobField, TMemoField,
TWordField, TBCDField,TBytesField
TGraphicsField, TAutoIncField,TNumericField

pero no que tipo de dato colocar en los párametros de entrada, lo que denomina pTipoCampo, es decir pTipoCampo que tipo de dato debe pedir, ya que a partir de dicho parámetro de entrada debo platear el constructor tal como lo vez de la línea de código

Código Delphi [-]
 TFloatField.Create(pDataSet);

muchas gracias de antemano



gertorresm
Colombia

Última edición por GerTorresM fecha: 25-11-2010 a las 22:54:13. Razón: Falta de Información
Responder Con Cita
  #4  
Antiguo 26-11-2010
Avatar de defcon1_es
defcon1_es defcon1_es is offline
Miembro
 
Registrado: mar 2004
Ubicación: Cuenca - España
Posts: 533
Poder: 21
defcon1_es Va por buen camino
Hola. ¿Te refieres a algo parecido a esto?

Código Delphi [-]
function CrearCampoCalculado (pNombreCampo: String;  pDataset : TDataset; pTipoCampo: Integer) : TField;
var Campo_local : TField;
begin
  //Crea los campos Campos
  case pTipoCampo of
    0: Campo_local := TFloatField.Create(pDataSet);
    1: Campo_local := TIntegerField.Create(pDataSet);
  //.... aqui pones el resto de tipos
  end;
  Campo.FieldName:= pNombreCampo;
  Campo.FieldKind:= fkCalculated;
  Campo.DataSet:= pDataset;
  Result:= Campo_local;
end;
__________________
Progress Openedge
https://abevoelker.com/progress_open...dered_harmful/


Delphi forever...
Responder Con Cita
  #5  
Antiguo 26-11-2010
Avatar de Estifmauin
Estifmauin Estifmauin is offline
Miembro
 
Registrado: may 2008
Ubicación: Alicante
Posts: 24
Poder: 0
Estifmauin Va por buen camino
Esta solución es buena, pero tiene una carencia: no tiene en cuenta que ya pueden existir campos en el dataset.
En mi caso, suelo añadir campos calculados a datasets "reales" que ya contiene campos persistentes. Un ejemplo es construir un mensaje de estado a partir de los valores de ciertos campos, y así mostrar en un grid directamente ese mensaje.
En ese caso, hay que respetar los campos existentes y luego añadirle los nuevos calculados:

Código Delphi [-]
procedure CrearCampoCalculado(DataSet :TDataSet; nombrecampo :string; tipo :TFieldType; longi :integer);
var
    f: TField;
    i: Integer;
begin
try
    //es necesario que antes estén definidos todos los campos persistentes
    DataSet.FieldDefs.Update;
    for i:=0 to DataSet.FieldDefs.Count - 1 do
        if DataSet.FindField(DataSet.FieldDefs[i].Name) = nil then
            DataSet.FieldDefs.Items[i].CreateField(DataSet);
    //ahora ya podemos comprobar el nuevo campo
    //antes comprobamos la existencia de otro campo con el mismo nombre
    if DataSet.FindField(nombrecampo) = nil then begin
        case tipo of
            ftString: f:=TStringField.Create(DataSet);
            ftInteger: f:=TIntegerField.Create(DataSet);
            ftBoolean: f:=TBooleanField.Create(DataSet);
            //contempla aqui todos los tipos que necesites
            //lógicamente, dependerán de la bbdd que uses
            else ShowMessage('Tipo de campo no contemplado: '+GetEnumName(TypeInfo(TFieldType),integer(tipo)));
        end;
        if f <> nil then begin
            f.DataSet:=DataSet;
            f.Name:=DataSet.Name+nombrecampo;
            f.FieldName:=nombrecampo;
            f.DisplayLabel:=nombrecampo;
            if tipo = ftString then
                f.Size:=longi;
            f.Calculated:=true;
        end;
    end
    else ShowMessage('Ya existe un campo de nombre "'+nombrecampo+'"');
except on e:exception do
    ShowMessage(e.Message);
end;
end;

Nota: la función GetEnumName requiere uses TypInfo;

Y llamo a esa función en el evento BeforeOpen:

Código Delphi [-]
procedure tDatasetBeforeOpen(DataSet: TDataSet);
begin
CrearCampoCalculado(DataSet, 'temporal_entero', ftInteger,0);
CrearCampoCalculado(DataSet, 'temporal_texto', ftString,20);
end;

Espero que ayude.
Responder Con Cita
  #6  
Antiguo 26-11-2010
Avatar de roboflekto
roboflekto roboflekto is offline
Registrado
 
Registrado: sep 2010
Posts: 1
Poder: 0
roboflekto Va por buen camino
Es suena interesante, voy a probarlo ahora mismo. Pero por qué dices es de:
//lógicamente, dependerán de la bbdd que uses
???
¿No se trata de campos calculados, es decir que no están en la base de datos?
y otra cosa: ¿por qué en el evento BeforeOpen? ¿No se puede usar en el AfterOpen?

Saludos a todos.
Responder Con Cita
  #7  
Antiguo 26-11-2010
Avatar de Estifmauin
Estifmauin Estifmauin is offline
Miembro
 
Registrado: may 2008
Ubicación: Alicante
Posts: 24
Poder: 0
Estifmauin Va por buen camino
Cita:
Empezado por roboflekto Ver Mensaje
Es suena interesante, voy a probarlo ahora mismo. Pero por qué dices es de:
//lógicamente, dependerán de la bbdd que uses
???
¿No se trata de campos calculados, es decir que no están en la base de datos?
y otra cosa: ¿por qué en el evento BeforeOpen? ¿No se puede usar en el AfterOpen?

Saludos a todos.
Bueno... lo de que depende de la bbdd que uses es un comentario que se me ha traspapelado: ignóralo. Es evidente que tienes razón.

Respecto a lo de llamar a la función en el evento AfterOpen, es cierto que parece lo más obvio, pero cuando hice mis pruebas daba problemas, así que cogí la mecánica de hacerlo en Before.
Te animo a que lo pruebes, y si se puede hacer, lo compartas con nosotros.
Responder Con Cita
  #8  
Antiguo 29-11-2010
Avatar de GerTorresM
GerTorresM GerTorresM is offline
Miembro
 
Registrado: nov 2005
Ubicación: Tunja - Boyacá
Posts: 210
Poder: 19
GerTorresM Va por buen camino
Tema Cerrado

Muchas gracias a tod@s:


Con sus aportes ya arme la función que se requeria


Agradezco de antemano su tiempo y aporte



gertorresm
colombia
Responder Con Cita
  #9  
Antiguo 01-03-2011
rchavezh rchavezh is offline
Miembro
 
Registrado: sep 2005
Ubicación: Guadalajara, Jalisco, México
Posts: 23
Poder: 0
rchavezh Va por buen camino
Al parecer el orden de asignacion en delphi 2010 afecta por lo que actualizo la funcion

Código Delphi [-]
CrearCampoCalculado(DataSet :TDataSet; nombrecampo :string; tipo :TFieldType; longi :integer);
var
    f: TField;
    i: Integer;
begin
try
    //es necesario que antes estén definidos todos los campos persistentes
    DataSet.FieldDefs.Update;
    for i:=0 to DataSet.FieldDefs.Count - 1 do
        if DataSet.FindField(DataSet.FieldDefs[i].Name) = nil then
            DataSet.FieldDefs.Items[i].CreateField(DataSet);
    //ahora ya podemos comprobar el nuevo campo
    //antes comprobamos la existencia de otro campo con el mismo nombre
    if DataSet.FindField(nombrecampo) = nil then begin
        case tipo of
            ftString: f:=TStringField.Create(DataSet);
            ftInteger: f:=TIntegerField.Create(DataSet);
            ftFloat: f:=TFloatField.Create(DataSet);
            ftBoolean: f:=TBooleanField.Create(DataSet);
            //contempla aqui todos los tipos que necesites
            //lógicamente, dependerán de la bbdd que uses
            else GeneraLog('Tipo de campo no contemplado: ');
        end;
        if f <> nil then begin
            f.Name:=DataSet.Name+nombrecampo;
            f.FieldName:=nombrecampo;
            f.DisplayLabel:=nombrecampo;
            if tipo = ftString then
                f.Size:=longi;
            f.Calculated:=true;
            f.FieldKind := fkCalculated;
            f.DataSet:=DataSet;
        end;
    end;
except on e:exception do
    GeneraLog(e.Message);
end;

Última edición por rgstuamigo fecha: 01-03-2011 a las 22:11:26. Razón: Estética en el código Delphi
Responder Con Cita
  #10  
Antiguo 01-03-2011
Avatar de rgstuamigo
rgstuamigo rgstuamigo is offline
Miembro
 
Registrado: jul 2008
Ubicación: Santa Cruz de la Sierra-Bolivia
Posts: 1.646
Poder: 17
rgstuamigo Va por buen camino
Thumbs up

Agradecemos tu colaboracion y tu actualizacion...
Nada más solicitarte que para que el código se vea bonito, la próxima ves utilices las etiquetas de código disponibles para una mejor estética., sin olvidar tambien que le dés una buena leida a nuestra Guía de Estilo si no lo has hecho aún...
Saludos.. y muchas gracias por tu colaboracion....
__________________
"Pedid, y se os dará; buscad, y hallaréis; llamad, y se os abrirá." Mt.7:7
Responder Con Cita
  #11  
Antiguo 01-03-2011
Avatar de Al González
[Al González] Al González is offline
In .pas since 1991
 
Registrado: may 2003
Posts: 5.604
Poder: 29
Al González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en bruto
Hola.

Me gustaría agregar que podemos prescindir del Case empleando la variable global DefaultFieldClasses:
Código Delphi [-]
// Tipo es una constante ftXXX
If DefaultFieldClasses [Tipo] <> Nil Then
  NuevoCampo := DefaultFieldClasses [Tipo].Create (DataSet)
Else
  // error

Respondiendo a roboflekto:
Cita:
Empezado por roboflekto Ver Mensaje
//lógicamente, dependerán de la bbdd que uses
???
¿No se trata de campos calculados, es decir que no están en la base de datos?
y otra cosa: ¿por qué en el evento BeforeOpen? ¿No se puede usar en el AfterOpen?
Más bien dependerá de los tipos de campos que soporte el componente conjunto de datos en cuestión.

Es más adecuado BeforeOpen que AfterOpen, para que al abrirse el conjunto de datos éste destine espacio en los buffers de registros para los nuevos campos calculados. De hecho hay una validación en la clase TField que impide agregar un nuevo campo a un conjunto de datos abierto.*

Saludos.

Al González.

*Off topic:
Tal validación puede ser burlada para crear campos calculados que no consuman memoria en los registros. Comento esto porque a alguien puede resultarle interesante como para abrir otro tema al respecto.
Responder Con Cita
Respuesta



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
Crear Campos Calculados en una Dataset GerTorresM OOP 3 28-06-2010 15:41:13
Consulta sobre campos calculados oscarac SQL 0 15-04-2009 18:23:21
como hacer consulta para crear dos campos a partir de uno Rom@n SQL 2 24-12-2008 17:56:37
Consulta sql sobre campos calculados Carlos A Ortega SQL 2 24-07-2003 15:50:33
Consulta campos calculados MiltonE Conexión con bases de datos 1 05-05-2003 18:47:09


La franja horaria es GMT +2. Ahora son las 16:35:00.


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