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:
Volver al índice de las colaboraciones sobre el manejo de dBase desde Visual Basic