La Cabecera de los .DBF

 

Por Luis Martínez

 

Muchos son los que hemos tenido problemas con los ficheros DBF, con los ficheros de los campos Memo (FPT) y muchas también las consultas las que se han planteado hacia ellos. Tales motivos me han llevado a hacer este artículo. En él veremos la estructura de los mismos y que información es la que se graba, así como la forma de recuperar un DBF con campos memo. Entremos en materia.

La estructura de ficheros más importante que tiene FoxPro es el fichero .DBF que es el que contiene los datos.

Este fichero lo componen dos partes claramente diferenciadas: La cabecera y los registros de datos.

La cabecera del .DBF

De la misma forma que los ficheros DBF se componen de cabecera y registros de datos, la cabecera también se compone de dos partes. Empecemos por la primera...

Primera parte de la cabecera.

La primera parte tiene 32 bytes de longitud. La estructura tiene la siguiente forma:

 

El identificador del tipo de fichero puede ser de dos tipos:

- Si se tiene un campo memo definido en el primer byte aparecerá F5h.

- Si no contiene ningún campo memo será 03h.

- Si el valor contenido en este primer byte es distinto, FoxPro nos devolverá:

Not a database file

La última fecha de modificación se guardará en hexadecimal ocupando los bytes 2,3 y 4 correspondiente al año, mes y día, respectivamente.

El número de registros de la base de datos incluye el número de los registros de la tabla. Los bytes utilizados -del 5 al 8- están dispuestos en orden inverso de tal manera que el byte menos significativo es el primero de la izquierda. Por ejemplo:

0B 2A 01 00

correspode al número 00/01/2A/0B en hexadecimal. Puede ser que si usamos la función RECCOUNT() para contar el número de registros que contiene el fichero, el número que nos dé no coincida con este número exacto y es que contabiliza también aquellos registros marcados para ser borrados. Sólo cuando se haya realizado el correspondiente borrado físico(PACK) el resultado de la función RECCOUNT() será correcto.

La dirección donde comienza el primer registro de datos ocupan los bytes 9 y 10. Al igual que el anterior, los bytes están en orden inverso siendo 42(byte 9) 1B(byte 10) igual a la dirección 1B42 en hexadecimal.

A partir de la dirección indicada por dichos bytes comenzará los registros de datos.

La longitud de un registro es la suma de las longitudes de cada uno de los campos. Este ocupa 2 bytes.

El byte 29, Flag de componente de indexación(índices) nos indicará la presencia de un componente de índice estructural. Si por alguna causa el fichero de índices es borrado por medio de un comando DOS como por ejemplo DEL o ERASE, FoxPro nos enviaría el siguiente mensaje:

STRUCTURAL CDX FILE NOT FOUND

Para que esto no suceda la siguiente vez que queramos abrir el fichero deberemos ejecutar la siguiente orden para borrar el flag que indica que es un fichero con índices(indexado):

DELETE TAG ALL

Por último, el byte 30 indica el número de página con el que ha sido creado el DBF. El número total de valores de códigos de página que puede soportar son 19, sin embargo los valores más comunes que este byte contiene son los señalados en la figura 1

El programa que se encarga de poner el valor del código de página en la cabecera del fichero DBF se encuentra en el directorio domicilio de FoxPro y se llama CPZERO.PRG. En él se puede encontrar información adicional.

Los bytes sobrantes, que no son usados por FoxPro, suelen rellenarse con el carácter 0 o nulo.

Segunda parte de la cabecera.

La segunda parte de la cabecera depende del número de campos del que se componga el registro. Por cada uno de los campos utiliza 32 bytes organizados de la siguiente manera

señalada a continuación:

 

 

El nombre del campo en FoxPro está limitado a 10 caracteres, el último carácter (el más a la derecha ) debe ser nulo (0). Si el nombre del campo es infereior a 10 caracteres el primer carácter de la derecha será 0 o nulo.

Pueden existir, en principio, 5 tipos de campos definidos en el byte 12 con un carácter ASCII de la siguiente forma:

 

 

Valores de Tipos de Campos

 

Tipo

Carácter ASCII

Valor

Decimal

Valor Hexadecimal

Character (Carácter)

C

67

43

Date (fecha)

D

68

44

Logical (lógico)

L

76

4C

Memo

M

77

4D

Numeric (Numérico)

N

78

4E

Foat (coma flotante)

F

70

46

General

G

71

47

La dirección donde comienza el campo (bytes 13 y 14) nos indica la posición de comienzo del campo relativo al principio del registro.

La longitud de los campos depende del tipo de dato que vayamos a definir. Para los campos de caracteres utiliza los bytes 17 y 18 para insertar el tamaño, eso sí, en formato invertido. Para los campos tipo Fecha, Memo, General y Lógico sólo necesita el primer byte para definir sus tamaños:

8 para el campo Fecha.

10 para el campo Memo.

10 para el campo General.

1 para el campo Lógico.

Por último, para los campos numéricos el primer byte especifica el total de número de dígitos, y el segundo el número de posiciones decimales.

Los bytes restantes no son utilizados, y su valor suele ser rellenado a nulo (0).

Cómo controlar el final de la definición de los campos?

FoxPro no es capaz de controlar el número de definiciones de campos que se han realizado en la cabecera. Hay tres formas/maneras de determinar cuando hemos leido todos los campos:

1.- La suma de todos los tamaños. El último campo ha sido leído cuando el total es igual a la longitud contada en la cabecera menos 1 para el flag de borrado.

2.- Buscar el carácter 0Dh (13 decimal) como el primer carácter después de de la definición de un campo. Esto separa la cabecera del principio de los datos. Tendremos que tener en cuenta el byte extra cuando determinemos la longitud de una cabecera del DBF.

3.- Por último, contar el total de bytes y comparar con el valor del comienzo de los datos del fichero contenidos en los bytes 9 y 10 de la primera parte de la cabecera.

Datos de la base de datos.

Los datos comienzan inmediatamente después del byte de terminación de la cabecera. El primer byte de cada registro está en el flag de borrado. Si el flag de borrado contiene 20h, el registro es activo. Si por el contrario su valor es 2Ah, significa que ese registro ha sido marcado para ser borrado.

El siguiente byte es el primer byte del primer campo. No existen sepaciones entre los campos, no es necesario. La sección de definición del registro de cada campo ya especifica la longitud y la posición.

Los campos de tipo carácter son fáciles de leer. Cada byte, es añadido de izquierda a derecha, añadiendo un carácter. Determinar el contenido de un campo, es sólo cuestión de convertir el valor hexadecimal en su correspondiente valor ASCII.

Los campos de tipo fecha también son fáciles de interpretar. Cada campo ocupa 8 bytes. Los cuatro primeros son los relativos al año, los dos siguientes al mes y los dos últimos al día. Los bytes son dígitos ASCII del 30 al 39 hex que se corresponden con el 0 al 9 decimal. Al 1 de Enero de 1995 le corresponderían los siguientes valores:

A A A A M M D D -------- Formato

31 39 39 35 30 31 30 31 -------- Valor Hex.

1 9 9 5 0 1 0 1 -------- Valor Dec.

Los campos de tipo lógico usan los caracteres ASCII F y T, que traducidos a valores hexadecimales se corresponden con el 46h para el valor lógico falso(F) y 54h para el valor verdadero(T).

Los campos memo, como comentábamos antes, usan 10 bytes en cada registro. Si el campo resulta estar vacío, este se rellena con el carácter 20h (espacion en blanco). Si el campo memo no está vacío, los caracteres ASCII definen su posición (en bloques de 64 bytes) en el fichero .FPT. Por ejemplo, si tenemos los 10 bytes con los siguientes valores:

20 20 20 20 20 20 20 20 31 35 (Valores hex.) traducido a decimal 15

Los datos del campo memo comienzan después del décimo quinto bloque de 64 bytes del fichero FPT.

los campos numéricos en FoxPro son interpretados como números ASCII individuales. Define el número de dígitos por la estructura de la base de datos.

Supongamos que definimos un campo numérico de seis caracteres con tres decimales. El número 22,324 estaría de la siguiente manera:

32 32 2C 33 32 34 Hex.

2 2 , 3 2 4 Dec.

La coma decimal corresponde con el valor hexadecimal 2Ch. Si el número no ocupase las seis posiciones se toman los siguientes criterios:

- Si el espacio es por la izquierda se rellenará con un espacio en blanco (20h).

- Si el espacio no utilizado es por la derecha se pondrá un cero (30h).

Después del último registro, FoxPro añade un carácter de final de fichero (1Ah). Este byte se crea cuando se determina la longitud del fichero DBF. Tener en cuenta que es diferente al carácter de final de cabecera (0Dh).

Veamos un ejemplo.

Supongamos que tenemos un tabla llamada PERSONAL.DBF la cual tiene la siguiente estructura:

Esta tabla contiene dos registros de datos los cuales que se muestran en la columna de al lado:

Esto no es más que el enunciado de nuestro problema ya que lo que deseamos saber es qué contiene PERSONAL.DBF. Para eso es necesario hacer un volcado hexadecimal del fichero en la pantalla. (Cualquier programa de utilidades permite hacer esta operación. Por ejemplo las Pctools o Utilidades Norton).

Examinemos el contenido de la tabla PERSONAL.DBF:

Desplazamiento

 

 

 

 

 

Código Hexadecimal

 

 

 

 

 

 

 

 

 

 

0000(0000)

03

5E

0C

17

02

00

00

00

E1

00

49

00

00

00

00

00

0016(0010)

00

00

00

00

00

00

00

00

00

00

00

00

00

03

00

00

0032(0020)

4E

4F

4D

42

52

45

00

00

00

00

00

43

01

00

00

00

0048(0030)

14

00

00

00

00

00

00

00

00

00

00

00

00

00

00

00

0064(0040)

41

50

45

4C

4C

49

44

4F

53

00

00

43

15

00

00

00

0080(0050)

1E

00

00

00

00

00

00

00

00

00

00

00

00

00

00

00

0096(0060)

45

44

41

44

00

00

00

00

00

00

00

4E

33

00

00

00

0112(0070)

03

00

00

00

00

00

00

00

00

00

00

00

00

00

00

00

0128(0080)

53

4F

4C

54

45

52

4F

00

00

00

00

4C

36

00

00

00

0144(0090)

01

00

00

00

00

00

00

00

00

00

00

00

00

00

00

00

0160(00A0)

46

45

43

48

41

4E

41

43

00

00

00

44

37

00

00

00

0176(00B0)

08

00

00

00

00

00

00

00

00

00

00

00

00

00

00

00

0192(00C0)

46

4C

4F

54

41

4E

54

45

00

00

00

46

3F

00

00

00

0208(00D0)

0A

00

00

00

00

00

00

00

00

00

00

00

00

00

00

00

0224(00E0)

0D

20

4C

75

69

73

20

20

20

20

20

20

20

20

20

20

0240(00F0)

20

20

20

20

20

20

4D

61

72

74

69

6E

65

7A

20

50

0256(0100)

65

72

65

7A

20

20

20

20

20

20

20

20

20

20

20

20

0272(0110)

20

20

20

20

20

32

35

54

31

39

36

39

31

31

31

37

0288(0120)

20

31

32

33

32

33

32

33

34

34

20

50

65

70

65

20

0304(0130)

20

20

20

20

20

20

20

20

20

20

20

20

20

20

20

52

0320(0140)

75

62

69

6F

20

4D

6F

72

61

6C

65

73

20

20

20

20

0336(0150)

20

20

20

20

20

20

20

20

20

20

20

20

20

20

35

30

0352(0160)

46

31

39

36

30

30

34

31

32

20

20

20

20

32

39

39

0368(0170)

33

39

32

1A

00

00

D6

0B

43

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Para verlo más detalladamente dividiremos el volcado hexadecimal del fichero PERSONAL.DBF en tres partes:

1.- Cabecera general de la tabla.

2.- Cabecera de los datos de tabla.

3.- Los datos de la tabla.

1.- La cabecera general de la tabla ocupa 32 bytes, con el siguiente significado:

El primer byte (03h) indica que el DBF no tiene campos memo.

Los bytes del 2 al 4 indican la fecha: 5E(94), 0C(12) y 17(23). El formato fecha resultante sería 23/12/94. Quiere esto decir que la fecha la guarda en orden inverso (AAMMDD).

Los cuatro siguientes bytes indican el número de registro que contiene el fichero. En nuestro caso 2, siendo el byte más significativo el situado más a la derecha de los 4 bytes.

Los bytes 9 y 10 indican la posición de comienzo de los datos (posición 00E1).

Los dos siguientes bytes indican la longitud del registro.

Los bytes del del 13 al 28 y del 30 al 32, no se usan como ya habíamos comentado.

Por último el byte 29 es el flag de índices estructurales.

2.- La cabecera de los datos determina su valor por el número de campos que contenga el registro. Si bien, la definición de cada campo ocupa 32 bytes y comienza justo en el byte siguiente al del final de la definición de la cabecera general. Estudiemos su contenido:

Los 11 primeros bytes corresponden al nombre del campo. En nuestro caso los valores hexadecimales 4E 4F 4D 42 52 45(ver tabla tercera línea) es equivalente a los caracteres ascii N O M B R E. Ya que el campo no ocupa los 10 caracteres, estos, se rellenan a nulos (0).

El siguiente byte nos indicará el tipo de dato que representa 43h = C de carácter.

Los bytes 13 y 14 contendrán la dirección de comienzo del campo desde el principio del registro.

Si el campo es númerico el byte 17 indicará el tamaño del campo, la longitud de los campos decimales se insertarán en el byte 18. Si por el contrario el campo no es numérico, la longitud del campo vendrá reflejada en los bytes 17 y 18.

Los demás bytes, hasta completar los 32 bytes de la definición, no son usados(su valor suele ser nulo).

Una vez definidas las cabeceras, tanto la general como la correspondiente a los campos, ya sólo nos queda ver como estan los datos de la tabla.

3.- los datos de la tabla son insertados dentro del fichero secuencialmente. EL comienzo de los datos va precedido del carácter hexadecimal 0Dh que sirve de separación entre el final de la definición de los campos con el principio de los datos.

A continuación, tenemos un byte(el flag de borrado) el cual nos indicará si el registro esta activo o bien esta marcado para ser borrado, los valores que tendrá dicho flag serán 20h y 2Ah respectivamente. En nuestro ejemplo ambos registros están activos. Seguidamente van los datos correspondientes al registro.

Este mismo proceso se repite tantas veces como registros de datos hallamos introducido hasta que nos encontremos con carácter 1Ah que nos indicará el final del fichero.

Ficheros con campos Memo.

En el ejemplo anterior no hemos considerado que un fichero contenga campos de tipo Memo. Los ficheros con campos Memo sólo cambian en el primer byte del fichero cuyo valor sería F5h, indicando que el fichero DBF contiene campos Memo.

Este campo memo crea un fichero .FPT en el que irá el contenido el contenido de los datos. Este fichero es independiente del DBF al que va asociado, quiere esto decir que si marcase y borrase un registro de la tabla DBF que contubiera un campo Memo, este, no se borraría del fichero .FPT.

Existen tres formas principales de actualizar o modificar un .FPT:

- Cuando se modifica la estructura del DBF.

- Cuando copiamos la tabla con COPY TO

- Cuando empaquetamos el fichero memo con PACK o PACK MEMO

El fichero memo se divide en dos partes claramente diferenciables:

- La cabecera.

- Los datos.

La cabecera.

El fichero memo comienza con 512 bytes de cabecera. Sin embargo, sólo utiliza los ocho primeros bytes con la siguiente distribución:

Número byte

Descripción/contenido

1-4

Indica el número de bloques de datos en el fichero memo o la posición del siguiente bloque libre.

5-8

Indica la longitud del bloque de datos.

Datos Memo.

FoxPro sólo usa por defecto bloques de datos de 64 bytes, pudiendo así usar los campos memo más eficientemente para entradas pequeñas. Es posible cambiar el tamaño de los bloques pero en este ejemplo asumiremos el tamaño por defecto por simplicidad.

Hemos modificado la estructura de la tabla, añadiendo un campo más llamado observac que se será de tipo memo en el que apuntaremos las observaciones de cada registro de la tabla PERSONAL.DBF. La estructura quedará pues, de la siguiente manera:

El fichero, en este caso, es un registro con el siguiente contenido:

El volcado hexadecimal del fichero DBF será el siguiente:

Desplazamiento

 

 

 

 

 

Código Hexadecimal

 

 

 

 

 

 

 

 

 

 

0000(0000)

F5

5E

0C

17

01

00

00

00

01

01

53

00

00

00

00

00

0016(0010)

00

00

00

00

00

00

00

00

00

00

00

00

00

03

00

00

0032(0020)

4E

4F

4D

42

52

45

00

00

00

00

00

43

01

00

00

00

0048(0030)

14

00

00

00

00

00

00

00

00

00

00

00

00

00

00

00

0064(0040)

41

50

45

4C

4C

49

44

4F

53

00

00

43

15

00

00

00

0080(0050)

1E

00

00

00

00

00

00

00

00

00

00

00

00

00

00

00

0096(0060)

45

44

41

44

00

00

00

00

00

00

00

4E

33

00

00

00

0112(0070)

03

00

00

00

00

00

00

00

00

00

00

00

00

00

00

00

0128(0080)

53

4F

4C

54

45

52

4F

00

00

00

00

4C

36

00

00

00

0144(0090)

01

00

00

00

00

00

00

00

00

00

00

00

00

00

00

00

0160(00A0)

46

45

43

48

41

4E

41

43

00

00

00

44

37

00

00

00

0176(00B0)

08

00

00

00

00

00

00

00

00

00

00

00

00

00

00

00

0192(00C0)

46

4C

4F

54

41

4E

54

45

00

00

00

46

3F

00

00

00

0208(00D0)

0A

00

00

00

00

00

00

00

00

00

00

00

00

00

00

00

0224(00E0)

4F

42

53

45

52

56

41

43

00

00

00

4D

49

00

00

00

0240(00F0)

0A

00

00

00

00

00

00

00

00

00

00

00

00

00

00

00

0256(0100)

0D

20

4C

75

69

73

20

20

20

20

20

20

20

20

20

20

0272(0110)

20

20

20

20

20

20

4D

61

72

74

69

6E

65

7A

20

50

0288(0120)

65

72

65

7A

20

20

20

20

20

20

20

20

20

20

20

20

0304(0130)

20

20

20

20

20

32

35

54

31

39

36

39

31

31

31

37

0320(0140)

32

31

33

31

32

33

31

32

33

31

20

20

20

20

20

20

0336(0150)

20

20

20

20

1A

00

00

00

00

00

00

00

00

00

00

00

0352(0160)

00

00

00

00

00

00

00

00

00

00

00

00

00

00

00

00

0368(0170)

00

00

00

00

00

00

00

00

00

00

00

00

00

00

00

00

0384(0180)

00

00

00

00

00

00

00

00

00

00

00

00

00

00

00

00

0400(0190)

00

00

00

00

00

00

00

00

00

00

00

00

00

00

00

00

0416(01A0)

00

00

00

00

00

00

00

00

00

00

00

00

00

00

00

00

0432(01B0)

00

00

00

00

00

00

00

00

00

00

00

00

00

00

00

00

0448(01C0)

00

00

00

00

00

00

00

00

00

00

00

00

00

00

00

00

0464(01D0)

00

00

00

00

00

00

00

00

00

00

00

00

00

00

00

00

0480(01E0)

00

00

00

00

00

00

00

00

00

00

00

00

00

00

00

00

0496(01F0)

00

00

00

00

00

00

00

00

00

00

00

00

00

00

00

00

 

El Volcado del fichero FPT asociado al campo memo observac antes de insertar valor alguno al campo, es el siguiente:

Los 4 primeros bytes indican que el número de bloques que contiene el fichero ( 00 00 00 08 ) en decimal 8 bloques. los cuatro bytes siguientes indican el tamaño de cada bloque (00 00 00 40) en decimal 64 bytes cada bloque.

Estos 512 bytes coforman el fichero FPT en el caso de que esté vacío. Estos 512 bytes equivalen a la cabecera.

Si por el contrario hemos insertado información dentro del campo memo el contenido del fichero FPT variará, añadiendo en la cabecera los bloques que ocupen el contenido de cada campo memo en cada registro del DBF principal.

Imaginemos que hemos insertado información en el campo memo correspondiente al primer registro de PERSONA.DBF

El contenido del campo memo es este:

El volcado hexadecimal del DBF no variará al expuesto anteriormente pero el correspondiente al campo memo (FPT) sufrirá las siguientes modificaciones:

Estos 512 bytes corresponden a la cabecera. El contenido de los cuarto primeros bytes ha variado con respecto al anterior (00 00 00 0A) ya que el fichero necesita de dos bloques más para almacenar el contenido del campo memo. Los cuatro siguientes no es necesario modificarlos (cada bloque de 64 bytes). Ahora veremos el volcado de los datos del campo memo:

 

Los cuatro primeros bytes (00 00 00 01) indican el comienzo de un nuevo campo memo. Los 4 bytes siguientes indican la longitud del campo memo en cuestión (00 00 00 55) 85 bytes en decimal. Si bien, el siguiente campo memo no comenzará inmediatamente en el siguiente byte ya que esta estructura obliga a utilizar como medida mímina bloques de 64 bytes, es decir, para este campo necesito 2 bloques. Si tuviéramos más registros introducidos, el siguiente tendría la marca de principio de campo memo (00 00 00 01) a partir del byte 128, cuya casilla correspondiente está marcada con un X.

La información que pueda haber desde el final de un campo memo hasta el principio del siguiente no es tomada en cuenta.

Estas son, en definitiva las cosas a tener en cuenta a la hora de interpretar el contenido de una tabla con o sin campos memo y de las diferencias que ello conlleva.

Desde FoxPro.

Existe una serie de funciones las cuales guardan una cierta relación con lo comentado en este artículo y que pueden ser útiles en algún momento. Estas son:

Función

Descripción/Comentario

HEADER ()

Devuelve el número de bytes de la cabecera del archivo especificado.

RECSIZE()

Devuelve el tamaño del registro de un tabla.

RECCOUNT()

Devuelve el número de registros de una tabla.

RECNO()

Devuelve el número del registro actual.

FSIZE()

Devuelve el tamaño en bytes del fichero.

FCOUNT()

Devuelve el número de campos de la tabla.

DBF()

Devuelve el nombre de una tabla a partir de un número de área o alias.

FIELD()

Devuelve el nombre de un campo, a partir de su número en la definición de la tabla.

Para terminar, comentar que al modificar la estructura de un DBF que contiene uno o más campos Memo, el fichero FPT correspondiente a ese campo pasa a tener la extensión TBK. También deciros que si en la estructura de la tabla conviven tanto campos generales como campos Memo, el contenido de estos se gurardá en el mismo fichero FPT y con la misma estructura. Sólo cambiarán los 4 primeros bytes de comienzo de nuevo campo:

-Si el campo es Memo, los cuatro bytes contienen 00 00 00 01.

-Si el campo es General, los cuatro bytes contienen 00 00 00 02.

Cómo recuperar un Fichero .DBF con campos Memo?

Existen momentos en los que, trabajando con una tabla, se produce un corte de suministro eléctrico. Cuando este se restablece volvemos al lugar exacto, dentro de la aplicación, donde nos habíamos quedado. En ese momento puede haber pasado muchas cosas:

A- Que el fichero se restablezca con normalidad.

B- Que el fichero se restablezca con normalidad pero no se halla actualizado alguno de sus campos. Si hemos modificado un campo memo y en el momento del corte de electricidad el fichero se encontraba abierto, las modificaciones realizadas no se reflejarán.

C- Que el fichero DBF ocupe 0 bytes.

Las soluciones posibles que podríamos adoptar serían estás:

- Incorporar a nuestro sistema una unidad de alimentación ininterrumpida que permita cerrar los ficheros evitando posibles problemas.

- En el caso B, en el que tenemos un campo Memo (asociado a un fichero FPT) la solución es algo más compleja.

- Si el DBF existe pero el FPT no puede ser leído es porque en la cabecera del FPT donde se indica el número de bloques que tiene el fichero es incorrecto. Para solucionarlo se debe cambiar ese valor y poner en su lugar el resultado de la siguiente operación en hexadecimal:

Tamaño del archivo(en bytes) / tamaño_bytes por bloque + 1

- Si tanto el DBF como el FPT pueden ser leídos pero las modificaciones hechas en el campo memo no son reflejadas, no es porque no se halla grabado en el fichero FPT sino porque la cabecera de cada campo memo no ha podido modificar su nueva longitud. Esta información se puede recuperar tan sólo modificando el tamaño del campo desde alguna de las utilidades mencionadas en el artículo.

- Si nos encontramos que el DBF ocupa 0 bytes (caso C) no queda más remedio que mirar en el directorio si existe algún fichero .BAK para poder recuperar aunque sólo fuera su estructura.

Todas estas soluciones no son 100% libres de error(ojalá!), por ello es imprescindible tener siempre una copia de seguridad actualizada para que en el caso de catástrofe, ésta sea lo más pequeña posible.

Luis Martínez es Diplomado en Informática.


1999 FoxPress. All rights reserved.