Sign in Join
Wiki copytemporary

Lazarus Tdbf Tutorial/es: what changed

Revision 1 to 2. 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
58-<center>
59-
60-<table style="text-align: center; " border="1">
61-
62-<tr>
63-
64-<td>
65-
6658Tipos de tabla
6759
68-</td>
69-
70-<td>
71-
7260TableLevel
7361
74-</td>
75-
76-</tr>
77-
78-<tr>
79-
80-<td>
81-
8262dBase III+
8363
84-</td>
85-
86-<td>
87-
88643
8965
90-</td>
91-
92-</tr>
93-
94-<tr>
95-
96-<td>
97-
9866dBase IV
9967
100-</td>
101-
102-<td>
103-
104684
10569
106-</td>
107-
108-</tr>
109-
110-<tr>
111-
112-<td>
113-
11470Visual dBase VII
11571
116-</td>
117-
118-<td>
119-
120727
12173
122-</td>
123-
124-</tr>
125-
126-<tr>
127-
128-<td>
129-
13074FoxPro
13175
132-</td>
133-
134-<td>
135-
1367625
13777
138-</td>
139-
140-</tr>
141-
142-</table>
143-
144-</center>
145-
14678   Para elegir un tipo de tabla de el valor adecuado a la propiedad TableLevel.
14779
14880### Añadir campos
14981
15082   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:
15183
15284``` pascal
15385 MyDbf.FilePathFull := '/ubicacion/para/mis/datos';
15486 MyDbf.TableLevel := 7;
15587 MyDbf.TableName := 'clientes.dbf'; // nota: ¿es realmente necesario .dbf?
15688 With MyDbf.FieldDefs do begin
15789 Add('Id', ftAutoInc, 0, True);
15890 Add('Nombre', ftString, 80, True);
15991 End;
16092```
16193
16294   Los tipos de campo definidos son:
16395
16496- ftUnknown
16597- **ftString**
16698- **ftSmallInt**
16799- **ftInteger**
168100- **ftWord**
169101- **ftBoolean**
170102- **ftFloat**
171103- **ftCurrency** (TableLevel 25)
172104- **ftBCD** (TableLevel 25)
173105- **ftDate**
174106- ftTime
175107- **ftDateTime**
176108- **ftBytes** (TableLevel 25)
177109- ftVarBytes
178110- **ftAutoInc** (TableLevel 7 or 25)
179111- **ftBlob**
180112- **ftMemo**
181113- ftGraphic
182114- ftFmtMemo
183115- ftParadoxOle
184116- **ftDBaseOle**
185117- ftTypedBinary
186118- ftCursor
187119- **ftFixedChar**
188120- **ftWideString**
189121- **ftLargeInt**
190122- ftADT
191123- ftArray
192124- ftReference
193125- ftDataSet
194126- ftOraBlob
195127- ftOraClob
196128- ftVariant
197129- ftInterface
198130- ftIDispatch
199131- ftGuid
200132- ftTimeStamp
201133- ftFMTBcd
202134
203135   Los tipos que aparecen en negrita son los soportados en la actualidad.
204136
205137### ¡Siga adelante y créela!
206138
207139   Una vez que ha definido los campos deseará usarlos en su nueva tabla, puede seguir adelante y crearla con:
208140
209141``` pascal
210142 MyDbf.CreateTable;
211143```
212144
213145## Añadir índices a una tabla
214146
215147   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.
216148
217149``` pascal
218150 MyDbf.Exclusive := True;
219151 MyDbf.Open;
220152```
221153
222154   Justo ahora, tenemos que añadir el índice.
223155
224156``` pascal
225157 MyDbf.AddIndex('clienteid', 'Id', [ixPrimary, ixUnique]);
226158 MyDbf.AddIndex('nombrecliente','Nombre', [ixCaseInsensitive]);
227159 MyDbf.Close;
228160```
229161
230162## Lo unimos todo y ... ¡ya está!
231163
232164   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 ;-)**
233165
234166``` pascal
235167 {Necesitamos que las siguientes unidades aparezcan en la clásula USES:}
236168 uses {otras unidades, } Dbf, db, Dbf_Common;
237169 { "Dbf" aparecerá, automáticamente, cuando pongamos el componente TDbf en el formulario... }
238170 { pero necesitamos la unidad "db" para el objeto DataSet
239171 { y la unidad "Dbf_Common" para las definiciones de tipos de campo, por ejemplo }
240172 var
241173 MyDbf: TDbf;
242174 begin
243175 MyDbf := TDbf.Create(nil);
244176 try
245177
246178 MyDbf.FilePath := 'datos/'; // usamos una ruta de acceso relativa para la carpeta "datos"
247179 MyDbf.TableLevel := 7; // utilizaremos tablas de tipo "Visual dBase VII"
248180 MyDbf.Exclusive := True; // imprescindible para poder modificar la estructura añadiendo campos
249181 MyDbf.TableName := 'clientes.dbf';
250182 With MyDbf.FieldDefs do begin
251183 Add('Id', ftAutoInc, 0, True);
252184 Add('Nombre', ftString, 80, True);
253185 End;
254186 MyDbf.CreateTable;
255187 MyDbf.Open;
256188 MyDbf.AddIndex('clienteid', 'Id', [ixPrimary, ixUnique]);
257189 { añadimos un índice secundario }
258190 MyDbf.AddIndex('nombrecliente','Nombre', [ixCaseInsensitive]);
259191 MyDbf.Close;
260192 finally
261193 MyDbf.Free;
262194 end;
263195```
264196
265197## Archivos índice externos
266198
267199   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:
268200
269201``` pascal
270202 MyDbf.AddIndex('nombrecliente.ndx','Nombre', [ixCaseInsensitive]);
271203```
272204
273205   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í:
274206
275207``` pascal
276208 MyDbf.OpenIndexFile('nombrecliente.ndx');
277209```
278210
279211   Por la misma razón los índices se empaquetan por separado, para ello utilizaremos el método *CompactIndexFile*, de esta forma:
280212
281213``` pascal
282214 MyDbf.CompactIndexFile('nombrecliente.ndx');
283215```
284216
285217   Y al dar el valor a la propiedad *IndexName*, para seleccionar el que estará activo, debemos incluir el nombre y la extensión:
286218
287219``` pascal
288220 MyDbf.IndexName := 'nombrecliente.ndx';
289221```
290222
291223## Cómo enlazar TDbf a componentes de datos
292224
293225   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.
294226
295227   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í:
296228
297-<code>` TDbEdit------\`\
229+` TDbEdit------\`\
298230`              |`\
299231` TDbEdit------|-->TDataSource-->TDbf`\
300232`              |`\
301-` TDbNavigator-/`</code>
233+` TDbNavigator-/`
302234
303235   No olvides establecer las propiedades *FilePath* (o *FilePathFulll*), *TableLevel*, y *TableName* del componente *TDbf* a los valores adecuados antes de activarlos mediante
304236
305237``` pascal
306238 TDbf.Active := True;
307239```
308240
309241   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.
310242
311243## Empaquetar y reconstruir índices
312244
313245   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.
314246
315247``` pascal
316248 MyDbf.Exclusive := True;
317249 MyDbf.Open;
318250 MyDbf.PackTable;
319251 // reconstruimos todos los índices
320252 MyDbf.RegenerateIndexes;
321253 MyDbf.Close;
322254 MyDbf.Exclusive := False;
323255```
324256
325257## Relaciones de tabla principal
326258
327259   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.
328260
329261   Cuando hay dos tablas relacionadas, por ejemplo:
330262
331263` [`**`clientes`**`]`\
332264` Id       <----\`\
333265` Nombre        |`\
334266` Telefono      |`\
335267` Direccion     |`\
336268`               |  ClienteID en facturas hace referencia a un campo primario de clientes`\
337269` [`**`facturas`**`]    |`\
338270` Id            |`\
339271` Importe       |`\
340272` ClienteID   --\---|  * Campo indexado como "idxclienteid"`
341273
342274   Si desea mostrar todas las facturas para un cliente determinado, la tabla detalle (facturas) puede sincronizarse con la tabla principal (clientes) automáticamente.
343275
344276   En el componente TDbf de facturas seleccione lo siguiente:
345277
346278``` pascal
347279 InvDbf.IndexName := 'idxclienteid'; // campo que se emparejará con el campo ID de la tabla clientes
348280 InvDbf.MasterSource := dsClientes; // fuente de datos que se enlaza al componente TDbf de clientes
349281 InvDbf.MasterFields := 'Id'; // campo en la tabla clientes que emparejamos con nuestro índice
350282```
351283
352284## Cómo filtrar las Fechas vacías
353285
354286   Voy a mostrar aquí como podemos filtrar las fechas en blanco con el componente de Lazarus TDbf.
355287
356288   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.
357289
358290   La forma más sencilla de hacerlo es utilizando el controlador de eventos OnFilterRecord y poner el siguiente código:
359291
360292``` pascal
361293 if not dfb1.FieldByName('DT_ENCERRA').IsNull then Accept := False;
362294```
363295
364296   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.
365297
366298   También es necesario poner la propiedad Dbf1.Filtered a True, pero fuera de este evento.
367299
368300``` pascal
369301 dfb1.Filtered := True;
370302```
371303
372304## Cómo filtrar un valor con TDbf
373305
374306   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"
375307
376308   Tenemos dos maneras de filtrar. La primera sería la de utilizar el siguiente código:
377309
378310``` pascal
379311 Dbf1.filter:= 'product_no "=" B019 "';
380312```
381313
382314   Resulta que esto funciona muy bien con varios componentes, pero no funciona con LazReport.
383315
384316   Para resolver el problema con LazReport puede utilizar el controlador de eventos OnFilterRecord y utilizar el siguiente código:
385317
386318``` pascal
387319 Accept:= Copy(Trim(Dbf1.FieldByName('product_no').AsString),1,4)='B019';
388320```
389321
390322   También es necesario poner la propiedad Dbf1.Filtered a True, pero fuera de este evento.
391323
392324   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
393325
394326## Programa de ejemplo - navegador DB
395327
396328   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
397329
398330` `[`tony.maro.net`](http://tony.maro.net/mod.php?mod=downloads&op=showcat&id=3&level=1)
399331
400332## See also
401333
402334- [[Example: TDbf (creating table and indexes, selecting of index)]]
403335
404336## A tener en cuenta
405337
406338   Actualmente no se soporta la integridad referencial, ni los archivos .db encriptados internamente.
407339
408340- Traducido por Usuario: Mgsalvador
409341- Normalización de estilo y formato, y algún añadido menor, por iskraelectrica (jldc). 11 de junio de 2008.
410342
411343---
412344*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).*
413345Category: Castellano
414346Category: Español

Back to history