Las Colaboraciones sobre el manejo de

Bases de datos dBase desde Visual Basic

 

Colaboración de: Jose Luis Soler <teodoro@arrakis.es>
Publicado el 5/Dic/98

Otra colaboración publicada el día 21/Dic/98


Amigo Guille:

Te envío esta pequeña colaboración que trata sobre esa nueva sección que pretendes abrir sobre manejo de Bases de Datos dBase.

La presente colaboración versa sobre el manejo de esas Bases de Datos sin utilizar y utilizando el control DATA.

Expongo el código necesario para abrir una Base de Datos, abrir una tabla y crear un índice para acceder, a través del mismo, a los registros de esa tabla.

Añado además un procedimiento genérico,(Sub), para importar datos de dBase a Access, campo a campo.

Mi recomendación, fruto de la experiencia, es que se utilicen esas Bases de Datos, sólo a efectos de importar datos de aplicaciones de D.O.S., pues Access da mucho más juego que el viejo modelo xBase.

La Base de Datos nativa de VB es Access y todo lo que sea salirse de ahí, es un poco "mear fuera del tiesto".

Aquí están los ejemplos:

 

Declarar variables en el módulo principal, se llame como se llame.

'Base de Datos para ClipperPublic dBASEJet As ObjectPublic TabLec as Object

'Variables para crear índices NDXPublic TablaDef As Object

Public IndiceNDX As Object

Public CampoX As Object

---------------------------------------------------------------------------

'Abre base de datos dBASE externa.Set dBASEJet = OpenDatabase("C:\MIAPP", False, False, "dBASE III;")En este ejemplo se muestra que para abrir una Base de Datos dBase no hay que darle al Motor DAO el nombre de la misma, sino la vía de acceso dónde deberá buscarla.

----------------------------------------------------------------------------El Motor DAO ofrece compatibilidad con dBase III y por lo tanto maneja los vetustos índices NDX, por consiguiente, los usuarios de Clipper, entre los que me cuento, no podemos utilizar los habituales NTX.

Según parece, (y esto me ha costado muchas cavilaciones), el Motor DAO, no puede trabajar adecuadamente con el índice de una Base de Datos DBF, cuyo nombre coincida con una tabla de una Base de Datos Access, al mismo tiempo.

El susodicho Motor se hace con cierto órgano un lío, al tener en su lista de tablas (aunque de diferente motor), dos con el mismo nombre.

Si se pretende dar el mismo nombre de las tablas dBase , por afinidad, a las tablas de Access, entonces se plantea un problema: que es que no funciona.

Para evitar confusiones del Motor, se recurre a sacar una copia del fichero DBF y trabajar con la copia. A la copia se le da un nombre genérico que en este caso es "FELON" en honor a Tio Billy.

 

If ExisteArchivo("C:\MIAPP\FICHERO1.DBF") Then

FileCopy "C:\MIAPP\FICHERO1.DBF", "C:\MIAPP\FELON.DBF"

End If

If ExisteArchivo("C:\MIAPP\FELON.NDX") Then

Kill "C:\MIAPP\FELON.NDX"

End If

If ExisteArchivo("C:\MIAPP\FELON.INF") Then

Kill "C:\MIAPP\FELON.INF"

End If

Como se puede comprobar en el ejemplo, se elimina cualquier fichero previo de índice NDX e INF. Éste último lo crea el propio Motor DAO automáticamente al generar un índice NDX (ver Libros en Pantalla de VB5).

Por si alguien quiere saber más, la función ExisteArchivo fue obtenida en las páginas de El Guille, de manera que buscad y encontrareis.

------------------------------------------------------------------------------

En el siguiente ejemplo se crea un índice NDX

 

Set IndiceNDX = dBASEJet.TableDefs("FELON").CreateIndex("FELON.NDX")

Set CampoX = IndiceNDX.CreateField("CAMPO1")

IndiceNDX.Fields.Append CampoX

Set CampoX = IndiceNDX.CreateField("CAMPO2")

IndiceNDX.Fields.Append CampoX

dBASEJet.TableDefs("FELON").Indexes.Append IndiceNDX

Las claves pueden ser incluso compuestas, (como en el ejemplo), y podrán ser accedidas mediante el método "Seek", como si de una tabla de Access se tratara.

------------------------------------------------------------------------------

Se abre tabla de Clipper con el índice recién creado

 

Set TabLec = dBASEJet.OpenRecordset("FELON.DBF", dbOpenTable)

TabLec.Index = "FELON"

------------------------------------------------------------------------------

Lectura a través de índice. La variable "Clave", puede ser cualquier expresión. Ver sintaxis del método Seek.

 

TabElec.Seek "=", Clave

If Not TabElec.NoMatch Then 'Si se ha encontrado

 

End If

------------------------------------------------------------------------------

 

Este procedimiento se ha utilizado para importar datos de una aplicación desarrollada en Clipper a otra desarrollada en Visual Basic 5.0 y que constituye la versión para Windows de la antigua. Los usuarios finales tienen la ventaja de aprovechar íntegramente los datos.

El procedimiento importa datos de una Base de Datos xBase selectivamente, es decir importa sólo los datos de los campos cuyo nombre exista en ambas tablas. De esta forma la tabla de Access puede tener una estructura más extendida que la de origen. Además el orden de los campos, de una y otra tabla, no influye en el resultado final.

Se usan dos controles DATA. El primero con la propiedad Acceso: "DBASE III;",

El segundo como un Recordset de Access normal.

Originalmente el procedimiento usa una barra de progresión y una barra de estado, pero se han eliminado ambas, para mejorar la lectura del código.

La llamada al procedimiento será:

Call CImport(DATA1, DATA2, "MiTabla")

Se supone que "MiTabla" es una tabla que existe en ambos mundos, xBase y Access, pero no tiene por qué ser así necesariamente, cada cual se lo monta a su manera.Yo siempre uso la palabra clave "Call", precisamente para saber que es una "Call" cuando leo el código, pero no es imprescindible.

Obsérvese, que los parámetros DATA1 y DATA2, no van acompañados del preceptivo ".recordset"; éste se le añadirá en el interior del procedimiento.

Se usa el nombre de campo utilizando la nomenglatura:

data1.recordset("nombre_de_campo")

Obsérvese que se ha colocado una protección contra la entrada de NULL en los campos numéricos y alfanuméricos. El Motor DAO tiene la fea costumbre de meter NULL en los campos de datos de destino, cuando en el campo de la tabla dBase origen hay ceros o blancos.Public Sub CImport(DataOrig As Object, DataDest As Object, Tabla As String) DataOrig.RecordSource = Tabla

DataOrig.Refresh

 

DataDest.RecordSource = Tabla

DataDest.Refresh

 

'Se importan datos

Do While Not DataOrig.Recordset.EOF

 

DataDest.Recordset.AddNew

 

For i = 0 To DataOrig.Recordset.Fields.Count - 1

On Error Resume Next

Select Case DataOrig.Recordset(i).Type

Case dbNumeric 'Cuando el campo de destino es un Autonumérico, no hace nada. If Not DataDest.Recordset(DataOrig.Recordset.Fields(i).Name).Type = dbLong Then

DataDest.Recordset(DataOrig.Recordset.Fields(i).Name) = 0 + DataOrig.Recordset(i)

End If

 

Case dbText

DataDest.Recordset(DataOrig.Recordset.Fields(i).Name) = "" & DataOrig.Recordset(i)

 

Case Else

DataDest.Recordset(DataOrig.Recordset.Fields(i).Name) = DataOrig.Recordset(i)

 

End Select

Next i

 

DataDest.Recordset.Update

 

DataOrig.Recordset.MoveNext

Loop

 

End Sub

 

NOTA: Como un programa en Visual Basic, siempre está bajo sospecha, si alguien encuentra alguna pega, que me lo diga en la siguiente dirección:

Teodoro@arrakis.es

 


Volver al índice de las colaboraciones sobre el manejo de dBase desde Visual Basic

el_guille.jpg (3322 bytes)