En estos ejemplos, los cuales son continuación del tutorial de manejo de archivos, vamos a implementar una agenda sencilla. No vamos a codificar la parte de interfaz de usuario completamente ya que escapa al motivo de este tutorial, excepto en aquellas ocaciones donde sea estrictamente necesario.
Comenzaré planteando el problema general. Se trata de tener una base de datos en un solo archivo donde guardaremos los datos relevantes acerca de unos contactos para uso personal. Mantendremos al máximo la sencillez de los ejemplos, ya que no pretendemos contruir una aplicación completa de agenda sino solamente concentrarnos en el manejo de archivos.
Lo primero que tenemos que pensar es qué datos de los contactos queremos almacenar para luego manipularlos mediante Pascal. La unidad de trabajo básica de un archivo con tipo en Pascal es el registro, cada registro se corresponderá con un contacto de nuestra agenda. Yo he pensado que el registro que a continuación defino es lo mínimo necesario para esto:
type TStr30=String[30]; TStr50=String[50];
TFecha=record
Ano, Mes, Dia:Byte;
end; { TFecha }
TRegistro=record
Nombre, Apellido: TStr30;
Edad: byte;
Direccion: TStr50;
FechaCumple: TFecha;
end; { TRegistro }
TFileOfRegistro= File of TRegistro;
Voy a explicar por qué he usado esta definición paso por paso.
Primero defino dos tipos string limitados en tamaño debido a que Pascal no admite el tipo genérico String como campo de un archivo porque si se hace de esta forma no puede determinar el ancho de la cadena guardada, siempre se debe especificar un tamaño de string como campo de un registro que luego será guardado en un archivo, además esto ahorra espacio en disco; no tiene sentido guardar 255 caracteres de un campo de los cuales solo los primeros 15 son relevantes, estamos desperdiciando 230 caracteres; por lo que es muy buena práctica limitar el tamaño de los string a un tamaño razonable. Yo he elegido estos dos tamaños basado en mi experiencia con almacenamiento en archivos, ustedes pueden implementar el tamaño que crean conveniente según el dato a almacenar. Por ejemplo si deseáramos guardar el número de placa de automóviles, el cual consta de tres letras y tres números no tiene sentido definir un string de más de 6 caracteres para ese campo.
Definir como tipo separado los strings y otros datos complejos (tal como una fecha) nos servirá luego para poder trabajar con ellos en parámetros de procedimiento, además de centralizar todas las definiciones en un solo lugar, de modo tal que será más facil el día de mañana cuando lo necesitemos, cambiar la definición sin modificar el resto del código fuente.
El tipo fecha también lo he puesto como tipo aparte ya que asumo que en algún momento trabajaré solamente con la fecha de un contacto sin afectar al resto del registro.
Quizá cause curiosidad que incluya la edad y además la fecha de cumpleaños de nuestro contacto en dos campos separados siendo que en teoría teniendo la fecha podemos calcular la edad, pero en la práctica esto no siempre es así. Podemos tener la edad y no saber la fecha de cumpleaños.
He separado el nombre del apellido en dos campos, esto nos permitirá luego hacer ordenaciones al archivo usando un dato o el otro. La dirección creo que no necesita mayor explicación.
Finalmente he definido el tipo archivo de registro para poder, más adelante, usar ese tipo como tipo de parámetro en las funciones y procedimientos implementando operaciones sobre ese mismo archivo.
También es buena práctica tener el nombre físico del archivo como constante pues suponemos que no va a cambiar durante el desarrollo de nuestro programa.
Ahora bien, como estos tipos creados serán comunes o estandar durante el desarrollo de nuestra aplicación de agenda trasladaremos estas definiciones a una unidad (unit) la cual llamaremos mediante la palabra reservada unit al inicio de cada ejemplo, dicha unidad tendrá el nombre DEFIN.PAS e iré acumulando cada implementación que crea conveniente a esa unidad.
Entonces el código fuente de DEFIN.PAS comienza teniendo este contenido:
unit defin; interface const NombreFisico='agenda.dat';
type TStr30=String[30]; TStr50=String[50];
TFecha=record
Ano, Mes, Dia:Byte;
end; { TFecha }
TRegistro=record
Nombre, Apellido: TStr30;
Edad: byte;
Direccion: TStr50;
FechaCumple: TFecha;
end; { TRegistro }
TFileOfRegistro= File of TRegistro;
var
Archivo: TFileOfRegistro;
Registro: TRegistro;
UltimoError: Integer; { Para almacenar el £ltimo error dado por IOResult }
implementation
begin end.