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 07-04-2009
Avatar de Carmelo Cash
Carmelo Cash Carmelo Cash is offline
Miembro
 
Registrado: jul 2003
Ubicación: Buenos Aires
Posts: 261
Poder: 21
Carmelo Cash Va por buen camino
Smile Compara Valores de Objetos de la misma clase

Hola Foro:
Necesito comparar los valores que tengo en dos objetos de la misma clase.
Cuando traigo los datos de un cliente los guardo en dos objetos, Cliente y ClienteViejo, entonces me queda.

Cliente.Nombre:='pepe'
Cliente.Direccion:='cucha cucha 444'

ClienteViejo.Nombre:='pepe'
ClienteViejo.Direccion:='cucha cucha 444'

lo que necesito hacer al cerrar el formulario es algo como esto

if Cliente.ValoresdeTodosLosCampos<>ClienteViejo.ValoresdeTodosLosCampos then grabar;

De esta manera mando a grabar solamente si hubo una modificación en.

Eso es todo, desde ya gracias por su atención.
Responder Con Cita
  #2  
Antiguo 07-04-2009
Avatar de delphi.com.ar
delphi.com.ar delphi.com.ar is offline
Federico Firenze
 
Registrado: may 2003
Ubicación: Buenos Aires, Argentina *
Posts: 5.932
Poder: 27
delphi.com.ar Va por buen camino
Como opción rápida, se me ocurre que todos los campos de la clase lo tengas almacenados en un record, crear un método que sea "Compare", e internamete utilizar la función CompareMem para comparar los valores de los records.

Saludos!
__________________
delphi.com.ar

Dedique el tiempo suficiente para formular su pregunta si pretende que alguien dedique su tiempo en contestarla.
Responder Con Cita
  #3  
Antiguo 07-04-2009
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.278
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Lo que yo he hecho en algun caso similar a este es crear un método en la clase (en este caso cliente) que devuelve el objeto como string.

Código Delphi [-]
  Self.FAsString := Self.FCodigo + '|' + Self.FDireccion + '|' + ...

Utilizando un separador.
En mi caso me sirve para temas de Debug, de exportación y para cuestiones como estas. En ese caso vadría con hacer algo similar a esto.

Código Delphi [-]
  if (Cliente.AsString <> ClienteViejo.AsString) then begin 
    ...

No es nada muy sofisticado, pero a mi me funciona.

NOTA: En mi caso lo tengo a nivel de una clase Base que recorre todos los campos y hace la operación de concatenación, de forma que no se implementa en cada una de las clases, pero la idea es la misma.

Un saludo.
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #4  
Antiguo 07-04-2009
Avatar de Crandel
[Crandel] Crandel is offline
Miembro Premium
 
Registrado: may 2003
Ubicación: Parana, Argentina
Posts: 1.475
Poder: 23
Crandel Va por buen camino
Desde la version Delphi 2006 se ha incluido la sobrecarga de operadores. Lo que te permite definir la operación de igualación entre dos registros y verificar si son iguales.

Supongamos que tienes el registro TCliente
Código Delphi [-]
TCliente = record
  Nombre: string;
  Direccion: string;
end;

entonces sobrecargas el operados Equal para poder hacer comparaciones entre dos registros

Código Delphi [-]
TCliente = record
  Nombre: string;
  Direccion: string;

  class operator Equal( c1, c2 : TCliente): bool;
end;

y lo implementas asi:
Código Delphi [-]
class operator TCliente.Equal( c1, c2 : TCliente): bool;
begin  
   Result := (c1.Nombre = c2.Nombre)  and (c1.Direccion = c2.Direccion);
end;

* El codigo no lo he verificado en delphi asi que puede tener errores, pero es la idea.
__________________
[Crandel]
Responder Con Cita
  #5  
Antiguo 07-04-2009
Avatar de Carmelo Cash
Carmelo Cash Carmelo Cash is offline
Miembro
 
Registrado: jul 2003
Ubicación: Buenos Aires
Posts: 261
Poder: 21
Carmelo Cash Va por buen camino
Listo

Quedó así, una función dentro del objeto que devuelve verdadero o false comparando todos los campos.

Código Delphi [-]
function tClientes.Equals(recDatos: tClientes): boolean;
begin
  result:=
  (self.Nombre = recDatos.Nombre) and
  (self.Direccion = recDatos.Direccion) ;
end;


-- Boton grabar --

Código Delphi [-]
if not ClienteActual.Equals(clienteViejo) then grabar;

Gracias a todos los que participaron.
Responder Con Cita
  #6  
Antiguo 07-04-2009
Avatar de JoseAntonio
JoseAntonio JoseAntonio is offline
Miembro
 
Registrado: abr 2006
Ubicación: Lima - Ciudad de los Reyes.
Posts: 87
Poder: 19
JoseAntonio Va por buen camino
En este caso si seria interesante usar las RTTI de delphi, aunque no soy un experto en el tema
__________________
nuestro carácter está reflejado en cada línea de código que escribimos.
Responder Con Cita
  #7  
Antiguo 07-04-2009
Avatar de delphi.com.ar
delphi.com.ar delphi.com.ar is offline
Federico Firenze
 
Registrado: may 2003
Ubicación: Buenos Aires, Argentina *
Posts: 5.932
Poder: 27
delphi.com.ar Va por buen camino
Cita:
Empezado por JoseAntonio Ver Mensaje
En este caso si seria interesante usar las RTTI de delphi, aunque no soy un experto en el tema
El tema es decidir que propiedades evaluar y cuales no. Por otro lado puede ser mas práctico si lo implementamos muchas veces, pero poco perfrormante.

Saludos!
__________________
delphi.com.ar

Dedique el tiempo suficiente para formular su pregunta si pretende que alguien dedique su tiempo en contestarla.
Responder Con Cita
  #8  
Antiguo 07-04-2009
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Si estamos trabajado con objetos, ¿por qué no hacer algo así?

Código Delphi [-]
type
  TMiObjeto = class
  private

    FPropiedad: TTipoDeDatos;
    procedure SetPropiedad(Valor: TTipoDeDatos);

  public
    Modificado: Boolean;
    property Propiedad: TTipoDeDatos write SetPropiedad;
  end;

implementation

procedure TMibjeto.SetPropiedad(Valor: TTipoDeDatos);
begin
  FPropiedad := Valor;
  Modificado := true;
end;

Claro que hay que poner un método de acceso para cada propiedad (cosa que es bastante común) pero al final, la comprobación es tan sencilla como

Código Delphi [-]
if MiObjeto.Modificado then
  Grabar;

sin tener que comparar campo por campo.

--------------------------------------------------------------------------------------

Cita:
Empezado por delphi.com.ar
que todos los campos de la clase lo tengas almacenados en un record, crear un método que sea "Compare", e internamete utilizar la función CompareMem para comparar los valores de los records.
Pero, ¿esto serviría si tenemos valores string? Es decir, creo que todos los valores que nos interesen para la comparación tendrían queser de longitud fija ¿no?

// Saludos
Responder Con Cita
  #9  
Antiguo 07-04-2009
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.278
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Cita:
Empezado por roman Ver Mensaje
Si estamos trabajado con objetos, ¿por qué no hacer algo así
El problema que le veo a esto Román, es que sólo podemos comparar u objeto consigo mismo (por decirlo así), pero no nos serviría para comparar dos objetos distintos físicamente.

En el caso de Cliente y ClienteViejo, son dos objetos de la clase cliente distintos.
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #10  
Antiguo 07-04-2009
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Tienes razón Neftalí; es que me parece que en el fondo no me cuadra lo de usar dos objetos para lo mismo y subconcientemente lo omití Pero claro que bajo esas condiciones no aplica lo que digo.

// Saludos
Responder Con Cita
  #11  
Antiguo 07-04-2009
Avatar de delphi.com.ar
delphi.com.ar delphi.com.ar is offline
Federico Firenze
 
Registrado: may 2003
Ubicación: Buenos Aires, Argentina *
Posts: 5.932
Poder: 27
delphi.com.ar Va por buen camino
Cita:
Empezado por roman Ver Mensaje
Pero, ¿esto serviría si tenemos valores string? Es decir, creo que todos los valores que nos interesen para la comparación tendrían queser de longitud fija ¿no?
Así es, creí haberlo aclarado .

Te dejo algo para marearse un ratito, cositas que hace el compilador:
Código Delphi [-]
type
  TData = record
    Field1: string;
    Field2: string
  end;
var
  D1, D2: TData;
begin
  D1.Field1 := 'Hola Mundo!';
  D1.Field2 := '123'; {Probar cambiando los valores, o tomandolos de un edit}

  D2.Field1 := 'Hola Mundo!';
  D2.Field2 := '123';

  Caption := IfThen(CompareMem(@D1, @D2, SizeOf(TData)), '=', '<>');
__________________
delphi.com.ar

Dedique el tiempo suficiente para formular su pregunta si pretende que alguien dedique su tiempo en contestarla.
Responder Con Cita
  #12  
Antiguo 07-04-2009
Avatar de Crandel
[Crandel] Crandel is offline
Miembro Premium
 
Registrado: may 2003
Ubicación: Parana, Argentina
Posts: 1.475
Poder: 23
Crandel Va por buen camino
Cita:
Empezado por Carmelo Cash Ver Mensaje
-- Boton grabar --

Código Delphi [-]
if not ClienteActual.Equals(clienteViejo) then grabar;
Una sentencia equivalente a la que acabas de escribir pero usando el operador mismo seria asi:

Código Delphi [-]
if not (ClienteActual = clienteViejo) then grabar;

de esta misma forma puedes definir el operador <> y todos los restantes.
__________________
[Crandel]
Responder Con Cita
  #13  
Antiguo 07-04-2009
Avatar de Crandel
[Crandel] Crandel is offline
Miembro Premium
 
Registrado: may 2003
Ubicación: Parana, Argentina
Posts: 1.475
Poder: 23
Crandel Va por buen camino
y en el caso de registros mas complejos con varios atributos se puede aprovechar la excelente funcion CompareMem (gracias fede ya no me la acordaba)

entonces la definicion del operados Equal te queria asi:

Código Delphi [-]
class operator TCliente.Equal( c1, c2 : TCliente): bool;
begin  
   Result := CompareMem(@c1, @c2, SizeOf(TCliente));
end;

y para el caso del operador <>

Código Delphi [-]
class operator TCliente.NotEqual( c1, c2 : TCliente): bool;
begin  
   Result := not (c1 = c2);
end;

nunca entendi porque este no es el efecto por defecto

y ahora si tienes exactamente la sentecia que querias arriba:

Código Delphi [-]
if ClienteActual <> clienteViejo then grabar;
__________________
[Crandel]

Última edición por Crandel fecha: 07-04-2009 a las 23:09:00.
Responder Con Cita
  #14  
Antiguo 07-04-2009
Avatar de delphi.com.ar
delphi.com.ar delphi.com.ar is offline
Federico Firenze
 
Registrado: may 2003
Ubicación: Buenos Aires, Argentina *
Posts: 5.932
Poder: 27
delphi.com.ar Va por buen camino
Cita:
Empezado por Crandel Ver Mensaje
entonces la definicion del operados Equal te queria asi:
Solo si el record tiene valores de longitud fija, si tiene pascal strings, null terminated string NO, pero si en su lugar lo cambias por un array de chars estático, si!

Fíjate que pasa en el ejemplo que pasé si los valores no son cargados desde constantes, haciendo algo como esto:
Código Delphi [-]
  D1.Field2 := Edit1.Text;
  D2.Field2 := Edit2.Text;
__________________
delphi.com.ar

Dedique el tiempo suficiente para formular su pregunta si pretende que alguien dedique su tiempo en contestarla.
Responder Con Cita
  #15  
Antiguo 07-04-2009
Avatar de Crandel
[Crandel] Crandel is offline
Miembro Premium
 
Registrado: may 2003
Ubicación: Parana, Argentina
Posts: 1.475
Poder: 23
Crandel Va por buen camino
Cita:
Empezado por delphi.com.ar Ver Mensaje
Solo si el record tiene valores de longitud fija, si tiene pascal strings, null terminated string NO, pero si en su lugar lo cambias por un array de chars estático, si!
POr eso digo no usar el CompareMem en este caso Eso me pasa por no seguir el hilo de la discución
__________________
[Crandel]
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
Como instanciar objetos de los cuales solo se conoce su clase ancestro AzidRain OOP 7 11-07-2008 02:58:17
ayuda handle de multiples ventanas de la misma clase octalh Varios 7 23-04-2008 07:44:16
Recorrer todos los objetos creados de una clase propia mierda OOP 1 25-10-2007 19:52:10
Crear una clase y asignar objetos como propiedades leanfreue OOP 4 13-04-2007 00:08:33
Obtener la clase de objetos Feñiz OOP 7 08-05-2003 20:21:55


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


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