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 13-09-2012
Critter Critter is offline
Miembro
 
Registrado: may 2003
Posts: 60
Poder: 21
Critter Va por buen camino
Post Mejor manera de convertir un record en string

dado el siguiente record

Código Delphi [-]
TPerson = record
   DNI: string[9];
   Nombre: string[40];
end;

var
  Person: TPerson;

Person.DNI    := '123456789';
Person.Nombre := 'Usuario Club Delphi';

para generar una cadena con el record hago ....

Código Delphi [-]
RecStr = Person.DNI + Person.Nombre;

¿ Existe alguna forma más generica de realizar dicha acción ?,

No se si me explico bien, pero lo que quiero es poder convertir un record dado en una cadena, sin que para lograrlo tenga que concatenar todos los campos.

Gracias.

Última edición por Casimiro Notevi fecha: 13-09-2012 a las 23:50:02.
Responder Con Cita
  #2  
Antiguo 13-09-2012
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.038
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Amigo, por favor, después de 50 mensajes y todavía no pones los tags al código
Recuerda poner los tags al código fuente, ejemplo:



Gracias
Responder Con Cita
  #3  
Antiguo 14-09-2012
[egostar] egostar is offline
Registrado
 
Registrado: feb 2006
Posts: 6.556
Poder: 25
egostar Va camino a la fama
Hola

Lo único que se me ocurre es usar una función dentro de tu record, para "juntar" los campos sí o sí debes de concatenar, pero bueno, no me creas mucho, por ahí vendrá alguno de los compañeros que si sabe y nos ilustrará con algo mas simple.


Código Delphi [-]
type
  TPerson = record
     DNI: string[9];
     Nombre: string[40];
     function Cadena: string;
  end;

var
  Person: TPerson;

{ TPerson }
function TPerson.Cadena: string;
begin
  result := DNI + Nombre;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Person.DNI    := '123456789';
  Person.Nombre := 'Usuario Club Delphi';

  showMessage( Person.cadena );
end;

Saludos
Responder Con Cita
  #4  
Antiguo 14-09-2012
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.038
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Creo que no hay muchas más posibilidades, salvo acceder a la memoria donde esté almacenado el contenido del record y leerlo, pero puede que el valor de ambas variables no estén contínuas en memoria, por lo que no sería seguro que siempre tuviese éxito.
Seguramente la solución de egostar sea la más "directa".
Responder Con Cita
  #5  
Antiguo 14-09-2012
Avatar de Delphius
[Delphius] Delphius is offline
Miembro Premium
 
Registrado: jul 2004
Ubicación: Salta, Argentina
Posts: 5.582
Poder: 25
Delphius Va camino a la fama
Si hay algo que no entiendo es porqué seguir intentando usar un record como si fuera una clase.
¿Y porqué no mejor abandonar ese pensamiento estructurado y avanzar hacia el maravilloso mundo que ofrece POO?
Y si esta duda surge porque se disponen de muchos campos y si quiere concatenar muchos de ellos, una posible manera de encarar el problema sería mediante TStringList.
En él se almacenan los datos de cada variable, y luego para concatenar basta con hacer algo como:

Código Delphi [-]
for i := 1 to Listado.Count - 1 do
result := result + Listado.Strins[i];

Aprovechando la propiedad .Values[] se puede hacer correspondencias entre atributos -> Valor. Por ejemplo:

Código Delphi [-]
Listado.Values['DNI'] := '123456789';

Siendo DNI el atributo en cuestión, y así con el resto de atributos imaginados.

Ojo, que lo digo de a memoria, no tengo Delphi abierto a mano.

Saludos,
__________________
Delphius
[Guia de estilo][Buscar]
Responder Con Cita
  #6  
Antiguo 14-09-2012
Critter Critter is offline
Miembro
 
Registrado: may 2003
Posts: 60
Poder: 21
Critter Va por buen camino
Talking

Amigo Casimiro, tienes razón un error imperdonable el mío, me aceptarias el decirte que fue un olvido ?

En cuanto a Delphius, tienes razón quizas con la POO es más fácil, pero el hecho es que se trata de la definicion de un archivo que debe ser guardado a texto, y cada registro puede ser distinto aunque todos tienen la misma longitud, por eso mi planteamiento era llenar los datos a traves del record y a la hora de guardar el archivo que fuese mediante

Código Delphi [-]
Writeln(strDelRecord);

olvidandome desde ese momento de la estructura interna del record.

Gracias a todos por vuestras respuestas.

En su momento hice la siguiente función para ese tipo de record, que desconozco si funcionará en todos los sistemas, pero lo que hacia era recorrer todo el record, averiguar la longitud del string y eliminar los carácteres extraños para un record del tipo como el mencionado arriba.


Código Delphi [-]
function RecordToString(const registro): string;
var
  StrTemp: string;  // Cadena temporal
  c: ^char;         // Puntero a char
  i: Integer;       // Contador.
  NumCars: LongInt; // Numero de carácteres
begin
  StrTemp := '';
  c := @registro;
  while (c^ <> #0) do   // Mientras no sea el final del registro.
  begin
    NumCars := Ord(c^); // Lee la longitud de la cadena
    i := 0;
    while (i < NumCars) do // Lee caracteres de la cadena.
    begin
      inc(c); // Incrementa el contador del caracter.
      StrTemp := StrTemp + c^; // Traspasa los datos a la cadena.
      inc(i); // Incrementa el contador de carácteres en el registro actual.
    end;
    inc(c); // Incrementa el contador de Caracter.
  end;
  Result := StrTemp; // Devuelve un string.
end;

¿ Podria tener algún problema usando esta funcion ?

Gracias.
Responder Con Cita
  #7  
Antiguo 14-09-2012
WkaymQ48 WkaymQ48 is offline
Miembro
NULL
 
Registrado: jul 2012
Posts: 43
Poder: 0
WkaymQ48 Va por buen camino
Si la longitud de los campos es fija, y podemos rellenar los huecos con espacios, prueba con esto:
Código Delphi [-]
type
  TPerson = packed record
     DNI: array[0..8] of AnsiChar;
     Nombre: array[0..39] of AnsiChar;
  end;


var
  Person: TPerson;
  Nombre: AnsiString;
  f1: TextFile;
  f2: file;
begin
  // Rellenamos de espacios en blanco todo el record
  FillChar(Person,SizeOf(TPerson),#32);
  // Metemos el DNI
  move(PAnsiChar('12345678Z')^,Person.DNI,9);
  // Metemos el Nombre  desde una variable, para ver asi los dos metodos
  Nombre:= 'Pepe Perez';
  move(PAnsiChar(Nombre)^,Person.Nombre,Length(Nombre));
  // En ambos casos hay que asegurarse de que el tamaño del texto no es mayo que el del array

  //Para guardarlo en un fichero todo junto, tenemos dos metodos
  AssignFile(f1,'E:\1.txt');
  Rewrite(f1);
  Writeln(f1,Copy(PAnsiChar(@Person),1,SizeOf(TPerson)));
  CloseFile(f1);

  AssignFile(f2,'E:\2.txt');
  Rewrite(f2,1);
  BlockWrite(f2,Person,Sizeof(Person));
  CloseFile(f2);
end.
Responder Con Cita
  #8  
Antiguo 14-09-2012
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 Critter.

Cita:
¿ Podria tener algún problema usando esta funcion ?
Solamente si tuviera dificultad en detectar el fin de los campos o del registro.

Pero por otro lado, la función RecordToString tendría el mismo resultado que la función Cadena que te sugirio egostar, siendo esta última mucho más simple y eficiente.

Si deseas que cada cadena conserve una longitud fija podes hacer :
Código Delphi [-]
...
{A-}
type
  TRegistro = record  // registro ejemplo
    a: string[10];
    b: string[12];
    c: string[7];
  end;

(* Pasa registro a cadena. Completa longitud fija con espacios al final *)
function RecordToString(r: TRegistro): string;
begin
  Result := r.a + StringOfChar(' ', SizeOf(r.a) - Length(r.a) - 1)+
            r.b + StringOfChar(' ', SizeOf(r.b) - Length(r.b) - 1)+
            r.c + StringOfChar(' ', SizeOf(r.c) - Length(r.c) - 1)
end;

(* Pasa las cadenas de longitud fija al registro *)
function StringToRecord(s: string): TRegistro;
begin
  with Result do
  begin
    a := Copy(s, 1, SizeOf(a)-1);
    b := Copy(s, SizeOf(a), SizeOf(b));
    c := Copy(s, SizeOf(a)+SizeOf(b)-1, SizeOf(c))
  end
end;
...

Ejemplo para guardar en el archivo de texto:
Código Delphi [-]
...
var
  r : TRegistro;
  F : TextFile;
begin
  ...
  AssignFile(F, ...
  ...
  Writeln(F, RecordToString(r));
  ...
Ejemplo para leer desde el archivo de texto:
Código Delphi [-]
...
var
 s : string;
 r : TRegistro; 
 F : TextFile;
begin
  AssignFile(F, ...
  ...
  while not Eof(F) do
  begin
    Readln(F, s);
    r := StringToRecord(s);
    ...
  end;
...
O si no, no estoy entendiendo el problema...


Saludos.
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....

Última edición por ecfisa fecha: 14-09-2012 a las 11:01:38. Razón: ortografía
Responder Con Cita
  #9  
Antiguo 14-09-2012
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 de nuevo.

Me quede pensando que tal vez tengas un registro con muchos campos de tipo string de diferentes tamaños y en ese caso se hace tedioso escribir los procedimientos anteriores.

Tratando de buscar el código simple, otra opción podría ser:
Código Delphi [-]
...
{$A-}
const
  (* Numero de campos del registro *)
  MaxFields = 20;
  (* Longitud de cada string del registro *)
  FieldsLength: array[1..MaxFields] of Integer = (12,9,8,5,7,11,...);

type
  TRegistro = record
    v: array[1..MaxFields] of string; // Campos
  end;

(* Registro a cadena *)
function RecordToString(r : TRegistro): string;
var
  i: Integer;
begin
  for i:= 1 to MaxFields do
    Result:= Result + r.v[i] + StringOfChar(' ', FieldsLength[i] - Length(r.v[i]));
end;

(* Cadena a registro *)
function StringToRecord(s : string): TRegistro;
var
  i,d: Integer;
begin
  d := 1;
  for i:= 1 to MaxFields do
  begin
    Result.v[i] := Copy(s, d, FieldsLength[i]);
    Inc(d,FieldsLength[i]);
  end;
end;
...

Saludos.
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
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
Mejor manera de validar un EDIT oscarac OOP 3 25-05-2011 20:00:46
mejor manera de conectar a Mysql chelox Conexión con bases de datos 2 16-05-2011 10:07:57
Tablas temporales. La mejor manera Wonni Conexión con bases de datos 14 10-07-2008 19:06:48
Firebird de la mejor manera david_uh Varios 7 19-01-2008 15:45:37
La mejor manera de Trabajar con Form manuelpr Varios 8 07-03-2005 17:08:14


La franja horaria es GMT +2. Ahora son las 19:09:52.


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