Ir al contenido


Foto

type Record personalizado


  • Por favor identifícate para responder
5 respuestas en este tema

#1 avechuche

avechuche

    Newbie

  • Miembros
  • Pip
  • 4 mensajes

Escrito 18 septiembre 2013 - 08:24

Hola gente soy nuevo por aca y en Delphi y necesito algo de ayuda. Tengo que hacer un programa q le permita al usuario crear su propia estructura

Cuando uno crea un record en Delphi lo hace asi (palabras más palabras menos)

Código:



delphi
  1.     TipoRegistro = Record
  2.         sApellido, sNombre: String[25];
  3.         iCodigoDeCliente: 0..9999;
  4.         iEstado: 0..1;
  5.         iColision: Integer;
  6.     End;



Con eso decimos que cada registro va a tener esos datos, ni más ni menos.
Si por esas casualidades yo necesito que en ese record además tenga, por ejemplo, la direccion y telefono de un cliente, tengo que modificar el código fuente y compilar el ".exe" de nuevo

Código:



delphi
  1.     TipoRegistro = Record
  2.         sApellido, sNombre, sDireccion: String[25];
  3.         iCodigoDeCliente: 0..9999;
  4.         iEstado: 0..1;
  5.         iColision, iTelefono: Integer;
  6.     End;



Por lo que para este ejercicio, no me sirve.
Lo que yo necesito es que cada usuario pueda elegir la cantidad de campos que tiene un record, el tipo de datos que va a contener y la longitud de estos.
No tengo ni idea de como empezar porque no se como implementarlo. Si alguno ya hizo algo de esto, me vendria re bien dos manos.

PD: No se si se puede hacer con record, lo que si NO puedo usar base de datos.
  • 0

#2 FerCastro

FerCastro

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 637 mensajes
  • LocationCiudad de México

Escrito 19 septiembre 2013 - 10:13

Hola gente soy nuevo por aca y en Delphi y necesito algo de ayuda. Tengo que hacer un programa q le permita al usuario crear su propia estructura

PD: No se si se puede hacer con record, lo que si NO puedo usar base de datos.


Hola

A ver entiendo lo que deseas hacer, pero esto en un ejercicio de... que?? (perdona la pregunta, pero me brinca la curiosidad por saber para qué deseas hacer esto).

Existe un componente free de los laboratorios Devart que se llama Virtual Table la cual a mi me resulta muy muy útil para trabajar estructuras en memoria:

http://www.devart.com/vtable/

Supongo que si la implementas invariablemente tendrás que hacer un diálogo donde el usuario pueda crear la estructura del registro que desee, y a su vez podrías tu ir agregando campos a un objeto VirtualTable.

Ahora, es todo? vas a querer hacer tb en tiempo de ejecución una forma para capturar los datos de la estructura creada?  o es solo un ejercicio de programación?

Saludos!!


  • 0

#3 avechuche

avechuche

    Newbie

  • Miembros
  • Pip
  • 4 mensajes

Escrito 19 septiembre 2013 - 05:59

Antes que nada gracias por la respuesta.

Tengo que hacer 3 ejercicios de repaso para la materia Base de Datos. En los 3 casos son ABM.
1) Un ABM con datos fijos (ID, Nombre, Apellido y Dirección) que se accede de modo secuencial, osea que yo para buscar un cliente por ID (por ejemplo), tengo que recorrer todo el archivo linea por linea hasta que lo encuentre o no.
2) Lo mismo que el primero pero con hash, osea cuando busco un cliente por algun campo (Este caso el ID), valla directo a la linea que contiene el cliente y no recorrer todo el archivo linea por linea.
3) Lo mismo que el primero pero aca el usuario tiene que tener la posibilidad de elegir los campos que va a tener su ABM, que no este restringido. Si uno quiere agregarle la direccion, mail y CUIT al cliente, que lo pueda agregar el, y no que el programador tenga que el mismo ponerlo y compilar el ".exe" de nuevo.

Si por supuesto tengo que poder guardar en un archivo los datos y poder mostrarlos, por ejemplo en un grid.
  • 0

#4 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.301 mensajes
  • LocationArgentina

Escrito 20 septiembre 2013 - 06:44

Hola avechuche,
Me resulta muy extraño la práctica que se te ha dado en la cátedra de base de datos y que a su vez como requisito sea el NO emplear algún motor de base de datos.
Más aún, que tales ejercicios estén mucho más orientados a una programación que al diseño de una base de datos como debiera de esperar.

En lo que si queda claro, y se sobre entiende, que si te piden tales ejercicios es porque se te han dados los conocimientos necesarios para encararlos. Es poco probable que un profesor les haya solicitado algo que escape a los contenidos dictados de clase, pero viendo las descripciones que haces del ejercicio 2 y 3 me hacen sospechar del alcance teórico y práctico dados en cátedra. Hacer tal cosa es algo por demás complejo como para canalizarlo como un mero trabajo práctico. En su lugar da a pensar que tal pedido sale de órbita conceptual y de las posibilidades que incluso un estudiante avanzado pueda encarar y realizar en poco tiempo; ¡parecen ejercicios hechos tirar a matar, que a tu profesor se le salió la cadena!

El ejercicio 1 mal que bien es encarable, si no se puede hacer uso de base de datos para hacer el trabajo con simples archivos y haciendo uso de los records como el que pones de ejemplo basta con definir un archivo de registro:



delphi
  1. type
  2. FileDB =  file of TRegistro;



Y utilizar las instrucciones Apend(), Seek() y entre otras para el tratamiento de archivos. Lo pesado de hacer el trabajo de esta manera artesanal es implementar los algoritmos para recorrido del archivo y volcar los datos al form (y viceversa, del form al archivo).

Pero por el otro lado, hacer el 2 ya es algo descomunal. Naturalmente no basta con hacer un simple archivo de registros. Se debe hacer uso de una estructura de datos que brinde soporte para una localización de registros que no sea secuencial. De algún modo se necesita de cierta indexisación. Tu mencionas hash. Justamente los motores de base de datos emplean la estructura de datos árboles para organizar la información, y a modo de índices se basan en el uso de hash o Btrees.
¡Esto implica que para llevar a cabo tu ejercicio te veas obligado a diseñar tu mini motor de base de datos!  :| Y por eso es que a mi me resulta todo un despropósito pedirle esto a un estudiante.

Del punto 3 mejor no digo... por empezar devidentmente no se puede encararlo por el lado del record para mantener la estructura de datos. Si el objetivo es que sea variante se debe encarar de otra forma. Mi primer pensamiento me lleva a pensar en el uso de clases del tipo TxxxList. Y cambiar del paradigma estructurado al paradigma orientado a objetos.
Dispondría de una clase que aproveche un TObjectList de forma interna para almacenar los campos y que tenga métodos como AddField, DeleteField entre otros para agregar, eliminar campos y demás.
Ahora bien lo complicado de esto es justamente en como llevar el tipo de datos. Si un usuario quiere agregar un campo que sea fecha/hora nuestra hipotetica clase TDBTable deberá ser capaz en su método AddField contar entre sus parámetros la forma de indicarle que el campo es un TDateTime, y lo mismo si fuera un integer, etc.
Otra forma es que se dispongan tantos AddField como tipos de esperar y que cada uno agrege un hipotético objeto de clase TDBField y se le asocie el tipo indicado.
Esto es por demás algo mucho más complejo. Parte del trabajo ya está hecho en Delphi... existe el tipo de dato Variant, al que se le puede asociar y almacenar diferentes datos. Más aún, toda la parte de la VCL encargada de trabajar con base de datos tiene su diseño basado en una clase ya definida... la hipotética TDBTable no es más que el TCustomDataSet. La clase base de la cual deriva todo el trabajo de las diferentes suite.
Es decir: hacer doble terminarías haciendo doble trabajo. Internamente TCustomDateSet tiene una lista que almacena objetos TField, la clase base para todos los tipos de campos. Internamente los Fields almacenan el dato en forma Variant y gracias a las ya existentes rutinas para conversión de un dato a variant (y viceversa) es que hacen el trabajo sucio.

Sugiero que explores la VCL e investigues sobre TCustomDataSet, TField, y Variant. Pero más que nada reomiendo que te hacerces a hablar con tu profesor y evacúes tus dudas primero con él; sugiero que de forma educada le hagas entender que el trabajo es por demás complejo como para pedirles eso.
Es un trabajo por demás proporcionado. Y que a mi parecer se sale de tónica... esto tiene más pinta para cátedra de programación que de base de datos.

Saludos,
  • 0

#5 Héctor Randolph

Héctor Randolph

    501st Legion

  • Moderadores
  • PipPipPip
  • 664 mensajes
  • LocationMéxico

Escrito 20 septiembre 2013 - 12:27

Este tema me hizo recordar la manera en que DBase guardaba la información en lo que ahora conocemos como archivos planos de tablas.

Si revisamos la estructura de un archivo de dbase (  buscando por google aparecen muchos resultados) esta es la idea básica que se puede extraer:


Estructuramos nuestro archivo de tal manera que contenga la definción de los campos que forman la tabla así como los mismos datos.

Tomando como base la estructura que se utilizaba en dbase propongo algo como esto:

Un encabezado que contenga información acerca de cuántos campos tiene nuestra tabla, qué tipo de datos tiene y cuántos registros forman el archivo.

El siguiente espacio lo utilizamos para guardar los datos en bloques de tamaño fijo y al final un delimitador constante para indicar el final del archivo.

La estructura puede ser algo como esto aunque se puede adaptar a las necesidades de cada uno.

Estructura del encabezado

[table]
[tr]
[td]Tamaño en bytes[/td]
[td]Descripción[/td]
[td]Abreviatura[/td]
[/tr]

[tr]
[td]2[/td]
[td]Número de bytes en el encabezado[/td]
[td]nbe[/td]
[/tr]


[tr]
[td]4[/td]
[td]Número de registros contenidos en el archivo[/td]
[td]nreg[/td]
[/tr]

[tr]
[td]4[/td]
[td]Número de campos[/td]
[td]nc[/td]
[/tr]


[tr]
[td]4[/td]
[td]Número de bytes por registro[/td]
[td]nbr[/td]
[/tr]

[tr]
[td]15*nc[/td]
[td]Arreglo con la descripción de los registros (la estructura de este cada entrada de este arreglo se muestra abajo)[/td]
[td][/td]
[/tr]


[/table]

Estructura de cada uno de los campos

[table]
[tr]
[td]Tamaño en bytes[/td]
[td]Descripción[/td]
[/tr]

[tr]
[td]12[/td]
[td]Nombre del campo[/td]
[/tr]

[tr]
[td]1[/td]
[td]Tipo de dato. Los siguientes valores son permitidos:
T =Texto, F = Fecha, E = Entero, N = Numérico
[/td]
[/tr]

[tr]
[td]1[/td]
[td]Longitud del campo[/td]
[/tr]

[tr]
[td]1[/td]
[td]Número de decimales ( solamente tiene sentido cuando el tipo de datos es numérico)[/td]
[/tr]
[/table]

Para que se comprenda mejor la idea esta es la estructura que tendría el archivo:


Imagen Enviada

Estoy proponiendo que los campos sean de cuatro tipos de datos diferentes para hacerlo sencillo. Los tipos de datos se denotan por un caracter que puede ser  'T','F','E','N' para texto, fecha, entero y numérico respectivamente.

En Dbase al eliminar un registro en realidad solamente se marcaba de una manera especial dentro del archivo. Esto se hacía porque eliminar físicamente un registro implicaba muchas operaciones de lectura y escritura en disco que eran lentas en esa época. La manera de solucionarlo fue colocando un byte como marca al principio de cada registro. Si esta marca corresponde al caracter  (20h) ASCII que es un espacio en blanco, entoces el registro se considera activo. Si la marca corresponde al caracter (2Ah) ASCII que es un asterisco, entonces el registro se considera inactivo o eliminado. Al final si el archivo crecía demasiado con una operación llamada PACK se eliminaban fisicamente los registros marcados como inactivos en una sola operación.

Ahora viene el trabajo pesado que consiste en crear las rutinas para leer y escribir en este archivo

Lo primero es definir la estructuras necesarias:



delphi
  1.   TEncabezado = record
  2.     nbe: Word; // bytes en el encabezado
  3.     nreg: LongWord; // registros en el archivo
  4.     nc: LongWord; // número de campos
  5.     nbr: LongWord; // bytes por cada registro
  6.   end;
  7.  
  8.   TDefCampo = record
  9.     Nombre  : String[12];
  10.     TipoDato : Char; // T =Texto, F = Fecha, E = Entero, N = Numerico
  11.     Longitud : Byte;
  12.     Decimales: Byte;
  13.   end;
  14.  
  15.   PArrayCampos = ^TArrayCampos;
  16.   TArrayCampos = array of TDefCampo;



Ahora lo que sigue es crear rutinas para crear la estructura del archivo.

Primero se debe crear una función que permita crear nuevos campos



delphi
  1. procedure NuevoCampo(ArrayCampos:PArrayCampos; ANombre:String;ATipoDato:Char;ALongitud,ADecimales: Byte);
  2. var
  3.   Dim: Integer;
  4. begin
  5.   Dim:=Length(ArrayCampos^);//Obtenemos el tamaño actual del arreglo
  6.   Inc(Dim);//Para incrementar el tamaño del arreglo
  7.   SetLength(ArrayCampos^,Dim);
  8.   //Guardamos la definición del nuevo campo
  9.   ArrayCampos^[Dim-1].Nombre:=Copy(ANombre,1,12);//Restringimos la cadena a 12 caracteres
  10.   ArrayCampos^[Dim-1].TipoDato:=ATipoDato;
  11.   ArrayCampos^[Dim-1].Longitud:=ALongitud;
  12.   ArrayCampos^[Dim-1].Decimales:=ADecimales; 
  13. end;
  14.  
  15. procedure TForm1.Button1Click(Sender: TObject);
  16. var
  17. P: PArrayCampos;
  18. NC: Integer;
  19. I: Integer;
  20. begin
  21.   //Creamos un arreglo y agregamos dos campos
  22.   New(P);
  23.   NuevoCampo(P,'Nombre','T',20,0);
  24.   NuevoCampo(P,'Apellidos','T',40,0);
  25.  
  26.  
  27.   //Para probar que funciona
  28.   NC:=Length(P^); //Obtenemos el total de campos
  29.   ShowMessageFmt('%d',[ NC]);
  30.   for I := 0 to Dim - 1 do
  31.     ShowMessage(P^[I].Nombre);
  32.   Dispose(P);
  33. end;



Con esto tenemos lo necesario para crear múltiples campos en nuestra tabla.

Ahora tenemos que hacer una rutina para guardar registros en estos campos, también faltan las rutinas para guardar todo en el archivo y después recuperarlo.

Por le momento no puedo continuar con el ejercicio, pero esto da una idea general de lo que propongo para resolverlo.

Espero que sea útil

Saludos
  • 0

#6 avechuche

avechuche

    Newbie

  • Miembros
  • Pip
  • 4 mensajes

Escrito 20 septiembre 2013 - 04:57

Antes que nada muchisimas gracias por la ayuda y las explicaciones. Voy a agregar algo que se me paso.

1) El punto 1 y 2, ya los tengo echo y funcionan re lindo re bonito, lo hice con record nada de otro mundo, es mas el 90% del código del ejercicio 2,  es del ejercicio 1, adaptado a hash.
2) Para el ejercicio 3, me olvide de comentar, que para que sea """mas facil"""  todos los campos son del tipo string
3) No se puede usar base de datos porque es un TP de repaso de Programación 2, el problema es que en Programación 2, vimos hasta hash, nunca nada sobre el punto 3, que habla que se puede hacer con metadados, pero no se como aplicarlos!

Voy a revisar los datos que me tiraron a ver de que me disfrazo y que hago :)
  • 0




IP.Board spam blocked by CleanTalk.