Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

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

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 01-10-2015
Avatar de geolife
[geolife] geolife is offline
Miembro Premium
 
Registrado: nov 2006
Ubicación: Barcelona
Posts: 87
Poder: 18
geolife Va por buen camino
¿Como comparar 2 record?

Estimados amig@s,

Tengo una base de datos de clientes basada en un TStringList asociada a un TCliente en forma de record y necesito comparar 2 registros. Como son muchos campos, me pregunto si existe alguna forma de comparar 2 bloques de memoria de una sola vez o usando algún automatismo, sin necesidad de preguntar campo a campo, lo que resulta muy engorroso.

Ejemplo:
Contamos con un registro tipo cliente...
Código Delphi [-]
// El caso real cuenta con más de 60 campos
TCliente = Record
  Campo1: String; 
  Campo2: Double;
  Campo3: TdateTime;
end;

Function Es_Igual (A,B: TCliente): Boolean;
begin
  A.Campo1 := 'Juan';
  A.Campo2 := 1000;
  B.Campo1 := 'Sebas';
  B.Campo2 := 1000;

  // No podemos hacer lo siguiente; Result :=  A = B;
  // He probado esta alternativa pero siempre obtengo el mismo resultado, son iguales;
  Result := CompareMem(@A, @B, SizeOf(TCliente));
end;
En fin, algo debo hacer mal!!

Saludos!

Silvestre

Última edición por Casimiro Notevi fecha: 01-10-2015 a las 19:49:54.
Responder Con Cita
  #2  
Antiguo 01-10-2015
Avatar de mamcx
mamcx mamcx is offline
Moderador
 
Registrado: sep 2004
Ubicación: Medellín - Colombia
Posts: 3.911
Poder: 25
mamcx Tiene un aura espectacularmamcx Tiene un aura espectacularmamcx Tiene un aura espectacular
Lo de comparar los punteros de memoria tiene sentido si quieres saber si los punteros son o no iguales.

Pero como quieres saber si los "valores" son o no iguales, entonces solo queda comparar valores. Eso significa, que si, tienes que comparar campo a campo hasta que encuentres uno diferente (o si necesitas saber cuales, acumular los campos dispares en una lista). Eso no tiene otro camino.

Si solo te interesa saber si son diferentes pero no porque, puedes acelerar el proceso guardando en un campo extra un hash de la suma de todos los campos cada vez de hacer insert/delete, y solo comparas los hash después.
__________________
El malabarista.
Responder Con Cita
  #3  
Antiguo 01-10-2015
Avatar de geolife
[geolife] geolife is offline
Miembro Premium
 
Registrado: nov 2006
Ubicación: Barcelona
Posts: 87
Poder: 18
geolife Va por buen camino
Gracias Mammx!,

Si, en este caso solo es necesario saber que son diferentes, pero no donde están las diferencias.

Para crear un campo que contiene el hash de la totalidad de los campos que deseamos comparar, supongo que hay que implementarlo también uno a uno, ¿Se podría recorrer los campos de un record? como hacemos con los objetos de un componente en el ejemplo de abajo...
Código Delphi [-]
Procedure Recorrer_Controles;
var
  i:integer;
  Hash: String;
begin
  for I:= 0 to PageControl.ControlCount - 1 do
    if (PageControl.Controls[i] is TEdit) then Hash := Hash + ' | '+  (PageControl.Controls[i] as Tedit).Text;
end;
Cita:
Empezado por mamcx Ver Mensaje
Lo de comparar los punteros de memoria tiene sentido si quieres saber si los punteros son o no iguales.

Pero como quieres saber si los "valores" son o no iguales, entonces solo queda comparar valores. Eso significa, que si, tienes que comparar campo a campo hasta que encuentres uno diferente (o si necesitas saber cuales, acumular los campos dispares en una lista). Eso no tiene otro camino.

Si solo te interesa saber si son diferentes pero no porque, puedes acelerar el proceso guardando en un campo extra un hash de la suma de todos los campos cada vez de hacer insert/delete, y solo comparas los hash después.

Última edición por Casimiro Notevi fecha: 01-10-2015 a las 19:50:12.
Responder Con Cita
  #4  
Antiguo 01-10-2015
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
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 geolife.

Si estas usando Delphi 2010 o superior, revisa este enlace: List the Record's element\fields

Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #5  
Antiguo 01-10-2015
Avatar de geolife
[geolife] geolife is offline
Miembro Premium
 
Registrado: nov 2006
Ubicación: Barcelona
Posts: 87
Poder: 18
geolife Va por buen camino
Hola ecfisa,

Si! Hace poco tiempo compre una licencia de Delphi XE7 y no estaba al corriente de esta mejora en la rtti. Esto aumenta en gran medida la capacidad de trabajar con registros de elementos.

Muchas gracias como siempre por vuestra ayuda. ecfisa, mamcx, casimiro!!

Cita:
Empezado por ecfisa Ver Mensaje
Hola geolife.
Si estas usando Delphi 2010 o superior, revisa este enlace: List the Record's element\fields

Saludos
Responder Con Cita
  #6  
Antiguo 01-10-2015
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
Además de la interesante aportación de Rodrigo Ruz indicada puntualmente por ecfisa, considera algún mecanismo de serialización que facilite el proceso de comparar. Serializar se puede entender de forma simple como convertir cualquier grupo de información estructurada en una tira plana de bytes sin punteros (los campos String son punteros a otra región de memoria). Como tal, esa tira de bytes será perfectamente comparable mediante la función CompareMem. Sólo considera que esto puede ser más lento que comparar campo por campo o que usar códigos Hash.

Como sea, y viendo que tienes una versión moderna de Delphi, tiene mucho valor estudiar temas de RTTI y clases novedosas como TBinaryWriter.

Un saludo.

Última edición por Al González fecha: 01-10-2015 a las 22:09:20.
Responder Con Cita
  #7  
Antiguo 01-10-2015
Avatar de geolife
[geolife] geolife is offline
Miembro Premium
 
Registrado: nov 2006
Ubicación: Barcelona
Posts: 87
Poder: 18
geolife Va por buen camino
Hola Al,

Entiendo según tu explicación que para poder usar la función CompareMen usando serialización lo que tengo que hacer es fabricar una estructura con longitud fija, es decir, si uso algún String del que puedo conocer su rango de uso, podría codificar algo como:

Código Delphi [-]
TCliente = Record
  Campo1: String[30]; 
  Campo2: Double;
  Campo3: TdateTime;
end;

Gracias!


Cita:
Empezado por Al González Ver Mensaje
Además de la interesante aportación de Rodrigo Ruz indicada puntualmente por ecfisa, considera algún mecanismo de serialización que facilite el proceso de comparar. Serializar se puede entender de forma simple como convertir cualquier grupo de información en una tira plana de bytes sin punteros (los campos String son punteros a otra región de memoria). Como tal, esa tira de bytes será perfectamente comparable mediante la función CompareMem. Sólo considera que esto puede ser más lento que comparar campo por campo o que usar códigos Hash.

Como sea, y viendo que tienes una versión moderna de Delphi, tiene mucho valor estudiar temas de RTTI y clases novedosas como TBinaryWriter.

Un saludo.
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 utilizar setoff record as con delphi !!! pame PostgreSQL 3 28-07-2013 01:48:55
¿Como enviar un Record mediante un Socket? jednavlop Internet 5 27-05-2012 09:18:54
Como Comparar Imagenes Jusar C++ Builder 7 15-03-2012 12:50:01
como puedo usar record en delphi antonio302050 Varios 7 08-02-2010 22:17:29
Comparar dos RECORD oworty Varios 3 23-11-2004 15:18:33


La franja horaria es GMT +2. Ahora son las 13:07:50.


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