Sign in Join
Wiki copytemporary

Lazarus Tdbf Tutorial/es: what changed

Revision 2 to 3. Removed lines have a minus sign; added lines have a plus sign.

OldNewLine
11## Resumen
22
33   Esta tutoría trata sobre el desarrollo elemental de bases de datos usando el componente [TDbf](http://tdbf.sf.net) (de Micha Nelissen) con Lazarus. Hay disponible documentación adicional para TDbf. Esta página fue creada por Tony Maro, pero ¡se agradecen otras colaboraciones!
44
55   En Lazarus, el componente DbfLaz utiliza el código de FPC TDbf.
66
77### Documentación
88
99   Para documentación de TDbf en PDF ir a [SourceForge](https://sourceforge.net/project/showfiles.php?group_id=34085&package_id=26371). Puede ser útil tener este pdf junto con este documento durante su lectura.
1010
1111Este artículo sirve como documentación adicional para nuevas características respecto a la documentación original.
1212
1313### Alternativas y problemas conocidos
1414
1515   Alternativas para bases de datos embedias tales como Firebird embebido (ventaja: fácilmente escalable para cliente / servidor), SQLite (ventaja: fácil implementación), o ZMSQL (usa archivos CSV; ventaja: sólo necesita código Pascal).
1616
1717   Problemas conocidos: El código TDbf careció de mantenedor por largo tiempo. Actualmente (marzo de 2013), tanto el proyecto *upstream* de Sourceforge (centrado en Delphi) como los desarrolladores de bases de datos FPC están de nuevo para arreglar errores de TDbf. Los errores corregidos en el trunk de FPC necesitarán fusionarse con la versión de SourceForge y viceversa.
1818
1919Incidencias actuales: por favor ver bugs en el seguimiento de errores, especialmente <http://bugs.freepascal.org/view.php?id=22177>
2020
2121#### Limitaciones
2222
2323- TDBF establece la codificación de la base de datos basándose en las configuraciones del lenguaje del sistema operativo (puedes establecer el tuyo estableciendo LanguageID; ver documentación). Mover una de estas bases de datos a un computador que no soporta dicha codificación puede ocasionar que la base de datos se quede como de solo lectura. *Nota: investigar cuando esto se aplica a Tablelevel 7 (Visual DBase) y 25/30 (Foxpro/Visual Foxpro)*
2424
2525- Ninguno de los formatos DBF utilizados soporta codicación Unicode (si UTF-8, UTF-16 o UTF-32). Podría haber una solución utilizando campos binarios, pero entonces perderiamos habilidades de reordenación, etc.
2626
2727- El indexado de un fichero DBase con \[ixCaseInsensitive\] no funciona actualmente.
2828- No soporta todavía integridad referencial en formatos de fichero que si lo soportan (DBase VII, Visual FoxPro).
2929- No soporta (ahora o bien para siempre) encriptación interna de ficheros .dbf: el mecanismo de encriptación de DbaseIV es bastante debil de todos modos. Por favor utiliza uno de los métodos de encriptación que se mencionan más abajo.
3030
3131FPC 2.6.x y anteriores:
3232
3333- En procesadores ARM, el códigoTDBF es sabido que no funciona debido a incidencias de alineación de bus. Esto está siendo addressed en la versión de desarrollo/trunk.
3434- Escoger el tablelevel (25) de FoxPro generará ficheros que no se podrán leer mediante drivers Visual Foxpro. Esto se ha solucionado en la versión de desarrollo/trunk de FPC.
3535
3636### No necesita instalación
3737
3838  El paquete DbfLaz (dbflaz.lpk) viene instalado por defecto tanto en FPC como en Lazarus. Este paquete utiliza TDbf y sus unidades asociadas en Free Pascal Free Component Library. En otras palabras, no es necesario instalar nada si tienes justamente una versión reciente de Lazarus. Está situado en la carpeta lazarus/components/tdbf/.
3939
4040### ¿Qué se puede hacer con TDbf?
4141
4242   El componente TDbf proporciona a Lazarus (y otros entornos) acceso a tablas dBase y FoxPro. Permite la lectura, escritura y creación de tablas dBase III+, dBase IV, Visual dBase VII y FoxPro. Y sin necesitar librerías o gestores de bases de datos adicionales. Simplemente ponga el componente TDbf en su formulario y tendrá acceso inmediato a un entorno de bases de datos de para múltiples plataformas. TDbf funciona tanto en Windows como en Linux usando Lazarus.
4343
4444## Cómo crear una nueva tabla
4545
4646   Como no hay todavía una aplicación "Database Desktop" para Lazarus, debemos crear las tablas de la base de datos mediante código, o utilizando herramientas externas.
4747
4848Puedes probar esta aplicación (windows - funciona con ***wine***): <http://www.dirfile.com/cdbf_explorer.htm>
4949
5050### Establecer la ruta de acceso
5151
5252   Es recomendable crear una carpeta para sus aplicaciones de bases de datos. Esto simplifica la realización de copias de seguridad de los datos. Hay dos maneras de establecer la ruta de acceso. Puede fijar la ruta completa usando la propiedad FilePathFull, o puede establecer una ruta relativa a la ruta del programa con FilePath. Por ejemplo, estableciendo "FilePath" en tiempo de ejecución a "datos/" utilizaría una subcarpeta de datos dentro de la carpeta del archivo ejecutable. Fijar la propiedad "FilePathFull" a "/var/datos/" colocaría todo en esa carpeta, no teniendo en cuenta la ubicación del programa.
5353
5454### Elegir un tipo de tabla con *TableLevel*
5555
5656   Por omisión, TDbf creará tablas dBase IV. Aunque son muy compatibles, hay características que puede desear usar que no están disponibles. Para poder utilizar campos *autoincrementales*, debe usar algo más nuevo. Los tipos de tabla posibles son:
5757
5858Tipos de tabla
5959
6060TableLevel
6161
6262dBase III+
6363
64643
6565
6666dBase IV
6767
68684
6969
7070Visual dBase VII
7171
72727
7373
7474FoxPro
7575
767625
7777
7878   Para elegir un tipo de tabla de el valor adecuado a la propiedad TableLevel.
7979
8080### Añadir campos
8181
8282   La creación de campos para su nueva tabla en tiempo de ejecución se realiza como en Delphi. Una vez establecidas las propiedades FilePath, TableLevel, y TableName, hay que utilizar la propiedad FieldDefs para determinar su estructura. Por ejemplo:
8383
8484``` pascal
8585 MyDbf.FilePathFull := '/ubicacion/para/mis/datos';
8686 MyDbf.TableLevel := 7;
8787 MyDbf.TableName := 'clientes.dbf'; // nota: ¿es realmente necesario .dbf?
8888 With MyDbf.FieldDefs do begin
8989 Add('Id', ftAutoInc, 0, True);
9090 Add('Nombre', ftString, 80, True);
9191 End;
9292```
9393
9494   Los tipos de campo definidos son:
9595
9696- ftUnknown
9797- **ftString**
9898- **ftSmallInt**
9999- **ftInteger**
100100- **ftWord**
101101- **ftBoolean**
102102- **ftFloat**
103103- **ftCurrency** (TableLevel 25)
104104- **ftBCD** (TableLevel 25)
105105- **ftDate**
106106- ftTime
107107- **ftDateTime**
108108- **ftBytes** (TableLevel 25)
109109- ftVarBytes
110110- **ftAutoInc** (TableLevel 7 or 25)
111111- **ftBlob**
112112- **ftMemo**
113113- ftGraphic
114114- ftFmtMemo
115115- ftParadoxOle
116116- **ftDBaseOle**
117117- ftTypedBinary
118118- ftCursor
119119- **ftFixedChar**
120120- **ftWideString**
121121- **ftLargeInt**
122122- ftADT
123123- ftArray
124124- ftReference
125125- ftDataSet
126126- ftOraBlob
127127- ftOraClob
128128- ftVariant
129129- ftInterface
130130- ftIDispatch
131131- ftGuid
132132- ftTimeStamp
133133- ftFMTBcd
134134
135135   Los tipos que aparecen en negrita son los soportados en la actualidad.
136136
137137### ¡Siga adelante y créela!
138138
139139   Una vez que ha definido los campos deseará usarlos en su nueva tabla, puede seguir adelante y crearla con:
140140
141141``` pascal
142142 MyDbf.CreateTable;
143143```
144144
145145## Añadir índices a una tabla
146146
147147   Si su base de datos es bastante grande, deberá definir índices para hacer búsquedas más rápidas. Para cambiar la estructura de índices de una tabla, deberemos tener acceso exclusivo a la tabla -mientras los creamos.
148148
149149``` pascal
150150 MyDbf.Exclusive := True;
151151 MyDbf.Open;
152152```
153153
154154   Justo ahora, tenemos que añadir el índice.
155155
156156``` pascal
157157 MyDbf.AddIndex('clienteid', 'Id', [ixPrimary, ixUnique]);
158158 MyDbf.AddIndex('nombrecliente','Nombre', [ixCaseInsensitive]);
159159 MyDbf.Close;
160160```
161161
162162## Lo unimos todo y ... ¡ya está!
163163
164164   El siguiente ejemplo crea una tabla "clientes" mediante código. Esto, por supuesto, sólo es necesario hacerlo una vez para cada tabla, y de ahí en adelante, **abrir la tabla, no crearla ;-)**
165165
166166``` pascal
167167 {Necesitamos que las siguientes unidades aparezcan en la clásula USES:}
168168 uses {otras unidades, } Dbf, db, Dbf_Common;
169169 { "Dbf" aparecerá, automáticamente, cuando pongamos el componente TDbf en el formulario... }
170170 { pero necesitamos la unidad "db" para el objeto DataSet
171171 { y la unidad "Dbf_Common" para las definiciones de tipos de campo, por ejemplo }
172172 var
173173 MyDbf: TDbf;
174174 begin
175175 MyDbf := TDbf.Create(nil);
176176 try
177177
178178 MyDbf.FilePath := 'datos/'; // usamos una ruta de acceso relativa para la carpeta "datos"
179179 MyDbf.TableLevel := 7; // utilizaremos tablas de tipo "Visual dBase VII"
180180 MyDbf.Exclusive := True; // imprescindible para poder modificar la estructura añadiendo campos
181181 MyDbf.TableName := 'clientes.dbf';
182182 With MyDbf.FieldDefs do begin
183183 Add('Id', ftAutoInc, 0, True);
184184 Add('Nombre', ftString, 80, True);
185185 End;
186186 MyDbf.CreateTable;
187187 MyDbf.Open;
188188 MyDbf.AddIndex('clienteid', 'Id', [ixPrimary, ixUnique]);
189189 { añadimos un índice secundario }
190190 MyDbf.AddIndex('nombrecliente','Nombre', [ixCaseInsensitive]);
191191 MyDbf.Close;
192192 finally
193193 MyDbf.Free;
194194 end;
195195```
196196
197197## Archivos índice externos
198198
199199   El componente TDBF también soporta índices secundarios que se almacenan en un archivo separado. Esto será útil cuándo la base de datos sea muy grande, al poder separar en varios archivos los distintos índices. Los archivos de índice secundarios se crean de forma muy parecida a los índices normales, pero con la adición de la extensión '.ndx ' en el nombre:
200200
201201``` pascal
202202 MyDbf.AddIndex('nombrecliente.ndx','Nombre', [ixCaseInsensitive]);
203203```
204204
205205   Estos índices no se gestionan de forma automática, por ello cada vez que se abre la tabla, se deberán cargar los archivos de índice que deseamos utilizar, usando el método *OpenIndexFile*, así:
206206
207207``` pascal
208208 MyDbf.OpenIndexFile('nombrecliente.ndx');
209209```
210210
211211   Por la misma razón los índices se empaquetan por separado, para ello utilizaremos el método *CompactIndexFile*, de esta forma:
212212
213213``` pascal
214214 MyDbf.CompactIndexFile('nombrecliente.ndx');
215215```
216216
217217   Y al dar el valor a la propiedad *IndexName*, para seleccionar el que estará activo, debemos incluir el nombre y la extensión:
218218
219219``` pascal
220220 MyDbf.IndexName := 'nombrecliente.ndx';
221221```
222222
223223## Cómo enlazar TDbf a componentes de datos
224224
225225   Los ejemplos anteriores muestran como crear una nueva tabla de base de datos mediante código. Usar la tabla es aún más simple.
226226
227227   Los componentes de acceso a datos en Lazarus (como *TDBEdit* y *TDbNavigator* por ejemplo) se vinculan a un componente *TDataSource* mediante las propiedades *DataSource* y *DataField*. El componente *TDataSource* controla la comunicación entre el gestor de bases de datos y los componentes de acceso a datos. Un *TDataSource* se vincula al componente *TDbf* mediante su propiedad *DataSet*. La conexión sería así:
228228
229-` TDbEdit------\`\
230-`              |`\
231-` TDbEdit------|-->TDataSource-->TDbf`\
232-`              |`\
233-` TDbNavigator-/`
229+```text
230+ TDbEdit------\
231+ |
232+ TDbEdit------|-->TDataSource-->TDbf
233+ |
234+ TDbNavigator-/
235+```
234236
235237   No olvides establecer las propiedades *FilePath* (o *FilePathFulll*), *TableLevel*, y *TableName* del componente *TDbf* a los valores adecuados antes de activarlos mediante
236238
237239``` pascal
238240 TDbf.Active := True;
239241```
240242
241243   Se podría decir mucho más sobre programación con bases de datos en Lazarus, y yo recomendaría un buen libro de programación de bases de datos con Delphi porque los conceptos fundamentales son los mismos. Constantemente hago referencia a mi ejemplar de "Liberado Delphi 2" porque los conceptos y el código básico no han cambiado mucho en 8 años.
242244
243245## Empaquetar y reconstruir índices
244246
245247   Cuando se borra un registro, realmente no desaparece físicamente del archivo que guarda la tabla. De vez en cuando debe *empaquetar* la tabla para eliminar realmente los registros y así recuperar ese espacio desaprovechado del archivo. Esto hay que hacerlo teniendo la tabla abierta en modo exclusivo.
246248
247249``` pascal
248250 MyDbf.Exclusive := True;
249251 MyDbf.Open;
250252 MyDbf.PackTable;
251253 // reconstruimos todos los índices
252254 MyDbf.RegenerateIndexes;
253255 MyDbf.Close;
254256 MyDbf.Exclusive := False;
255257```
256258
257259## Relaciones de tabla principal
258260
259261   La verdadera potencia de la programación de bases de datos comienza cuando tenemos múltiples tablas que se hacen referencia mutuamente. Mientras que TDbf aún no soporta la integridad referencial, si soporta una relación del tipo maestro/detalle entre componentes TDbf.
260262
261263   Cuando hay dos tablas relacionadas, por ejemplo:
262264
263-` [`**`clientes`**`]`\
264-` Id       <----\`\
265-` Nombre        |`\
266-` Telefono      |`\
267-` Direccion     |`\
268-`               |  ClienteID en facturas hace referencia a un campo primario de clientes`\
269-` [`**`facturas`**`]    |`\
270-` Id            |`\
271-` Importe       |`\
272-` ClienteID   --\---|  * Campo indexado como "idxclienteid"`
265+```text
266+ [clientes]
267+ Id <----\
268+ Nombre |
269+ Telefono |
270+ Direccion |
271+ | ClienteID en facturas hace referencia a un campo primario de clientes
272+ [facturas] |
273+ Id |
274+ Importe |
275+ ClienteID --\---| * Campo indexado como "idxclienteid"
276+```
273277
274278   Si desea mostrar todas las facturas para un cliente determinado, la tabla detalle (facturas) puede sincronizarse con la tabla principal (clientes) automáticamente.
275279
276280   En el componente TDbf de facturas seleccione lo siguiente:
277281
278282``` pascal
279283 InvDbf.IndexName := 'idxclienteid'; // campo que se emparejará con el campo ID de la tabla clientes
280284 InvDbf.MasterSource := dsClientes; // fuente de datos que se enlaza al componente TDbf de clientes
281285 InvDbf.MasterFields := 'Id'; // campo en la tabla clientes que emparejamos con nuestro índice
282286```
283287
284288## Cómo filtrar las Fechas vacías
285289
286290   Voy a mostrar aquí como podemos filtrar las fechas en blanco con el componente de Lazarus TDbf.
287291
288292   Considérese que en este ejemplo, el componente se denomina datos dbf1 y la base de datos tiene un campo, DT_ENCERRA, que indica cuando el caso se completó. Imagina también que necesitas crear un informe utilizando LazReport que enumera todos los casos que siguen pendientes, con el campo DT_ENCERRA en blanco.
289293
290294   La forma más sencilla de hacerlo es utilizando el controlador de eventos OnFilterRecord y poner el siguiente código:
291295
292296``` pascal
293297 if not dfb1.FieldByName('DT_ENCERRA').IsNull then Accept := False;
294298```
295299
296300   Cuando ponemos el valor de Accept a False todos los registros que no cumplen con esa condición particular, no se tienen en cuenta, es decir, no se muestran en el informe.
297301
298302   También es necesario poner la propiedad Dbf1.Filtered a True, pero fuera de este evento.
299303
300304``` pascal
301305 dfb1.Filtered := True;
302306```
303307
304308## Cómo filtrar un valor con TDbf
305309
306310   Supón que tienes una base de datos que identifica los productos con un código, por ejemplo, B019, y es necesario filtrar sólo aquellos productos que son de este código (B019, en este ejemplo) de manera que se genera un informe con LazReport. El componente se llama Dbf1. El campo que almacena el valor es "product_no"
307311
308312   Tenemos dos maneras de filtrar. La primera sería la de utilizar el siguiente código:
309313
310314``` pascal
311315 Dbf1.filter:= 'product_no "=" B019 "';
312316```
313317
314318   Resulta que esto funciona muy bien con varios componentes, pero no funciona con LazReport.
315319
316320   Para resolver el problema con LazReport puede utilizar el controlador de eventos OnFilterRecord y utilizar el siguiente código:
317321
318322``` pascal
319323 Accept:= Copy(Trim(Dbf1.FieldByName('product_no').AsString),1,4)='B019';
320324```
321325
322326   También es necesario poner la propiedad Dbf1.Filtered a True, pero fuera de este evento.
323327
324328   Como se dijo antes, cuando el valor de Accept es false los registros no se tienen en cuenta y de esta manera puede evitar mostrar todos los productos con ese código en el informe LazReport
325329
326330## Programa de ejemplo - navegador DB
327331
328332   He escrito un programa sencillo que utiliza el componente TDbf para abrir y mostrar tablas de bases de datos mediante el control dbGrid. El ejecutable Linux, junto con las fuentes del proyecto, que debería compilarse bien en Windows, está disponible en
329333
330-` `[`tony.maro.net`](http://tony.maro.net/mod.php?mod=downloads&op=showcat&id=3&level=1)
334+```text
335+ tony.maro.net
336+```
331337
332338## See also
333339
334340- [[Example: TDbf (creating table and indexes, selecting of index)]]
335341
336342## A tener en cuenta
337343
338344   Actualmente no se soporta la integridad referencial, ni los archivos .db encriptados internamente.
339345
340346- Traducido por Usuario: Mgsalvador
341347- Normalización de estilo y formato, y algún añadido menor, por iskraelectrica (jldc). 11 de junio de 2008.
342348
343349---
344350*From the Free Pascal wiki, page "Lazarus Tdbf Tutorial/es", as it stood on 2020-02-18 after a change by Trev, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*
345351Category: Castellano
346352Category: Español

Back to history