Sie sind auf Seite 1von 56

Compactar una base de datos, usando cdigo VB (27/Feb)

Este es el cdigo que uso para compactar las bases de datos. Cosa que suelo hacer
bastante a menudo, sobre todo en las que uso en la empresa, que cambian a
diario.
Por aquello de la seguridad, mantengo dos copias: la anterior y la ltima. Ms vale
prevenir. Nunca se sabe cuando se cortar la luz o se quedar colgado el equipo...
as que, me curo en salud.

'Cerrar la base (esto slo si la tienes abierta...)


Db.Close
'Liberar memoria y "desligarla"
Set Db = Nothing
'
'Tomar el nombre sin la extensin
sTmp = ""
i = InStr(NombreBase, ".")
If i Then
p = i - 1
Else
p = Len(NombreBase)
End If
sTmp = Left$(NombreBase, p)
'Buscar \, para tomar el directorio (path)
For i = p To 1 Step -1
If Mid$(NombreBase, i, 1) = "\" Then
sTmp = Left$(NombreBase, i)
Exit For
End If
Next
If Right$(sTmp, 1) <> "\" Then
sTmp = sTmp & "\"
End If

'Todo este proceso es para estar seguro de que se quede una copia
'en caso de que falle la compactacin...
dBaseTmp = sTmp & "~dBase2.mdb"
If Len(Dir$(dBaseTmp)) Then Kill dBaseTmp
If Len(Dir$(sTmp & "~dBase1.mdb")) Then Kill sTmp & "~dBase1.mdb"

'Esta es la madre del cordero, se pueden usar otras "versiones", es


cuestin de adecuarte.
CompactDatabase NombreBase, dBaseTmp, dbLangSpanish, dbVersion20

'Guardar una copia de como estaba antes


Name NombreBase As sTmp & "~dBase1.mdb"
'Esta es la base ya compactada, as que asignar el nombre
Name dBaseTmp As NombreBase
'Borrar los ficheros LDB
If Len(Dir$(sTmp & "*.ldb")) Then Kill sTmp & "*.ldb"
Bases de datos ADO con VB 6
(ADO = ActiveX Data Objects)

Contenido: (los ms recientes arriba)

1. Usar base de datos de SQL Server 2005 desde Visual Basic 6.0 (26/May/07)
2. Indicar el path de una base de datos usando el control data (18/Sep/04)
Ejemplo paso a paso de cmo usar un control data y DataGrid
3. Conectar a una base de datos de SQL Server con VB6 (Abrir una tabla y
mostrar los campos/columnas) (10/Sep/04)
4. Instrucciones SQL para seleccionar, actualizar, eliminar datos, etc.
(02/May/04)
5. Acceder a una base de datos de Access desde una pgina ASPX usando ADO
(02/Ene/04)
6. Comprobar si un Recordset est vaco (18/Dic/03)
7. Cmo manejar fechas en consultas, adems de otros ejemplos, tanto para
ADO como para DAO (09/Jul/03)
8. Acceder a una base de datos ADO sin el data control (Curso Bsico entrega
41) (09/Jul/03)
9. Ms consejos para mejorar el acceso a datos, aportados por Norman A.
Armas (25/Oct/01)
10. Compactar y cambiar el password de una base de datos (24/Oct/01)
11. Compactar una base de datos con password (24/Oct/01)
12. Consejos para mejorar el acceso a los datos (04/Oct/01)
13. Cdigo de ejemplo de compactar, crear base y crear tablas con ADO
(29/Sep/01)
14. Compactar una base de datos usando ADO y VB (29/Sep/01)
15. Crear una tabla en una base de datos, usando ADO y VB (29/Sep/01)
Leer nota del 04/Oct/01 y 27/Dic/02
16. Crear una base de datos con ADO, usando cdigo de VB (29/Sep/01)
17. Abrir una base de datos ADO con contrasea (05/Sep/01)
18. Manipular imgenes usando ADO (con datacontrol) (11/Jul/01)
19. Usar el ADO DataControl (Curso Bsico entrega 36) (14/Feb/01)
20. Acceder a bases de datos usando ADO (sin el data control) (31/Ago/99)
21. Acceder a bases de Access 2000 (usando el datacontrol de ADO)
(31/Ago/99)

Comprobar si un Recordset est vaco (18/Dic/2003)

Como sabrs, se puede usar .BOF o .EOF para comprobar si est en los lmites del
recordset.
BOF devolver True si el "puntero" est antes del primer registro, por otro lado EOF
nos indicar si ese puntero est despus del ltimo registro, pero la recomendacin
para comprobar si realmente est vaco es que se cumplan esas dos condiciones:
que tanto BOF como EOF sean True, por tanto podremos hacer una comprobacin
como esta:

With rst
If .EOF And .BOF Then
lblData.Caption = "No hay ningn registro activo"
.MoveFirst
Else
Text1(0) = .Fields("Au_ID")
' Por si el dato es nulo, aadirle una cadena vacia
Text1(1) = .Fields("Author") & ""
Text1(2) = .Fields("Year Born") & ""
End If
End With

Aunque tambin se podra comprobar que .BOF Or .EOF sean True, es decir, hacer
algo como esto:
If .EOF Or .BOF Then
pero ya te digo que lo ms correcto es usar AND, al menos eso es lo que he ledo
en la documentacin de ADO.
Espero que esta pequea aclaracin te pueda ser de utilidad.

Nos vemos.
Guillermo

Ms consejos para mejorar el acceso a los datos, aportados por Norman


A. Armas (25/Oct/2001)

Algunos consejos para mejorar el acceso a datos:

-Abrir el recordset o el Data slo en el momento necesario, NUNCA abrir los


recordsets o datas en el momento de cargar la forma (salvo en casos en que no
queda mas remedio)
Por ejemplo si tienes un formulario con varios combos no es necesario llenarlos en
el momento de cargar la forma, una buena costumbre es cargarlos en el momento
en que el usuario haga click en el combo.

-No cargar mas de 100 records como mximo en un grid o lista, si es necesario
mostrar ms, jugar con el SELECT TOP y el WHERE para mostrar los datos en
bloques de a 100 (o menos de 100)

Compactar una base de datos con password y cambiarlo. (24/Oct/2001)

Para compactar una base de datos con password (o contrasea), se hace


prcticamente igual que en una base de datos sin password, lo nico que hay que
hacer es aadirle la cadena correspondiente al cdigo mostrado anteriormente.

Este sera el cdigo para compactar una base de datos con password:
je.CompactDatabase "Data Source=" & txtNombreBase.Text & ";" & _
"Jet OLEDB:Database Password=PasswordAnterior", _
"Data Source=" & sDBTmp & ";"

Y este otro para cambiarle el password actual y ponerle otro:

je.CompactDatabase "Data Source=" & txtNombreBase.Text & ";" & _


"Jet OLEDB:Database Password=PasswordAnterior", _
"Data Source=" & sDBTmp & ";" & _
"Jet OLEDB:Database Password=NuevoPassword"

Consejos para mejorar el acceso a los datos (04/Oct/2001)

Esta seccin te mostrar algunos consejos con los cuales podrs mejorar el acceso
a los datos, el primero de ellos, con el que inauguramos esta seccin es de Norman
A. Armas, si crees que tienes alguno que se pueda aadir, me lo mandas. Gracias.

1. Consejo aportado por Norman A. Armas, publicado el 04/Oct/2001

Nunca usar SELECT * FROM TuTabla., especifica siempre que campos son
los que se quieren seleccionar en ese momento y que record o records

Cdigo de ejemplo de compacta, crear base y crear tablas


con ADO (29/Sep/2001)

Este es el link al cdigo completo de los tres casos indicados:

Cmo crear una base de datos con ADO,


Cmo crear tablas y
Cmo compactar una base de datos.

En la pgina se muestra el cdigo completo, el cual puedes bajar mediante un


fichero comprimido.

Que lo disfrutes!
Guillermo

Compactar una base de datos usando ADO y VB (29/Sep/2001)

Para compactar bases de datos usando ADO, tienes que crear una referencia a
Microsoft Jet and Replication Objects 2.6 Library (JRO).

Nota: JRO slo se puede usar con bases de datos Microsoft JET
Aqu tienes el cdigo necesario para compactar una base de datos:

Private Sub cmdCompactar_Click()


' Compactar una base de datos con ADO
Dim sDBTmp As String
Dim je As JRO.JetEngine
'
On Error GoTo ErrCompactar
'
Set je = New JRO.JetEngine
'
' Crear un nombre "medio" aleatorio
sDBTmp = "DBT_" & Format$(Minute(Now), "00") & Format$
(Second(Now), "00") & ".mdb"
' Asegurarnos de que no existe una base con el nombre temporal
If Len(Dir$(sDBTmp)) Then
Kill sDBTmp
End If
'
lblInfo.Caption = " Compactando la base de datos..."
lblInfo.Refresh
'
' Compactar la base de datos
je.CompactDatabase "Data Source=" & txtNombreBase.Text & ";", _
"Data Source=" & sDBTmp & ";"
'
' Eliminar la base de datos original
Kill txtNombreBase.Text
'
' Renombrar la base temporal con el original
Name sDBTmp As txtNombreBase.Text
'
lblInfo.Caption = " Base de datos compactada."
lblInfo.Refresh
'
Exit Sub
'
ErrCompactar:
' Mostrar el mensaje de error
MsgBox "Error al compactar la base de datos:" & vbCrLf & _
Err.Number & " " & Err.Description, _
vbExclamation, "Error al compactar la base de datos"
Err.Clear
lblInfo.Caption = " *** Error al compactar la base de datos ***"
lblInfo.Refresh
End Sub

Para ms informacin: Compacting a Database (MDAC Technical Articles)

Crear una tabla en una base de datos usando ADO y VB


(29/Sep/2001)

Hay que crear una referencia a ADOX (ver Cmo crear una base de datos con
ADO).
El cdigo, casi simplificado, sera algo como esto:
Dim cat As ADOX.Catalog
Dim tbl As ADOX.Table
'
Set cat = New ADOX.Catalog
Set tbl = New ADOX.Table
'
' Abrir el catlogo
cat.ActiveConnection = _
"Provider=" & cboProvider.Text & ";" & _
"Data Source=" & txtNombreBase.Text & ";"
'
' Crear la nueva tabla
With tbl
.Name = txtNombreTabla.Text
' Crear los campos y aadirlos a la tabla.
' Esto hay que hacerlo antes de aadir la tabla a la coleccin de
tablas
.Columns.Append "ID", adInteger
' Dependiendo del tipo de proveedor, los datos de cadena sern de
un tipo u otro
If cboProvider.Text = "Microsoft.Jet.OLEDB.3.51" Then
' Para Access 97
.Columns.Append "Nombre", adVarChar, 50 ' Una cadena
de 50 caracteres
.Columns.Append "email", adVarChar, 100
.Columns.Append "Telefono", adVarChar
.Columns.Append "Observaciones", adLongVarChar ' Una cadena
larga, (Memo)
Else
' Para Access 2000
.Columns.Append "Nombre", adVarWChar, 50 ' Una cadena
de 50 caracteres
.Columns.Append "email", adVarWChar, 100
.Columns.Append "Telefono", adVarWChar
.Columns.Append "Observaciones", adLongVarWChar ' Una cadena
larga, (Memo)
End If
.Columns("Nombre").Attributes = adColNullable ' Permite
contener nulos
.Columns("email").Attributes = adColNullable
.Columns("Telefono").Attributes = adColNullable
.Columns("Observaciones").Attributes = adColNullable
End With
'
' Aadir la nueva tabla a la base de datos
cat.Tables.Append tbl
'
Set tbl = Nothing
Set cat = Nothing

En este ejemplo, tenemos que tener asignadas las variables sProvider (el
proveedor), sNombreBase (el nombre y path de la base de datos) y
sNombreTabla para el nombre de la tabla.
Para una base de datos del tipo Access 97, sProvider =
"Microsoft.Jet.OLEDB.3.51"
Para una base de datos del tipo Access 2000, sProvider =
"Microsoft.Jet.OLEDB.4.0"

Nota:
Los tipos de datos de cadena adVarChar y adLongVarChar son los que
aceptan las tablas para Access 97,
las tablas de Access 2000 se deben usar los del tipo adVarWChar y
adLongWChar.

Nota 2:
Los campos se aaden a la tabla por orden alfabtico, independientemente
del orden en el que se han aadido.
Nota del 27/Dic/02:
Esto slo ocurre si se usa el JET 3.51, con JET 4.0 los crea en el orden
indicado al crearlos.
Gracias Jose Angel Calvo.

Si alguien sabe cmo hacer que no se clasifiquen, (en JET 3.51), por favor que me
lo diga, gracias

Para ms informacin: Defining and Retrieving a Databases Schema (MDAC


Technical Articles)

Crear una base de datos con ADO, usando cdigo de VB


(29/Sep/2001)

Para poder crear una base de datos, desde Visual Basic, usando ADO (ActiveX Data
Objects), tenemos que crear en nuestro proyecto una referencia a: Microsoft ADO
Ext. 2.6 for DDL and Security (msadox.dll), y crear un objeto del tipo Catalog.

Nota: Esta referencia es para la versin 2.6 de ADO, por tanto puede ser que, si la
versin que tienes instalada es otra, en lugar de 2.6 aparezca otra numeracin.
ADOX slo est disponible a partir de la versin 2.1 de ADO.

Veamos, de forma simple, cmo crear una base de datos:

Dim cat As ADOX.Catalog


Set cat = New ADOX.Catalog
'
' Crear la base de datos
cat.Create "Provider=" & sProvider & ";" & _
"Data Source=" & sNombreBase & ";"

En este ejemplo, tenemos que tener asignadas las variables sProvider (el
proveedor) y sNombreBase (el nombre y path de la base de datos).
Para una base de datos del tipo Access 97, sProvider =
"Microsoft.Jet.OLEDB.3.51"
Para una base de datos del tipo Access 2000, sProvider =
"Microsoft.Jet.OLEDB.4.0"

Nota: Si la base de datos ya existe, dar un error.

Para ms informacin: Defining and Retrieving a Databases Schema (MDAC


Technical Articles)
Abrir una base de datos ADO con contrasea (05/Sep/2001)

Para abrir una base de datos ADO con contrasea, podemos hacerlo al crear la
conexin.
He probado varias de las formas que se indican en la ayuda, pero la nica que me
ha funcionado es la que aqu te muestro... as que, si a ti te funciona de otra forma,
pues... eso, que uses la que mejor te parezca... je, je.

Este cdigo es para bases de datos del tipo Access 97, en caso de que quieras usar
una de Access 2000, hay que cambiar el provider por:
Provider=Microsoft.Jet.OLEDB.4.0;

Set Cnn = New ADODB.Connection

Cnn.Open "Provider=Microsoft.Jet.OLEDB.3.51; " & _


"Data Source=" & sBase & ";" & _
"Jet OLEDB:Database Password=laclave"

En este ejemplo, asumimos que tenemos una variable llamada Cnn del tipo
ADODB.Connection y otra, sBase del tipo String, a la que se ha asignado el
nombre de la base de datos a la que queremos acceder.

Indicar el path de la base de datos


usando un data control
Ejemplos con ADO y DAO
En este ejemplo vamos a ver cmo indicar el path en el que se encuentra la base
de datos, pero lo haremos en tiempo de ejecucin, es decir cuando la aplicacin
est ejecutndose.

Seguramente si lees el prrafo anterio en la que te digo lo que te voy a explicar, no


te parecer nada del otro mundo, ya que eso se ha dicho y explicado en varias
ocasiones. Pero como resulta que an hay mucha gente que usa los controles
"enlazados" y los data control y los asigna en modo de diseo... pues... para ellos
seguros que le ir bien esta "historia" que voy a contar.

Seguramente cuando te explique la situacin en la que puede ser til saber lo que
te voy a contar, cambies de opinin.

Los precedentes (la situacin)


Empecemos el ejemplo usando DAO, ya que en VB6 puede que haya ms gente
(sobre todo los que empiezan) que usen el DataControl que est de forma
predeterminada en la barra de herramientas.
Usando controles enlazados DAO
Estos son los pasos que debemos seguir para poder hacer el proyecto de prueba:

1- Creamos un nuevo proyecto de Visual Basic 6 (cuando digo VB6, tambin se


puede aplicar a VB5 e incluso a VB4), aadimos el control Data, que est en el
Toolbox y se crear un objeto en el formulario llamado Data1.

2- Ahora le asignamos la base de datos que usaremos, lo ms usual es que el


usuario seleccione el DataControl, se vaya a la ventana de propiedades, seleccione
la propiedad DatabaseName y busque una base de datos (pulsando en el botn
con los tres puntos suspensivos).

3- Una vez que hemos indicado el nombre de la base de datos, tendremos que
indicarle la tabla a la que queremos acceder. Para ello tendremos que seleccionar la
propiedad RecordSource y elegir de la lista desplegable la tabla a usar.

Estos tres pasos sern los que nos permitan acceder a una base de datos desde
nuestro proyecto de VB6.

Nota:
En el zip con el cdigo completo he incluido una base de datos de
prueba.
Copia esa base de datos (db2000.mdb) en el mismo directorio del
proyecto y sala para asignarla al control data.
De esa forma ser ms fcil seguir las indicaciones de este
artculo.

Ahora vamos a aadir un control DataGrid, de forma que podamos manejar de


forma simple los datos de nuestra base de datos y de la tabla seleccionada.

Para aadir un DataGrid tendremos que hacer lo siguiente:

1- En el men Proyecto (Project) seleccionamos Componentes (Components...),


nos mostrar un cuadro de dilogo con los controles ActiveX que podemos aadir a
nuestra aplicacin. De ese cuadro de dilogo seleccionaremos Microsoft Data
Bound Grid Control (tambin se indicar la versin del VB y el SP que se est
usando, en mi caso sera 5.0 (SP3)).
Esto aadir a la barra de herramientas el control DataGrid y haciendo doble-click
en l, lo aadiremos al formulario.

2- Seleccionamos el nuevo control que tenemos en el formulario, lo cambiamos de


tamao y posicin y ahora le indicaremos de dnde obtendr los datos. Para ello
nos vamos a la ventana de propiedades (el DataGrid debe estar seleccionado) y
buscamos la propiedad DataSource, de la lista desplegable seleccionamos el
DataControl que usaremos para obtener los datos. En este ejemplo ser Data1 (que
debera ser el nico que se muestre).
Hecho todo esto, podemos pulsar F5 para ejecutar la aplicacin y veremos que el
DataGrid se llena con los datos que tenga la tabla de la base de datos que le
indicamos al control Data.

Para probar que todo esto funciona como debe vamos a compilar el proyecto (crear
el ejecutable) y veamos si siempre funciona.

Para compilar el proyecto y crear el ejecutable, selecciona la opcin Make del men
File (si tienes el VB en espaol, seguramente tendr otros nombres).

Ahora ve al directorio en el que est el EXE y ejectalo (haz doble-click en l).


Si has seguido los pasos de forma correcta, debera mostrarte lo mismo que cuando
pulsaste F5 desde el IDE (entorno de desarrollo) de VB.

Haciendo que falle todo esto...


Para probar que no siempre funcionar, vamos a hacer ahora lo siguiente:

1- Asegrate de que has cerrado la aplicacin. Cierra tambin el VB6.

2- Crea un directorio en otro sitio.

3- Corta el ejecutable y la base de datos (se supone que la base de datos estaba en
el mismo directorio del proyecto, tal como se comenta en la nota)

4- Pgalos en el nuevo directorio.

5- Abre el ejecutable (ejectalo, doble-click, ya sabes...)

Al ejecutarse la aplicacin, nos indicar que no se puede encontrar la base de datos


y nos mostrar el path en el que estaba anteriormente.
La aplicacin se abrir, pero en el DataGrid no habr nada... ya que no se ha
podido abrir la base de datos y por tanto no se pueden "ver" esos datos.

La solucin:
Para que la aplicacin vuelva a funcionar, tendramos que volver a copiar la base de
datos en el directorio en el que estaba (el del proyecto).
Comprubalo moviendo (cortar y pegar) la base de datos al directorio del proyecto.

El problema (colateral):
Pero... imagnate que lo que quieres hacer, es distribuir esta aplicacin y la base de
datos.
Como hemos podido comprobar, la nica forma de que funcione es creando un
directorio que se encuentre en el mismo "camino" que el que nosotros tenemos en
nuestro equipo.

Por ejemplo, en mi caso el directorio del proyecto es:


E:\gsCodigo\VBpruebas\Bases de datos\indicar el path de una base de
datos usando Data Control\conDAO
Que pasa si el cliente no tiene un disco E? O, peor an, que pasa si el disco E del
cliente es un CD-ROM?
Pues que no funcionar el programa. Y en caso de que si tenga un disco E,
tendremos que crear esos directorios para que todo funcione.

Cual es la mejor solucin?


Creo que sera mejor que el programa pudiera funcionar si tanto el ejecutable y la
base de datos estn en el mismo directorio, y lo ms importante es: sea cual sea
ese directorio.
Es decir, nos dar igual si el disco en el que est la base y el exe es el disco C, el E
o el X, adems de que el directorio puede ser cualquiera...

Cmo podemos hacerlo?


Indicndole al programa dnde est la base de datos.

Si la base de datos est en el mismo directorio que el ejecutable, podemos hacer lo


siguiente:

Private Sub Form_Load()


Data1.DatabaseName = App.Path & "\db2000.mdb"
End Sub

De esta forma le indicamos al control data dnde localizar la base de datos y todo
volver a funcionar de forma satisfactoria.
En este cdigo, indicamos que el directorio en el que se encuentra la base de datos
es el mismo directorio desde el que se est ejecutando la aplicacin.
En el caso de que la base de datos est en otro directorio, simplemente tenemos
que usar ese directorio a la propiedad DatabaseName del data control. Por ejemplo
si leemos el path de un fichero de configuracin (INI) o desde el registro de
Windows usando GetSetting, etc.

Nota:
Si tienes varias tablas en la misma base de datos y tambin tienes
varios controles data y a la vez varios controles DataGrid
enlazados con esos controles data, lo nico que tendras que hacer
es asignar a todos los controles data el path correcto de la base de
datos.
El resto de propiedades no hace falta cambiarlas ya que seguirn
siendo los mismos valores.

Este primer ejemplo es para usar con acceso a datos DAO.


Ahora veamos cmo hacer lo mismo pero con controles ADO.

Usando controles enlazados ADO


Tal como vamos a comprobar, lo que vamos a hacer en esta ocasin, (usando
ADO), es casi lo mismo que en el caso de DAO, lo nico que cambiar sern los
controles que vamos a usar, adems de que el control data de ADO no tiene las
mismas propiedades que el de DAO.
As que, veamos paso a paso cmo crear el proyecto, agregar los controles,
enlazarlos con la base de datos, etc., etc.

1- Creamos un nuevo proyecto de VB6

2- En el men Proyecto (Project) seleccionamos Controles (Controls...), en el


cuadro de dilogo tenemos que seleccionar el control data de ADO, el cual (en mi
caso) tiene el nombre Microsoft ADO Data Control 6.0 (SP4) (OLEDB).

3- Repetimos el paso anterior, pero en esta ocasin seleccionamos Microsoft


DataGrid Control 6.0 (SP5) (OLEDB).

4- Con los dos pasos anteriores tendremos en el Toolbox dos nuevos controles,
hacemos doble-click en cada uno de ellos para agregarlos al formulario.

5- Seleccionamos el control data (Adodc1) para indicar la base de datos y la tabla


que vamos a usar. En la ventana de propiedades seleccionamos ConnectionString
y pulsamos en el botn con los tres puntos suspensivos para que se muestre el
asistente de conexin.

-De las tres opciones que nos muestra, seleccionamos la ltima: Use Connection
String, pulsamos en el botn Build... y se mostrar otro cuadro de dilogo.
-Seleccionamos la primera ficha (Provider) y de la lista de proveedores que muestra
seleccionamos Microsoft.Jet.OLEDB.4.0 (si no se muestra, es que no tienes ese
proveedor y la base de datos de ejemplo no te funcionar)
-Pulsa en Next>> para indicar el nombre de la base de datos, se mostrar la
segunda ficha (Connection).
-Escribe el nombre de la base de datos en la caja de texto que hay bajo 1. Select
or enter a database name o pulsa en el botn con los tres puntos para
seleccionar una base (recuerda usar la base de datos que acompaa al cdigo la
cual debe estar en el mismo directorio del proyecto)
-No escribas nada en usuario y password, djalos con los valores predeterminados,
ya que usaremos autentificacin de Windows para abrir la base.
-Para comprobar que se puede abrir la base de datos, pulsa en el botn Test
Connection y si todo va bien, te dir que la conexin ha funcionado correctamente.

6- Ahora vamos a indicar que tabla queremos usar. Asegrate que el control data
est seleccionado y en la ventana de propiedades selecciona RecordSource y
pulsa en el botn con los tres puntos para que se muestre el asistente.

-De la primera lista desplegable selecciona 2- adCmdTable.


-De la segunda lista selecciona la tabla que quieres usar (en nuestro caso ser
Table1).

7- Ya tenemos asignado el control data para que sepa que base de datos y que
tabla debe usar.

8- Ahora vamos a indicarle al DataGrid que use el control data como fuente de
datos, por tanto selecciona el DataGrid y en la ventana de propiedades selecciona
la propiedad DataSource y de la lista desplegable tienes que seleccionar el control
data que tiene la conexin a la tabla que queremos usar, en nuestro caso Adodc1.
9- Pulsa F5 para probar que todo funciona bien.

Con todos estos pasos tendremos una aplicacin similar al del ejemplo anterior y
adems, con los mismos problemas, es decir, la base de datos que usar el
ejecutable (el cual no tiene ni una lnea de cdigo) ser la que hemos indicado en el
control data.
Por tanto para que funcione, la base de datos tiene que estar en el path indicado en
tiempo de diseo.
Si hacemos la misma prueba que antes de compilar la aplicacin y mover el
ejecutable y la base de datos a un directorio diferente, no funcionar.

La primera opcin de ADO para que funcione:

Para que funcione debemos indicarle al data control dnde se encuentra la base de
datos, pero resulta que el control data ADO no tiene una propiedad DatabaseName
como su primo el data control DAO.
En el control ADO tenemos que usar la cadena de conexin (como en las bases de
datos de SQL Server), por tanto debemos modificar dicha cadena de conexin para
que apunte a la base de datos adecuada.
Aqu tenemos el cdigo a aadir al proyecto para que todo funcione correctamente:

Private Sub Form_Load()


' Aqu se puede indicar el path de la base de datos:
Adodc1.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & App.Path &
"\db2000.mdb;" & _
"Persist Security Info=False"

Adodc1.Refresh
Set DataGrid1.DataSource = Adodc1.Recordset
End Sub

En el caso de ADO, adems de indicarle el path correcto debemos usar este cdigo
adicional:
Adodc1.Refresh para que se carguen los datos desde la base de datos.
Set DataGrid1.DataSource = Adodc1.Recordset porque debemos asignar los datos
que el control data ha cargado. Esto ltimo no es "estrictamente" necesario, pero si
no lo hacemos el contenido de la base de datos no ser el correcto.
Por qu este cdigo extra?
Por la sencilla razn de que el control data intentar obtener los datos de la base de
datos y despus rellenar el DataGrid.

Adems, en el caso del control data de ADO si la base de datos no est en el sitio
adecuado, se mostrar un mensaje de aviso de que la base de datos no se ha
encontrado, aunque despus cargar bien los datos y funcionar correctamente.

La segunda opcin de ADO para que funcione


Por tanto es preferible no asignar en tiempo de diseo la cadena de conexin a la
base de datos, ni tampoco asignar el RecordSource, en este caso, el cdigo a usar
ser el siguiente:

Private Sub Form_Load()


' Aqu se puede indicar el path de la base de datos:
Adodc1.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & App.Path &
"\db2000.mdb;" & _
"Persist Security Info=False"

Adodc1.RecordSource = "Table1"
Adodc1.Refresh
Set DataGrid1.DataSource = Adodc1.Recordset
End Sub

En este caso, lo que hacemos es indicar tambin la tabla de la que se extraern los
datos.

La tercera opcin de ADO para que funcione

Otra opcin es no indicar el path de la base de datos, sino slo el nombre de la


base, de esta forma, la base se buscar en el mismo path del ejecutable.
Con lo cual la cadena de conexin podra quedar de la siguiente forma:

Provider=Microsoft.Jet.OLEDB.4.0;Data Source=db2000.mdb;Persist Security


Info=False

Y ya no ser necesario usar ningn cdigo en el evento Load del formulario.

Bueno, confo en que con estas explicaciones, (las cuales he preferido indicarlas en
plan "paso a paso para principiantes" porque, casi con seguridad, todo esto lo
necesitarn los que no tengan mucho manejo con el uso de bases de datos...), te
quede ms claro porqu algunas veces las aplicaciones que usan los controles
enlazados no funcionan al cambiar el path en el que se encuentra la base de datos.

Que lo disfrutes!

Nos vemos.
Guillermo

El cdigo fuente de los ejemplos y la base de datos:


nombreBase_datacontrolADOyDAO.zip 42 KB
Recuerda copiar la base de datos en los directorios del proyecto.
Cmo manejar fechas en
consultas
(adems de otras cosillas ms...)
Ejemplos con ADO y DAO

Lo que vamos a ver aqu es algo bastante simple, ser el uso de una fecha en una
consulta SQL.

Nota:
Recuerda (o lo aclaro) que una consulta SQL no es una consulta hecha a una base
de datos del tipo SQL, sino es una cadena "SELECT" que se usa para obtener los
datos de una base de datos, sea del tipo que sea.

El problema con las fechas es que no siempre funciona como nos gustara, sobre
todo si en la consulta se indica ms de una fecha o varias condiciones sobre una
misma fecha.
Por regla general, (al menos yo), usbamos la funcin DateValue() para convertir
la fecha en un valor de slo fecha, (no, no es que me est liando, bueno, un poco
s, pero es que normalmente un tipo de datos fecha (Date) suele incluir la fecha y
la hora y con DateValue nos quedamos slo con la fecha), por la sencilla razn de
que esa funcin la podemos usar tanto "dentro" de la cadena SQL como fuera de
ella para convertir el valor de una variable en un dato de tipo fecha, dentr ode un
rato veremos un ejemplo.
Pero esto no siempre funciona, por tanto lo ms recomendable es que los datos de
fechas contenidos en variables, que vayamos a usar en una consulta, la
convirtamos en un dato que no de problemas a confusin al motor de la base de
datos.
Hasta no hace mucho lo que yo haca (seguramente recomendado por alguien en
algn momento) es convertir la fecha en el formato "americano":
#mm/dd/yyyy#, es decir, poner primero el mes, despus el da y a continuacin
el ao. Pero esto no siempre funcionaba, incluso si cambiaba el carcter / por -
para que la fecha quedara #mm-dd-yyyy#.
Despus de mucho probar, la solucin que he encontrado es usar el formato de
fechas #yyyy/mm/dd#, es decir empezar desde atrs por el ao, el mes y el da
y todo esto siempre encerrado entre un par de almohadillas (#).

Para que me resulte ms fcil, me he creado una funcin que convierte una fecha
en el formato indicado, a esta funcin la he llamado FechaSQL y es la siguiente:

La funcin FechaSQL:

Public Function FechaSQL(ByVal vFecha As String) As String


' Funcin para convertir una fecha al formato mm/dd/yy
( 7/Ago/97)
' La fecha la convierte al formato: #yyyy/mm/dd#
(30/May/01)
'
On Local Error GoTo SQLDateValErr
'
If IsDate(vFecha) Then
' si es una fecha vlida, convertirla
FechaSQL = "#" & Format$(vFecha, "yyyy/mm/dd") & "#"
Else
' si no es una fecha vlida, devolverlo sin modificar
FechaSQL = vFecha
End If
'
Exit Function
'
SQLDateValErr:
' Si hay error, la fecha por defecto 1-Ene-1980
Err = 0
FechaSQL = "#1980/01/01#"
End Function

Esta funcin recibe una parmetro que ser una fecha vlida (o debera serlo),
debido a que es posible que el parmetro pasado a la funcin no sea una fecha
vlida, se comprueba mediante la funcin de Visual Basic IsDate(), si es una fecha
correcta, la devolvemos en el formato #yyyy/mm/dd#, en caso de que no sea
una fecha vlida, simplemente devolvemos la misma cadena que hemos recibido en
el parmetro.
Si se produjera un error, devolveramos una fecha ficticia.

Ahora veamos cmo haca yo antes las consultas.

Nota:
Si no quieres tragarte esta batallita, puedes pasar al cdigo "propuesto" usando la
funcin FechaSQL o bien pasar a ver el ejemplo prctico.

Supongamos que tenemos un campo de una tabla que se llama FechaTrmino


(con tilde en la e) y quera comprobar todos los datos entre la fecha actual (o la
indicada en la variable fechaActual) y un nmero de das despus, (el nmero de
das estar indicado en la variable cuantosDias), lo que hasta hace poco haca era
esto:

Dim s As String
Dim rs As Recordset
Dim dFin As Date
Dim fechaActual As Date
Dim cuantosDias As Long
'
fechaActual = Format$(txtFecha, "dd/mm/yyyy")
cuantosDias = txtDias
dFin = (fechaActual + cuantosDias)

' la cadena de la consulta SQL


s = "SELECT * FROM Tabla WHERE " & _
"DateValue([FechaTrmino]) >= " & DateValue(fechaActual) & _
" AND DateValue([FechaTrmino]) <= " & DateValue(dFin)
' realizar la consulta

' en DAO sera algo as:


' (se supone que Db es del tipo DataBase y ya est instanciada)
Set rs = Db.OpenRecordset(s, dbOpenForwardOnly)

' en ADO sera algo como esto:


' (se supone que cnn es del tipo ADODB.Connection y ya est
instanciada)
Set rs = New Recordset
rs.Open s, cnn, adOpenForwardOnly, adLockReadOnly
Pero esto no funciona.
Si quitamos la comparacin que hay detrs de AND si funciona, pero entonces nos
devolver todos los registros (filas) que sean igual o posterior a la fecha contenida
en fechaActual, por tanto tendramos que hacer posteriormente un bucle
comprobando que las fechas sean inferiores a la fecha indicada en dFin.

Suponiendo que la cadena de la consulta es:

s = "SELECT * FROM Tabla WHERE DateValue([FechaTrmino]) >= " &


DateValue(fechaActual)

El bucle que habra que hacer sera algo as:

With rs
Do While Not .EOF
' en ADO no indicar el campo dentro de corchetes!
If .Fields("[FechaTrmino]") <= DateValue(dFin) Then
'...
End If
.MoveNext
Loop
End With

Pero esto es trabajo doble... ya que...

Usando la funcin FechaSQL, podemos hacer la consulta de esta forma:

' la cadena de la consulta SQL, usando FechaSQL


s = "SELECT * FROM Tabla WHERE " & _
"[FechaTrmino] >= " & FechaSQL(fechaActual) & " AND
[FechaTrmino] <= " & FechaSQL(dFin)

Y slo devolver las filas que estn entre las dos fechas indicadas.

Si ests usando DAO debers tener en cuenta que para acceder al campo
FechaTrmino mediante Fields del recordset, tendrs que usar el nombre de ese
campo dentro de corchetes.
Si ests usando ADO no tendrs que usar los corchetes, si lo haces te dar error.

Nota:
Es posible que me haya estado complicando la vida, pero... as es como lo haca y
como lo hago ahora.
De todas formas, te aclaro que no soy ningn experto en bases de datos... as
que... es posible que haya mejores formas de hacer lo que te he comentado y lo
que te voy a mostrar, as que... no me regaes si sabes cmo hacerlo mejor,
simplemente comprtelo! (seguramente ya sabrs cmo...)

Un ejemplo prctico de todo lo dicho.


Ahora veremos un ejemplo completo de cmo poner todo esto en prctica.
En este ejemplo veremos estas cosillas:

Crear una base de datos.


Introducir automticamente unos campos (ID y FechaTrmino)
Saber / acceder a los campos de una tabla.
Aadir / eliminar campos de una tabla.
Rellenar la tabla con datos ficticios.
Realizar una consulta desde una fecha indicada y dentro del nmero de das
indicados.
Recorrer el contenido del recordset y comprobar si hay datos.
Mostrar el resultado de la consulta en un ListView.
Calcular el tiempo empleado en la consulta usando la clase cGetTimer.
Habilitar/ deshabilitar los controles contenidos en un control Frame.

La intencin es mostrarte el cdigo relacionado con el acceso a datos tanto para


DAO como ADO, por tanto, puedes pulsar en estos links para ver el cdigo de cada
una de esas versiones de acceso a datos.

Ejemplo usando DAO.


Ejemplo usando ADO (por terminar)

En esos mismos links tienes acceso al cdigo completo.

Aqu te muestro las capturas de los dos formularios usados por los ejemplos.

El formulario para crear la base y los campos con DAO


El formulario para crear la base y los campos con ADO

El formulario para realizar la consulta


Que lo disfrutes!

Nos vemos.
Guillermo

Ejemplo usando DAO:


Este es el cdigo usado para todo lo mencionado en la relacin anterior, no se
incluye el cdigo de la clase cGetTimer, ya que a dicho cdigo puedes acceder
usando el link anteriormente indicado.

Para usar DAO, en referencias tendrs que aadir una a: Microsoft DAO 3.51
Object Library
Para usar el ListView tendrs que aadir el componente: Microsoft Windows
Common Controls 6.0 (SP6)

Este es el cdigo completo del ejemplo de DAO (fechasDAO.zip 12.0 Bytes)

El cdigo del formulario para crear la base y los campos, etc.

'---------------------------------------------------------------------
---------
' Crear una base de datos DAO
(09/Jul/03)
'
' Con el botn de crear la base de datos, se crear una tabla
' con los campos ID, Nombre y FechaTrmino.
' NO BORRAR ESOS CAMPOS para poder probar lo de la consulta.
'
' Guillermo 'guille' Som, 2003
'---------------------------------------------------------------------
---------
Option Explicit

Private sCampos() As String ' Array con los campos en la tabla


'
Private Enum eTamao
Nombre = 22&
Tipo = 10&
Tamao = 7&
AlloZeroLength = 7&
Required = 6&
End Enum

'---------------------------------------------------------------------
---------
' Procedimientos privados (no de eventos)
'---------------------------------------------------------------------
---------
Private Sub crearBase(ByVal sBase As String)
' Crear la base de datos indicada
'
Dim Db As Database
Dim Fd As Field
Dim Tb As TableDef ' Definir una Tabla
Dim Idx As Index ' Para crear un ndice
Dim i As Long
Dim tVersion As DatabaseTypeEnum
'
On Error Resume Next
'If sBase = "" Then Exit Sub
i = Len(Dir$(sBase))
If Err Then i = 1
If i Then
MsgBox "La base de datos indicada ya existe." & vbCrLf & _
"Tendrs que eliminarla antes...", vbCritical
Exit Sub
End If
'

'---------------------------------------------------------------------
-----
' Crear base de datos, idioma general (dbLangGeneral)
' y para la versin indicada del Jet de Access

'---------------------------------------------------------------------
-----
Select Case True
Case optVersion(0)
tVersion = dbVersion10
Case optVersion(1)
tVersion = dbVersion11
Case optVersion(2)
tVersion = dbVersion20
Case optVersion(3)
tVersion = dbVersion30
End Select
Set Db = CreateDatabase(sBase, dbLangGeneral, tVersion)
'
' Primero la tabla de las tareas
Set Tb = Db.CreateTableDef(txtTabla.Text)
' Vamos a crear el Campo ID que ser un ndice
Set Fd = Tb.CreateField("ID", dbLong)
' Ahora vamos a asignar las propiedades de contador, etc.
Fd.Attributes = dbAutoIncrField Or dbUpdatableField Or
dbFixedField
Tb.Fields.Append Fd
' El resto de los campos
Set Fd = Tb.CreateField("Nombre", dbText, 50)
Tb.Fields.Append Fd
Set Fd = Tb.CreateField("FechaTrmino", dbDate)
Tb.Fields.Append Fd
'
' Creamos un ndice con el ID
Set Idx = New Index
Idx.Name = "PrimaryKey"
Idx.Unique = True
Idx.Primary = True
Idx.Fields = "ID"
' Aadimos el ndice a la tabla
Tb.Indexes.Append Idx
' Aadimos la tabla a la base
Db.TableDefs.Append Tb
'
' Cerramos la base
Db.Close
'
MsgBox "Nueva base de datos " & sBase & " creada.", vbInformation
End Sub

Private Function ajusta(ByVal Cadena As String, _


ByVal Ancho As Long, _
Optional Alineado As AlignmentConstants =
vbLeftJustify _
) As String
' Ajustar la cadena al ancho especificado
Dim s As String
'
' Alinear segn el parmetro Alineado
(06/Nov/00)
s = Left$(Cadena, Ancho)
If Alineado = vbLeftJustify Then
s = Left$(s & Space$(Ancho), Ancho)
ElseIf Alineado = vbRightJustify Then
s = Right$(Space$(Ancho) & s, Ancho)
Else
Do While Len(s) < Ancho
s = " " & s & " "
Loop
s = Left$(s, Ancho)
End If
ajusta = s
End Function

Private Sub mostrarCampos(Td As TableDef)

'---------------------------------------------------------------------
-----
' Inicializar los campos de la tabla especificada

'---------------------------------------------------------------------
-----
Dim Fd As Field
Dim tIndex As Index
Dim s As String
Dim n As Long
'
'On Local Error Resume Next
'
' recorrer los campos de la tabla
n = -1
'
List1.Clear
s = ajusta("Nombre:", eTamao.Nombre) & " " & ajusta("Tipo:",
eTamao.Tipo) & " " & ajusta("Tamao:", eTamao.Tamao) & " " &
ajusta("CeroLen", eTamao.AlloZeroLength) & " " & ajusta("Requer",
eTamao.Required)
List1.AddItem s
s = String$(eTamao.Nombre, "-") & " " & String$(eTamao.Tipo,
"-") & " " & String$(eTamao.Tamao, "-") & " " & String$
(eTamao.AlloZeroLength, "-") & " " & String$(eTamao.Required, "-")
List1.AddItem s
For Each Fd In Td.Fields
s = ""
With Fd
n = n + 1
ReDim Preserve sCampos(n)
sCampos(n) = .Name
'
s = s & ajusta(.Name, eTamao.Nombre) & " "
' Aadir el "nombre" del tipo
's = s & ajusta(.Type, eTamao.Tipo) & " "
s = s & ajusta(tipoToString(.Type), eTamao.Tipo) & " "
s = s & ajusta(CStr(.Size), eTamao.Tamao,
vbRightJustify) & " "
s = s & IIf(.AllowZeroLength, " S ", " No ") & " "
s = s & IIf(.Required, " S ", " No ")
List1.AddItem s
End With
Next
'
Err = 0
End Sub

Private Function tipoToString(ByVal elTipo As DataTypeEnum, _


Optional ByVal ConTipo As Boolean =
False) As String
' Devuelve una cadena segn el tipo de datos
(05/Nov/00)
Dim s As String
'
Select Case elTipo
Case dbBigInt
s = "dbBigInt"
Case dbBinary
s = "dbBinary"
Case dbBoolean
s = "dbBoolean"
Case dbByte
s = "dbByte"
Case dbChar
s = "dbChar"
Case dbCurrency
s = "dbCurrency"
Case dbDate
s = "dbDate"
Case dbDecimal
s = "dbDecimal"
Case dbDouble
s = "dbDouble"
Case dbFloat
s = "dbFloat"
Case dbGUID
s = "dbGUID"
Case dbInteger
s = "dbInteger"
Case dbLong
s = "dbLong"
Case dbLongBinary
s = "dbLongBinary"
Case dbMemo
s = "dbMemo"
Case dbNumeric
s = "dbNumeric"
Case dbSingle
s = "dbSingle"
Case dbText
s = "dbText"
Case dbTime
s = "dbTime"
Case dbTimeStamp
s = "dbTimeStamp"
Case dbVarBinary
s = "dbVarBinary"
Case Else
'If ConTipo Then
' s = "Tipo desconocido"
'Else
s = "dbMemo"
'End If
End Select
If ConTipo Then
s = s & " (" & CStr(elTipo) & ")"
End If
tipoToString = s
End Function

Private Sub habilitarCampos(Optional ByVal habilitar As Boolean =


True)
' habilitar / deshabilitar los controles contenidos en FrameCampos
Dim tControl As Control
Dim s As String
'
s = FrameCampos.Name
For Each tControl In Controls
' deshabilitar/habilitar slo los contenidos en el FrameCampos
If tControl.Container.Name = s Then
tControl.Enabled = habilitar
End If
Next
End Sub
'---------------------------------------------------------------------
---------

Private Sub cmdAdd_Click()


' Aadir el campo indicado a la tabla
Dim tBase As Database
Dim tTableDef As TableDef
Dim tField As Field
Dim i As Long
Dim s As String
'
On Error GoTo ErrAdd
'
Set tBase = OpenDatabase(Me.txtBase)
Set tTableDef = tBase.TableDefs(txtTabla.Text)
'
With Me.cboTipo
i = .ItemData(.ListIndex)
End With
With tTableDef
Set tField = .CreateField(Me.txtNombre, i, Me.txtLongitud)
.Fields.Append tField
With tField '.Fields(txtNombre)
If Me.chkAllowZeroLength Then
.AllowZeroLength = True
Else
.AllowZeroLength = False
End If
If Me.chkRequired Then
.Required = True
Else
.Required = False
End If
' aadirlo a la lista
s = ajusta(.Name, eTamao.Nombre) & " "
s = s & ajusta(tipoToString(.Type), eTamao.Tipo) & " "
s = s & ajusta(CStr(.Size), eTamao.Tamao,
vbRightJustify) & " "
s = s & IIf(.AllowZeroLength, " S ", " No ") & " "
s = s & IIf(.Required, " S ", " No ")
List1.AddItem s
End With
End With
'
tBase.Close
'
Exit Sub
'
ErrAdd:
MsgBox "Error al aadir el campo: " & txtNombre & vbCrLf & _
Err.Number & " " & Err.Description, _
vbExclamation Or vbOKOnly, "Error al borrar campos"
tBase.Close
End Sub

Private Sub cmdConsulta_Click()


With fComprobarFechasDAO
.NombreBase = txtBase
.NombreTabla = txtTabla
.Show vbModal, Me
End With
End Sub

Private Sub cmdCrearBase_Click()


crearBase txtBase.Text
End Sub

Private Sub cmdDel_Click()


' Eliminar el campo de la tabla
Dim tBase As Database
Dim tTableDef As TableDef
Dim tIndex As Index
Dim b As Boolean
Dim i As Long
'
On Error GoTo 0 'ErrDel
'
Set tBase = OpenDatabase(Me.txtBase)
Set tTableDef = tBase.TableDefs(txtTabla.Text)
' Si es un ndice, borrarlo de la tabla de ndices
(08/May/01)
On Error Resume Next
b = tTableDef.Indexes(Me.txtNombre).Unique
If Err = 0 Then
If b = False Then
tTableDef.Indexes.Delete Me.txtNombre
Else
If MsgBox("ATENCION! El campo " & txtNombre & " es un
ndice nico." & vbCrLf & "Quieres borrarlo?", vbYesNo Or
vbExclamation) = vbYes Then
On Error GoTo ErrDel
tTableDef.Indexes.Delete Me.txtNombre
End If
End If
End If
Err = 0
On Error GoTo ErrDel
tTableDef.Fields.Delete Me.txtNombre
'
' si llegamos aqu, es que se ha borrado
' eliminar el campo de la lista
For i = 0 To List1.ListCount - 1
If InStr(List1.List(i), txtNombre) > 0 Then
List1.RemoveItem i
Exit For
End If
Next
'
tBase.Close
'
Exit Sub
'
ErrDel:
MsgBox "Error al borrar el campo: " & txtNombre & vbCrLf & _
Err.Number & " " & Err.Description, _
vbExclamation Or vbOKOnly, "Error al borrar campos"
tBase.Close
End Sub

Private Sub cmdMostrarCampos_Click()


' abrir la tabla sealada por el combo
Dim Db As Database
Dim Td As TableDef
'
ReDim sCampos(0)
'
Set Db = OpenDatabase(txtBase)
For Each Td In Db.TableDefs
If Td.Name = txtTabla Then
' si es la tabla buscada...
mostrarCampos Td
habilitarCampos True
Exit For
End If
Next
Db.Close
Set Db = Nothing
End Sub

Private Sub cmdRellenarBase_Click()


' rellenar la base de datos con datos ficticios
Dim i As Long, j As Long
Dim k As Long, n As Long
Dim s As String
Dim cuantosDias As Long
Dim tDb As Database
Dim tRs As Recordset
'
On Error GoTo ErrRellenar
'
' asegurarnos de que hemos leido los campos
cmdMostrarCampos_Click
'
n = UBound(sCampos)
If n = 0 Then
MsgBox "La tabla debera tener al menos dos campos",
vbInformation
Exit Sub
End If
'
Set tDb = OpenDatabase(txtBase)
s = "SELECT * FROM " & txtTabla
Set tRs = tDb.OpenRecordset(s, dbOpenDynaset)
'
Me.MousePointer = vbHourglass
DoEvents
Randomize
j = txtRegsitros
For i = 1 To j
' crear registros ficticios
cuantosDias = Int(Rnd * 20) + 20
With tRs
.AddNew
For k = 0 To n
' slo aadir datos en campos de fecha, texto y moneda
Select Case .Fields(sCampos(k)).Type
Case DataTypeEnum.dbDate
If Rnd > 0.5 Then
.Fields(sCampos(k)) = Now + Int(Rnd *
cuantosDias)
Else
.Fields(sCampos(k)) = Now - Int(Rnd *
cuantosDias)
End If
Case DataTypeEnum.dbText
.Fields(sCampos(k)) = ajusta(sCampos(k) & " " & i,
.Fields(sCampos(k)).Size, vbLeftJustify)
Case DataTypeEnum.dbCurrency
.Fields(sCampos(k)) = CCur(Rnd * 15000)
End Select
Next
.Update
End With
Next
'
tRs.Close
tDb.Close
'
Me.MousePointer = vbDefault
DoEvents
MsgBox "Se han aadido " & j & " regsitros a la tabla " &
txtTabla, vbInformation
Exit Sub
'
ErrRellenar:
MsgBox "Se ha producido un error:" & vbCrLf & _
Err.Number & " " & Err.Description, vbCritical, "Error al
aadir regsitros"
Err = 0
End Sub

Private Sub Form_Load()


Move (Screen.Width - Width) \ 4, 0
'
' Asignar al combo los tipos de datos a elegir
With cboTipo
.Clear
.AddItem "dbText"
.ItemData(.NewIndex) = DataTypeEnum.dbText
.AddItem "dbCurrency"
.ItemData(.NewIndex) = DataTypeEnum.dbCurrency
.AddItem "dbDate"
.ItemData(.NewIndex) = DataTypeEnum.dbDate
.AddItem "dbLong"
.ItemData(.NewIndex) = DataTypeEnum.dbLong
.AddItem "dbDouble"
.ItemData(.NewIndex) = DataTypeEnum.dbDouble
.AddItem "dbInteger"
.ItemData(.NewIndex) = DataTypeEnum.dbInteger
.AddItem "dbBoolean"
.ItemData(.NewIndex) = DataTypeEnum.dbBoolean
.AddItem "dbMemo"
.ItemData(.NewIndex) = DataTypeEnum.dbMemo
.AddItem "dbByte"
.ItemData(.NewIndex) = DataTypeEnum.dbByte
.AddItem "dbChar"
.ItemData(.NewIndex) = DataTypeEnum.dbChar
.AddItem "dbLongBinary"
.ItemData(.NewIndex) = DataTypeEnum.dbLongBinary
.AddItem "dbSingle"
.ItemData(.NewIndex) = DataTypeEnum.dbSingle
.AddItem "dbFloat"
.ItemData(.NewIndex) = DataTypeEnum.dbFloat
.AddItem "dbBigInt"
.ItemData(.NewIndex) = DataTypeEnum.dbBigInt
.AddItem "dbBinary"
.ItemData(.NewIndex) = DataTypeEnum.dbBinary
.AddItem "dbDecimal"
.ItemData(.NewIndex) = DataTypeEnum.dbDecimal
.ListIndex = 0
End With
txtNombre = "Nombre"
txtLongitud = "50"
chkAllowZeroLength.Value = vbChecked
chkRequired.Value = vbUnchecked
' deshabilitar el contenido del Frame1(1)
habilitarCampos False
End Sub

Private Sub List1_Click()


' Mostrar la informacin del campo seleccionado
Dim i As Long
Dim s As String
'
With List1
i = .ListIndex
If i > 1 Then
s = .List(i)
Me.txtNombre = Trim$(Left$(s, eTamao.Nombre))
s = LTrim$(Mid$(s, eTamao.Nombre + 1))
Me.cboTipo.Text = Trim$(Left$(s, eTamao.Tipo))
s = (Mid$(s, eTamao.Tipo + 2))
Me.txtLongitud = Trim$(Left$(s, eTamao.Tamao))
s = LTrim$(Mid$(s, eTamao.Tamao + 1))
If Trim$(Left$(s, eTamao.AlloZeroLength)) = "S" Then
Me.chkAllowZeroLength.Value = vbChecked
Else
Me.chkAllowZeroLength.Value = vbUnchecked
End If
s = LTrim$(Mid$(s, eTamao.AlloZeroLength + 1))
If Trim$(s) = "S" Then
Me.chkRequired.Value = vbChecked
Else
Me.chkRequired.Value = vbUnchecked
End If
End If
End With
End Sub

El cdigo del formulario para hacer la consulta y mostrar los


datos

'---------------------------------------------------------------------
---------
' Prueba de consulta con fechas en base de datos DAO
(09/Jul/03)
'
' Los campos que debe tener la tabla de la base indicada sern:
' ID, Nombre y FechaTrmino
'
' Guillermo 'guille' Som, 2003
'---------------------------------------------------------------------
---------
Option Explicit

Public NombreBase As String ' Nombre de la base de datos


Public NombreTabla As String ' El nombre de la tabla
Private mCuantosDias As Long
Private Db As Database

Private Sub cmdProcesar_Click()


' procesar los datos a mostrar
Dim fechaActual As Date
Dim s As String
Dim dFin As Date
Dim tRs As Recordset
Dim tGT As cGetTimer
Dim n As Long
'
On Error Resume Next
Set Db = OpenDatabase(NombreBase)
If Err Then
MsgBox "Error al abrir la base de datos: " & NombreBase &
vbCrLf & _
Err.Number & " " & Err.Description
Exit Sub
End If
'
fechaActual = Format$(txtFecha, "dd/mm/yyyy")
mCuantosDias = txtDias
dFin = (fechaActual + mCuantosDias)
'
ListView1.ListItems.Clear
'
Set tGT = New cGetTimer
tGT.StartTimer
'
n = 0
Err.Number = 0
s = "SELECT ID, Nombre, [FechaTrmino] FROM " & NombreTabla & "
WHERE [FechaTrmino] >= " & FechaSQL(fechaActual) & " AND
[FechaTrmino] <= " & FechaSQL(dFin) & " ORDER BY [FechaTrmino]"
Set tRs = Db.OpenRecordset(s, dbOpenForwardOnly)
If Err Then
MsgBox "Error al abrir el Recordset" & vbCrLf & _
Err.Number & " " & Err.Description
Exit Sub
End If
With tRs
If (.EOF = True) And (.BOF = True) Then
' Si no hay datos...
With ListView1.ListItems.Add(, , "0")
.SubItems(1) = "No hay datos entre las fechas " &
Format$(fechaActual, "dd/mm/yyyy")
.SubItems(2) = Format$(dFin, "dd/mm/yyyy")
End With
Else
n = 0
Do While Not .EOF
n = n + 1
With ListView1.ListItems.Add(, , tRs.Fields("ID"))
.SubItems(1) = Trim$(tRs.Fields("Nombre"))
.SubItems(2) = Format$
(tRs.Fields("[FechaTrmino]") & "", "dd/mm/yyyy")
End With
.MoveNext
Loop
End If
End With
tRs.Close
Db.Close
'
tGT.StopTimer
lblInfo.Caption = "Tiempo: " & tGT.ElapsedTime & " (" & n & ")"
End Sub

Private Sub Form_Load()


' Asignar el nombre de la base de datos
'NombreBase App.Path & "PruebaDAO.mdb"
'
If Year(Now) > 2003 Then
lblInfo.Caption = "Guillermo 'guille' Som, 2003-" & Year(Now)
Else
lblInfo.Caption = "Guillermo 'guille' Som, 2003"
End If
'
mCuantosDias = 10&
txtDias.Text = mCuantosDias
'
' crear las columnas del ListView
' (aunque ya estn creadas en tiempo de diseo)
With ListView1
.ColumnHeaders.Clear
.ColumnHeaders.Add , , "ID", 800
.ColumnHeaders.Add , , "Nombre", 3200
.ColumnHeaders.Add , , "Fecha Trmino", 1400, lvwColumnRight
.GridLines = True
.FullRowSelect = True
.LabelEdit = lvwManual
End With
End Sub

Ejemplo usando ADO:


Este es el cdigo usado para todo lo mencionado en la relacin anterior, no se
incluye el cdigo de la clase cGetTimer, ya que a dicho cdigo puedes acceder
usando el link anteriormente indicado.

Para usar ADO, en referencias tendrs que aadir una a: Microsoft ActiveX Data
Objects 2.5 Library
Adems de una a ADOX: Microsoft ADO Ext. 2.7 for DDL and Security
(la versin pude ser cualquier otra anterior a la 2.7)
Para usar el ListView tendrs que aadir el componente: Microsoft Windows
Common Controls 6.0 (SP6)

Nota:
He de aclarar que para mi gusto, este cdigo no est terminado, ya que, por
ejemplo, los tipos de datos no estn "comprobados", simplemente los he sustituido
"a mocho".

Adems, (y esto es ms grave), que con el motor 3.51 (el compatible con Access
97) no he logrado crear un campo Auntonumrico, sin embargo usando el 4.0 si
que se crea sin problemas...
Lo mismo es que estoy demasiado "ofuscado", en fin... a ver si con ms calma o
con la ayuda de alguna alma caritativa lo dejo solucionado...

Nota del 10/Jul/03:


Pues la aparicin del alma caritativa no se ha hecho esperar, gracias a
Joaqun Delgado Pastor, tenemos la solucin.
Y esta consiste en lo siguiente:
-Usar siempre el proveedor Microsoft.Jet.OLEDB.4.0
-Aadir esta cadena a la cadena de conexin:
-Para Access 97: Jet OLEDB:Engine Type=4;
-Para Access 2000: Jet OLEDB:Engine Type=5;
De esta forma se crear correctamente el campo autonumrico y segn se
seleccione la opcin 3.51 o 4.0 se crear una base de datos compatible con
Access 97 o Access 2000/XP respectivamente.

En el cdigo mostrado estn hechas las correcciones correspondientes para


usar este nueva forma.

Si quieres, ahora en los dos Options en lugar de indicar el "motor" Jet, se


puede indicar si ser con formato Access 97 o con formato Access
2000/XP.
En el cdigo incluido en el Zip ya est modificado.

Este es el cdigo completo del ejemplo de ADO (fechasADO.zip 12.8 KB)

El cdigo del formulario para crear la base y los campos, etc.

'---------------------------------------------------------------------
---------
' Crear una base de datos ADO
(09/Jul/03)
'
' Con el botn de crear la base de datos, se crear una tabla
' con los campos ID, Nombre y FechaTrmino.
' NO BORRAR ESOS CAMPOS para poder probar lo de la consulta.
'
' Guillermo 'guille' Som, 2003
'---------------------------------------------------------------------
---------
Option Explicit

Private sProvider As String


Private sCampos() As String ' Array con los campos en la tabla
'
Private Enum eTamao
Nombre = 22&
Tipo = 10&
Tamao = 7&
AlloZeroLength = 7&
Required = 6&
End Enum

'---------------------------------------------------------------------
---------
' Procedimientos privados (no de eventos)
'---------------------------------------------------------------------
---------

Private Sub crearBase(ByVal sBase As String)


' Crear la base de datos indicada
'
Dim i As Long
'
Dim tbl As ADOX.Table
Dim cat As ADOX.Catalog
Dim idx As ADOX.Index
Dim col As ADOX.Column
'
Dim sProviderDes As String
'
On Error Resume Next
'
'If sBase = "" Then Exit Sub
i = Len(Dir$(sBase))
If Err Then i = 1
If i Then
MsgBox "La base de datos indicada ya existe." & vbCrLf & _
"Tendrs que eliminarla antes...", vbCritical
Exit Sub
End If
'
On Error GoTo 0
'
' Gracias a Joaquin Delgado Pastor (10/Jul/03), con esto funciona:
'
Select Case True
Case Me.optVersion(0)
'sProvider = "Microsoft.Jet.OLEDB.3.51"
'
sProviderDes = "Jet OLEDB:Engine Type=4;"

Case Me.optVersion(1)
'sProvider = "Microsoft.Jet.OLEDB.4.0"
sProviderDes = "Jet OLEDB:Engine Type=5;"

End Select
sProvider = "Microsoft.Jet.OLEDB.4.0"
'
' Crear la base de datos
Set cat = New ADOX.Catalog
cat.Create "Provider=" & sProvider & ";" & _
"Data Source=" & txtBase & ";" & sProviderDes
'
Set cat = New ADOX.Catalog
Set tbl = New ADOX.Table
'
' Abrir el catlogo
cat.ActiveConnection = _
"Provider=" & sProvider & ";" & _
"Data Source=" & txtBase & ";"
'
' Crear la nueva tabla
With tbl
.Name = txtTabla.Text
' Crear los campos y aadirlos a la tabla.
' Esto hay que hacerlo antes de aadir la tabla a la coleccin
de tablas
Set col = New ADOX.Column
With col
.Name = "ID"
.Type = adInteger
' Autoincrement no existe como propiedad en 3.51
If sProvider <> "Microsoft.Jet.OLEDB.3.51" Then
Set .ParentCatalog = cat
.Properties("AutoIncrement") = True
End If
End With
.Columns.Append col
'
'
Set idx = New ADOX.Index
idx.Name = "IDx"
idx.PrimaryKey = True
idx.Unique = True
idx.IndexNulls = adIndexNullsDisallow
idx.Columns.Append "ID"
.Indexes.Append idx
'
'
' Dependiendo del tipo de proveedor, los datos de cadena sern
de un tipo u otro
If sProvider = "Microsoft.Jet.OLEDB.3.51" Then
' Para Access 97
.Columns.Append "Nombre", adVarChar, 50 ' Una
cadena de 50 caracteres
.Columns.Append "FechaTrmino", adDate
Else
' Para Access 2000
.Columns.Append "Nombre", adVarWChar, 50 ' Una
cadena de 50 caracteres
.Columns.Append "FechaTrmino", adDate
End If
.Columns("Nombre").Attributes = adColNullable ' Permite
contener nulos
.Columns("FechaTrmino").Attributes = adColNullable
End With
'
' Aadir la nueva tabla a la base de datos
cat.Tables.Append tbl
'
Set tbl = Nothing
Set cat = Nothing
'
'
MsgBox "Nueva base de datos " & sBase & " creada.", vbInformation
End Sub

Private Function ajusta(ByVal Cadena As String, _


ByVal Ancho As Long, _
Optional Alineado As AlignmentConstants =
vbLeftJustify _
) As String
' Ajustar la cadena al ancho especificado
Dim s As String
'
' Alinear segn el parmetro Alineado
(06/Nov/00)
s = Left$(Cadena, Ancho)
If Alineado = vbLeftJustify Then
s = Left$(s & Space$(Ancho), Ancho)
ElseIf Alineado = vbRightJustify Then
s = Right$(Space$(Ancho) & s, Ancho)
Else
Do While Len(s) < Ancho
s = " " & s & " "
Loop
s = Left$(s, Ancho)
End If
ajusta = s
End Function

Private Sub mostrarCampos(Td As Table)

'---------------------------------------------------------------------
-----
' Inicializar los campos de la tabla especificada

'---------------------------------------------------------------------
-----
Dim Fd As Column
Dim s As String
Dim n As Long
'
'On Local Error Resume Next
'
' recorrer los campos de la tabla
n = -1
'
List1.Clear
s = ajusta("Nombre:", eTamao.Nombre) & " " & ajusta("Tipo:",
eTamao.Tipo) & " " & ajusta("Tamao:", eTamao.Tamao) & " " &
ajusta("CeroLen", eTamao.AlloZeroLength) & " " & ajusta("Requer",
eTamao.Required)
List1.AddItem s
s = String$(eTamao.Nombre, "-") & " " & String$(eTamao.Tipo,
"-") & " " & String$(eTamao.Tamao, "-") & " " & String$
(eTamao.AlloZeroLength, "-") & " " & String$(eTamao.Required, "-")
List1.AddItem s
For Each Fd In Td.Columns
s = ""
With Fd
n = n + 1
ReDim Preserve sCampos(n)
sCampos(n) = .Name
'
s = s & ajusta(.Name, eTamao.Nombre) & " "
' Aadir el "nombre" del tipo
's = s & ajusta(.Type, eTamao.Tipo) & " "
s = s & ajusta(tipoToString(.Type), eTamao.Tipo) & " "
s = s & ajusta(CStr(.DefinedSize), eTamao.Tamao,
vbRightJustify) & " "
s = s & IIf((.Attributes And adColNullable) =
adColNullable, " S ", " No ") & " "
s = s & IIf((.Attributes And adIndexNullsAllow) =
adIndexNullsAllow, " S ", " No ")
List1.AddItem s
End With
Next
'
Err = 0
End Sub

Private Function tipoToString(ByVal elTipo As DataTypeEnum, _


Optional ByVal ConTipo As Boolean =
False) As String
' Devuelve una cadena segn el tipo de datos
(05/Nov/00)
Dim s As String
'
Select Case elTipo
Case DataTypeEnum.adBigInt
s = "adBigInt"
Case DataTypeEnum.adBinary
s = "adBinary"
Case DataTypeEnum.adBoolean
s = "adBoolean"
Case DataTypeEnum.adChar
s = "adChar"
Case DataTypeEnum.adVarChar
s = "adVarChar"
Case DataTypeEnum.adCurrency
s = "adCurrency"
Case DataTypeEnum.adDate
s = "adDate"
Case DataTypeEnum.adDecimal
s = "adDecimal"
Case DataTypeEnum.adDouble
s = "adDouble"
Case DataTypeEnum.adSingle
s = "adSingle"
Case DataTypeEnum.adGUID
s = "adGUID"
Case DataTypeEnum.adInteger
s = "adInteger"
Case DataTypeEnum.adNumeric
s = "adNumeric"
Case DataTypeEnum.adLongVarBinary
s = "adLongVarBinary"
Case DataTypeEnum.adNumeric
s = "adNumeric"
Case DataTypeEnum.adSingle
s = "adSingle"
Case DataTypeEnum.adDBTime
s = "adDBTime"
Case DataTypeEnum.adDBDate
s = "adDBDate"
Case DataTypeEnum.adVarBinary
s = "adVarBinary"
Case Else
s = "adVarChar"
End Select
If ConTipo Then
s = s & " (" & CStr(elTipo) & ")"
End If
tipoToString = s
End Function

Private Sub habilitarCampos(Optional ByVal habilitar As Boolean =


True)
' habilitar / deshabilitar los controles contenidos en FrameCampos
Dim tControl As Control
Dim s As String
'
s = FrameCampos.Name
For Each tControl In Controls
' deshabilitar/habilitar slo los contenidos en el FrameCampos
If tControl.Container.Name = s Then
tControl.Enabled = habilitar
End If
Next
End Sub
'---------------------------------------------------------------------
---------

Private Sub cmdAdd_Click()


' Aadir el campo indicado a la tabla
Dim i As Long
Dim s As String
Dim cat As ADOX.Catalog
Dim tTable As ADOX.Table
'Dim col As ADOX.Column
'
On Error GoTo ErrAdd
'
Set cat = New ADOX.Catalog
cat.ActiveConnection = "Provider=" & sProvider & "; Data Source="
& txtBase.Text
Set tTable = cat.Tables(txtTabla.Text)
'
With Me.cboTipo
i = .ItemData(.ListIndex)
End With
With tTable
.Columns.Append txtNombre, i, txtLongitud
With .Columns(txtNombre)
If Me.chkAllowZeroLength Then
.Attributes = adColNullable
End If
' aadirlo a la lista
s = ajusta(.Name, eTamao.Nombre) & " "
s = s & ajusta(tipoToString(.Type), eTamao.Tipo) & " "
s = s & ajusta(CStr(.DefinedSize), eTamao.Tamao,
vbRightJustify) & " "
s = s & IIf((.Attributes And adColNullable) =
adColNullable, " S ", " No ") & " "
s = s & " " 'IIf(.Required, " S ", " No ")
List1.AddItem s
End With
End With
'
Set tTable = Nothing
Set cat = Nothing
'
Exit Sub
'
ErrAdd:
MsgBox "Error al aadir el campo: " & txtNombre & vbCrLf & _
Err.Number & " " & Err.Description, _
vbExclamation Or vbOKOnly, "Error al borrar campos"
End Sub

Private Sub cmdConsulta_Click()


Load fComprobarFechasADO
With fComprobarFechasADO
.NombreBase = txtBase
.NombreTabla = txtTabla
.Provider = sProvider
.Show vbModal, Me
End With
End Sub

Private Sub cmdCrearBase_Click()


crearBase txtBase.Text
End Sub

Private Sub cmdDel_Click()


' Eliminar el campo de la tabla
Dim b As Boolean
Dim i As Long
Dim cat As ADOX.Catalog
Dim tTable As ADOX.Table
Dim col As ADOX.Column
'
'
Set cat = New ADOX.Catalog
cat.ActiveConnection = "Provider=" & sProvider & "; Data Source="
& txtBase.Text
Set tTable = cat.Tables(txtTabla.Text)
'
'
' Si es un ndice, borrarlo de la tabla de ndices
(08/May/01)
On Error Resume Next
b = tTable.Indexes(txtNombre).Unique
If Err = 0 Then
If b = False Then
tTable.Indexes.Delete txtNombre
Else
If MsgBox("ATENCION! El campo " & txtNombre & " es un
ndice nico." & vbCrLf & "Quieres borrarlo?", vbYesNo Or
vbExclamation) = vbYes Then
On Error GoTo ErrDel
tTable.Indexes.Delete txtNombre
End If
End If
End If
Err = 0
On Error GoTo ErrDel
tTable.Columns.Delete txtNombre
'
' si llegamos aqu, es que se ha borrado
' eliminar el campo de la lista
For i = 0 To List1.ListCount - 1
If InStr(List1.List(i), txtNombre) > 0 Then
List1.RemoveItem i
Exit For
End If
Next
'
Set tTable = Nothing
Set cat = Nothing
'
Exit Sub
'
ErrDel:
MsgBox "Error al borrar el campo: " & txtNombre & vbCrLf & _
Err.Number & " " & Err.Description, _
vbExclamation Or vbOKOnly, "Error al borrar campos"
End Sub

Private Sub cmdMostrarCampos_Click()


' abrir la tabla sealada por el combo
Dim cat As ADOX.Catalog
Dim tTable As ADOX.Table
'
Set cat = New ADOX.Catalog
cat.ActiveConnection = "Provider=" & sProvider & "; Data Source="
& txtBase.Text
Set tTable = cat.Tables(txtTabla.Text)
'
ReDim sCampos(0)
'
mostrarCampos tTable
habilitarCampos True
'
Set tTable = Nothing
Set cat = Nothing
End Sub

Private Sub cmdRellenarBase_Click()


' rellenar la base de datos con datos ficticios
Dim i As Long, j As Long
Dim k As Long, n As Long
Dim s As String
Dim cuantosDias As Long
Dim cnn As ADODB.Connection
Dim tRs As ADODB.Recordset
'
'On Error GoTo ErrRellenar
On Error GoTo 0
'
' asegurarnos de que hemos leido los campos
cmdMostrarCampos_Click
'
n = UBound(sCampos)
If n = 0 Then
MsgBox "La tabla debera tener al menos dos campos",
vbInformation
Exit Sub
End If
'
Set cnn = New ADODB.Connection
cnn.Open "Provider=" & sProvider & "; Data Source=" & txtBase
s = "SELECT * FROM " & txtTabla
Set tRs = New Recordset
tRs.Open s, cnn, adOpenDynamic, adLockOptimistic
'
Me.MousePointer = vbHourglass
DoEvents
Randomize
j = txtRegsitros
For i = 1 To j
' crear registros ficticios
cuantosDias = Int(Rnd * 20) + 20
With tRs
.AddNew
For k = 0 To n
' slo aadir datos en campos de fecha, texto y moneda
Select Case .Fields(sCampos(k)).Type
Case DataTypeEnum.adDate
If Rnd > 0.5 Then
.Fields(sCampos(k)) = Now + Int(Rnd *
cuantosDias)
Else
.Fields(sCampos(k)) = Now - Int(Rnd *
cuantosDias)
End If
Case DataTypeEnum.adVarChar, DataTypeEnum.adVarWChar
.Fields(sCampos(k)) = ajusta(sCampos(k) & " " & i,
.Fields(sCampos(k)).DefinedSize, vbLeftJustify)
Case DataTypeEnum.adCurrency
.Fields(sCampos(k)) = CCur(Rnd * 15000)
End Select
Next
.Update
End With
Next
'
Set tRs = Nothing
cnn.Close
'
Me.MousePointer = vbDefault
DoEvents
MsgBox "Se han aadido " & j & " regsitros a la tabla " &
txtTabla, vbInformation
Exit Sub
'
ErrRellenar:
MsgBox "Se ha producido un error:" & vbCrLf & _
Err.Number & " " & Err.Description, vbCritical, "Error al
aadir regsitros"
Err = 0
End Sub

Private Sub Form_Load()


Move (Screen.Width - Width) \ 4, 0
'
'txtBase = App.Path & "\PruebaDAO.mdb"
txtBase = "PruebaADO.mdb"
'sProvider = "Microsoft.Jet.OLEDB.3.51"
' con el proveedor 4.0 el autoincremento no da error
sProvider = "Microsoft.Jet.OLEDB.4.0"
'
' Asignar al combo los tipos de datos a elegir
With cboTipo
.Clear
' Tipos de datos de DAO y ADO (equivalencias)
'dbBinary adBinary
'dbBoolean adBoolean
'dbByte adUnsignedTinyInt
'dbCurrency adCurrency
'dbDate adDate
'dbDecimal adNumeric
'dbDouble adDouble
'dbGUID adGUID
'dbInteger adSmallInt
'dbLong adInteger
'dbLongBinary adLongVarBinary
'dbMemo adLongVarWChar
'dbSingle adSingle
'dbText adVarWChar
.AddItem tipoToString(DataTypeEnum.adVarChar)
.ItemData(.NewIndex) = DataTypeEnum.adVarChar
.AddItem "adCurrency"
.ItemData(.NewIndex) = DataTypeEnum.adCurrency
.AddItem "adDate"
.ItemData(.NewIndex) = DataTypeEnum.adDate
.AddItem "adNumeric"
.ItemData(.NewIndex) = DataTypeEnum.adNumeric
.AddItem "adDouble"
.ItemData(.NewIndex) = DataTypeEnum.adDouble
.AddItem "adInteger"
.ItemData(.NewIndex) = DataTypeEnum.adInteger
.AddItem "adBoolean"
.ItemData(.NewIndex) = DataTypeEnum.adBoolean
.AddItem "adVarBinary"
.ItemData(.NewIndex) = DataTypeEnum.adVarBinary
.AddItem "adChar"
.ItemData(.NewIndex) = DataTypeEnum.adChar
.AddItem "adSingle"
.ItemData(.NewIndex) = DataTypeEnum.adSingle
.AddItem "adBigInt"
.ItemData(.NewIndex) = DataTypeEnum.adBigInt
.AddItem "adBinary"
.ItemData(.NewIndex) = DataTypeEnum.adBinary
.AddItem "adDecimal"
.ItemData(.NewIndex) = DataTypeEnum.adDecimal
.ListIndex = 0
End With
txtNombre = "Nombre"
txtLongitud = "50"
chkAllowZeroLength.Value = vbChecked
chkRequired.Value = vbUnchecked
' deshabilitar el contenido del Frame1(1)
habilitarCampos False
End Sub

Private Sub List1_Click()


' Mostrar la informacin del campo seleccionado
Dim i As Long
Dim s As String
'
With List1
i = .ListIndex
If i > 1 Then
s = .List(i)
Me.txtNombre = Trim$(Left$(s, eTamao.Nombre))
s = LTrim$(Mid$(s, eTamao.Nombre + 1))
Me.cboTipo.Text = Trim$(Left$(s, eTamao.Tipo))
s = (Mid$(s, eTamao.Tipo + 2))
Me.txtLongitud = Trim$(Left$(s, eTamao.Tamao))
s = LTrim$(Mid$(s, eTamao.Tamao + 1))
If Trim$(Left$(s, eTamao.AlloZeroLength)) = "S" Then
Me.chkAllowZeroLength.Value = vbChecked
Else
Me.chkAllowZeroLength.Value = vbUnchecked
End If
s = LTrim$(Mid$(s, eTamao.AlloZeroLength + 1))
If Trim$(s) = "S" Then
Me.chkRequired.Value = vbChecked
Else
Me.chkRequired.Value = vbUnchecked
End If
End If
End With
End Sub

Private Sub optVersion_Click(Index As Integer)


If Index = 0 Then
sProvider = "Microsoft.Jet.OLEDB.3.51"
Else
sProvider = "Microsoft.Jet.OLEDB.4.0"
End If
End Sub

El cdigo del formulario para hacer la consulta y mostrar los


datos

'---------------------------------------------------------------------
---------
' Prueba de consulta con fechas en base de datos ADO
(09/Jul/03)
'
' Los campos que debe tener la tabla de la base indicada sern:
' ID, Nombre y FechaTrmino
'
' Guillermo 'guille' Som, 2003
'---------------------------------------------------------------------
---------
Option Explicit

Public NombreBase As String ' Nombre de la base de datos


Public NombreTabla As String ' El nombre de la tabla
Public Provider As String
Private mCuantosDias As Long
' Objetos para acceder directamente a la base usando cdigo
Private cnn As ADODB.Connection

Private Sub cmdProcesar_Click()


' procesar los datos a mostrar
Dim fechaActual As Date
Dim s As String
Dim dFin As Date
Dim tRs As Recordset
Dim tGT As cGetTimer
Dim n As Long
'
Set cnn = New ADODB.Connection
'
cnn.Open "Provider=" & Provider & "; Data Source=" & NombreBase
'
fechaActual = Format$(txtFecha, "dd/mm/yyyy")
mCuantosDias = txtDias
dFin = (fechaActual + mCuantosDias)
'
ListView1.ListItems.Clear
'
Set tGT = New cGetTimer
tGT.StartTimer
'
' en ADO no hace falta indicar el campo FechaTrmino entre
corchetes
s = "SELECT ID, Nombre, [FechaTrmino] FROM " & NombreTabla & "
WHERE [FechaTrmino] >= " & FechaSQL(fechaActual) & " AND
[FechaTrmino] <= " & FechaSQL(dFin) & " ORDER BY [FechaTrmino]"
Set tRs = New Recordset
tRs.Open s, cnn, adOpenForwardOnly, adLockReadOnly
'adLockOptimistic
With tRs
If (.EOF = True) And (.BOF = True) Then
' Si no hay datos...
With ListView1.ListItems.Add(, , "0")
.SubItems(1) = "No hay datos entre las fechas " &
Format$(fechaActual, "dd/mm/yyyy")
.SubItems(2) = Format$(dFin, "dd/mm/yyyy")
End With
Else
n = 0
Do While Not .EOF
n = n + 1
With ListView1.ListItems.Add(, , tRs.Fields("ID"))
.SubItems(1) = Trim$(tRs.Fields("Nombre") & "")
.SubItems(2) = Format$(tRs.Fields("FechaTrmino")
& "", "dd/mm/yyyy")
End With
.MoveNext
Loop
End If
End With
tRs.Close
cnn.Close
'
tGT.StopTimer
lblInfo.Caption = "Tiempo: " & tGT.ElapsedTime & " (" & n & ")"
End Sub

Private Sub Form_Load()


' Asignar el nombre de la base de datos y el proveedor
'
' para bases de datos Access 97 (con Access 2000/XP no funciona)
NombreBase = App.Path & "\PruebaDAO.mdb"
Provider = "Microsoft.Jet.OLEDB.3.51"
'
' para bases de datos Access 2000 (tambin para Access 97, pero va
ms lento)
'NombreBase = App.Path & "PruebaDAO.mdb"
'sProvider = "Microsoft.Jet.OLEDB.4.0"
'
If Year(Now) > 2003 Then
lblInfo.Caption = "Guillermo 'guille' Som, 2003-" & Year(Now)
Else
lblInfo.Caption = "Guillermo 'guille' Som, 2003"
End If
'
mCuantosDias = 10&
txtDias.Text = mCuantosDias
'
' crear las columnas del ListView
' (aunque ya estn creadas en tiempo de diseo)
With ListView1
.ColumnHeaders.Clear
.ColumnHeaders.Add , , "ID", 800
.ColumnHeaders.Add , , "Nombre", 3200
.ColumnHeaders.Add , , "Fecha Trmino", 1400, lvwColumnRight
.GridLines = True
.FullRowSelect = True
.LabelEdit = lvwManual
End With
End Sub

http://www.elguille.info/vb/bases/ADO/indiceADO.htm#ado18Dic03
Bases de Datos usando DAO
y Visual Basic (clsico)

Contenido: (los ms recientes abajo)

1. Copiar la estructura de una tabla con Access


2. Ordenes SQL para cambiar los datos de una tabla.
3. Caracteres no "standards" en los nombres de los campos
4. Procesar una consulta SQL (Execute)
5. Procesar una consulta SQL creando un Recordset
6. Evitar el error al asignar un Null
7. Comprobar si un registro se est editando
8. Asignar a un Recordset los registros deseados
9. Compactar una base de datos, usando cdigo VB (27/Feb)
10. Crear una base de datos, usando cdigo VB (18/Abr)
11. Como crear un Formulario de Datos con un Grupo de Registros Subyacente
(18/Abr)
12. Cambiar los caracteres extraos por ? (para usar en las consultas a bases de
datos con LIKE) (20/Abr)
13. Procesar el resultado de una consulta con varias tablas para evitar registros
duplicados (13/Jul)
14. Programacin sobre la seguridad de Access (31/Ago)
15. Un mtodo rpido para efectuar bsquedas (8/Sep)
16. Enumerar las tablas de una base de datos (17/Sep)
17. Capturar errores de ODBC (9/Abr/98)
18. Acceso a bases de datos SQL Server...
19. Cargar Imgenes de una base de datos sin usar el DataControl
20. Acceder a bases de datos de Access 2000 con el VB5 (05/Oct/99)
21. Un consejo si instalas VB6 SP4 para acceder a bases de datos de Access
2000 (10/Nov/00)
22. Ejemplo "simple" de acceso a datos DAO con el data control (Curso Bsico
entrega 34) (09/Jul/03)
23. Buscar en una base de datos DAO con el data control (Curso Bsico entrega
35) (09/Jul/03)
24. Acceder a una base de datos DAO sin el data control (Curso Bsico entrega
40) (09/Jul/03)
25. Realizar consultas en una base de datos DAO (Curso Bsico entrega 40)
(09/Jul/03)
26. Cmo manejar fechas en consultas, adems de otros ejemplos, tanto para
ADO como para DAO (09/Jul/03)
27. Instrucciones SQL para seleccionar, actualizar, eliminar datos, etc.
(02/May/04)
28. Conectar a una base de datos de SQL Server con VB6 (Abrir una tabla y
mostrar los campos/columnas) (10/Sep/04)
29. Indicar el path de una base de datos usando el control data (18/Sep/04)
Ejemplo paso a paso de cmo usar un control data y DataGrid
1.- Copiar la estructura de una tabla con Access

Para copiar/duplicar la estructura de una tabla en una base de datos Access, sigue
estos pasos:

1. Carga la base de datos en Access


2. Selecciona la tabla a copiar
3. En el men de Edicin, selecciona Copiar
4. En el men de Edicin, selecciona Pegar
5. Escribe el nuevo nombre de la tabla
6. Selecciona "Estructura solamente"

Ya est la tabla "duplicada" en la misma base de datos, por si haces cambios de los
que despus te arrepientas.
Si la intencin es copiarla en otra base de datos, antes de seguir con el paso 4,
cargar o crear la nueva base de datos y ya est. En el paso 6 puedes seleccionar
"Estructura y Datos" si quieres copiar tambin los datos.

2.- Ordenes SQL para cambiar los datos de una tabla.

UPDATE tabla
SET nombre_campo = 'nuevo_valor'
WHERE opciones_a_tener_en_cuenta

Ejemplo: Actualizar la tabla Clientes poniendo el campo Agente a LIBRE si la fecha


de ltimaVisita es anterior al 1 de Enero de 1996 (este es un caso sobre una base
de datos que uso en mi trabajo, pero como ejemplo puede valer):

UPDATE Clientes SET Agente = 'LIBRE' WHERE [ltimaVisita] <


DateValue('01/01/96')

Normalmente el campo de fechas ser segn tengis configurado el sistema.

3.- Caracteres no "standard" en los nombres de los campos


Si al crear las tablas de la base de datos usas caracteres acentuados, ees,
espacios, etc. Cuando hagas una consulta o lo uses en un Recordset, etc, ponlos
entre corchetes, fijates en cmo se usa ltimaVisita en el ejemplo anterior.

4.- Procesar una consulta SQL (Execute)

Para ejecutar una orden SQL en una base de datos, usar la orden Execute en la
variable de una base de datos (Database)

'SQLTmp= orden SQL


'Db ser una base de datos:
'Dim Db As Database 'Variable para las Bases de Datos
'Set Db = OpenDatabase("Nombre_Base_Datos")

On Error Resume Next


Db.Execute SQLTmp, dbFailOnError
If Err Then
MsgBox "Se ha producido un error al ejecutar la orden:" &
vbCrLf & SQLTmp
End If

5.- Procesar una consulta SQL creando un Recordset

Se crear un Recordset con el resultado de una consulta SQL realizada a uan base
de datos, posteriormente se procesarn los datos que ha producido dicha consulta.
Por ejemplo si tenemos una base de datos con nuestra coleccin discogrfica,
podramos hacer una consulta con todos los CD's de Phil Collins
Suponiendo que el formato de los discos (CD, LP, etc.) es Formato y el Nombre del
Autor est en Cantante, la orden a ejecutar sera:
SQLTmp = "SELECT * FROM mis_discos WHERE Formato Like '*CD*' AND Cantante
Like '*Phil Collins*'"
Por supuesto se puede usar = en lugar de Like, si estamos seguros de que no
necesitamos los comodines, ya que la consulta es "bastante" ms rpida. Es decir
quedara as:
SQLTmp = "SELECT * FROM mis_discos WHERE Formato = 'CD' AND Cantante =
'Phil Collins'"

'Ejecutar orden SQL con los datos solicitados

'Db ser una base de datos:


'Dim Db As Database 'Variable para las Bases de Datos
'Set Db = OpenDatabase("Nombre_Base_Datos")

Dim SQLTmp As String


Dim MySnap As Recordset
SQLTmp = "select * from " & Nombre_Tabla & " <Consulta> " & " order by
" & Clasificar
Set MySnap = Db.OpenRecordset(SQLTmp, dbOpenSnapshot)
Err = 0
MySnap.MoveFirst
If Err Then
Err = 0
'no hay datos, avisar
MsgBox "No hay datos que coincidan con la bsqueda
especificada," & vbCrLf & "(o no est bien realizada)", 64, "Listados"
Exit Sub
End If

'Aadir el resultado a un List


List1.Clear

MySnap.MoveFirst
Do Until MySnap.EOF
'Procesar los datos...
'
List1.AddItem MySnap("Cantante") & " " & MySnap("[Cancin]")
'...y dems datos

MySnap.MoveNext
Loop
MySnap.Close

6.- Evitar el error al asignar un campo Null de una base de datos.

Adems de evitar el error, es ms rpido que usar If...Then... para comprobar si el


campo es nulo o est vaco.

Para cadenas:

Cadena = "" & rs!Campo

Para nmeros:

'Numero = 0 & rs!Campo


Numero = CInt("0" & rs!Campo)

7.- Comprobar si un registro se est editando.

Esto puede ser til si el programa tiene que acceder a una base de datos en red o
bien si accedes en el mismo equipo a una base de datos.
Lo que hay que hacer es usar EditMode y comprobar si se est editando.
Veamos un ejemplo:

With Data1.Recordset
'Escribe el cdigo para buscar el registro a editar, etc.
'...
Do While .EditMode = dbEditInProgress
DoEvents
Loop
'Cuando llegue aqu, es que ya est libre...
.Edit
'...hacer los cambios al registro...
.Update
End With

Los valores que devuelve EditMode, pueden ser:

dbEditNone Si no se est editando.


dbEditInProgress Se est editando actualmente.
dbEditAdd Se ha aadido un registro con AddNew
y el registro actual todava est en el buffer.

8.- Seleccionar los registros que queremos en un Recordset

Para asignar a un Data (Recordset) los datos que quieras de una tabla, usa la
propiedad Recordsource.

Data1.RecordSource = "SELECT * FROM Tabla WHERE (condiciones de seleccin)


ORDER BY campo, [campo2]"
Data1.Refresh

El Refresh que no se te olvide, si no quieres que produzca error.


Condiciones de seleccin, sern las comparaciones (consulta) que quieres incluir
para la seleccin.
Por ejemplo, si quieres incluir todos los clientes de Mlaga que tengan coche,
clasificados por la poblacin:

Data1.RecordSource = "SELECT * FROM Clientes WHERE Provincia = 'Mlaga' AND


Coche = 'Si' ORDER BY [Poblacin]"

Fijate que Poblacin est entre corchetes, esto es necesario, porque la (o


acentuada) es un caracter "extrao" y se debe poner entre corchetes para que el
Jet lo entienda. Lo mismo hay que hacer si el nombre del campo incluye espacios.
Otra cosa a tener en cuenta es que si usas =, el contenido del campo "debe
coincidir exactamente", si en Provincia tienes algo como: Mlaga (Andaluca), no lo
"encontrar". Para que lo incluya tambin, cambia el signo igual por LIKE:

Data1.RecordSource = "SELECT * FROM Clientes WHERE Provincia LIKE '*Mlaga*'


AND Coche = 'Si' ORDER BY [Poblacin]"
Ms cosas, en la parte ORDER BY, se pueden incluir ms de un campo, separados
por comas.
El asterisco (*) que hay despus de SELECT, es para que incluya todos los campos
de la tabla.
Si slo quieres incluir algunos campos, especificalos en lugar del asterisco y
separalos con comas:

Data1.RecordSource = "SELECT Nombre,Apellidos, [Poblacin], Provincia, Coche


FROM Clientes WHERE Provincia LIKE 'Mlaga' AND Coche = 'Si' ORDER BY
[Poblacin]"

9.- Compactar una base de datos, usando cdigo VB (27/Feb)

Este es el cdigo que uso para compactar las bases de datos. Cosa que suelo hacer
bastante a menudo, sobre todo en las que uso en la empresa, que cambian a
diario.
Por aquello de la seguridad, mantengo dos copias: la anterior y la ltima. Ms vale
prevenir. Nunca se sabe cuando se cortar la luz o se quedar colgado el equipo...
as que, me curo en salud.

'Cerrar la base (esto slo si la tienes abierta...)


Db.Close
'Liberar memoria y "desligarla"
Set Db = Nothing
'
'Tomar el nombre sin la extensin
sTmp = ""
i = InStr(NombreBase, ".")
If i Then
p = i - 1
Else
p = Len(NombreBase)
End If
sTmp = Left$(NombreBase, p)
'Buscar \, para tomar el directorio (path)
For i = p To 1 Step -1
If Mid$(NombreBase, i, 1) = "\" Then
sTmp = Left$(NombreBase, i)
Exit For
End If
Next
If Right$(sTmp, 1) <> "\" Then
sTmp = sTmp & "\"
End If

'Todo este proceso es para estar seguro de que se quede una copia
'en caso de que falle la compactacin...
dBaseTmp = sTmp & "~dBase2.mdb"
If Len(Dir$(dBaseTmp)) Then Kill dBaseTmp
If Len(Dir$(sTmp & "~dBase1.mdb")) Then Kill sTmp & "~dBase1.mdb"
'Esta es la madre del cordero, se pueden usar otras "versiones", es
cuestin de adecuarte.
CompactDatabase NombreBase, dBaseTmp, dbLangSpanish, dbVersion20

'Guardar una copia de como estaba antes


Name NombreBase As sTmp & "~dBase1.mdb"
'Esta es la base ya compactada, as que asignar el nombre
Name dBaseTmp As NombreBase
'Borrar los ficheros LDB
If Len(Dir$(sTmp & "*.ldb")) Then Kill sTmp & "*.ldb"

10.- Crear una base de datos, usando cdigo VB (18/Abr)

Aprovechando que he puesto la colaboracin de Harvey Triana en esta pgina, pues


te voy a poner cmo crear una base desde dentro del propio Visual Basic.
Te recomiendo que veas el Proyecto Paso a Paso, en el que puedes tener el cdigo
completo y otras cosillas que aqu no se van a explicar.
Este es el listado del procedimiento que se encargar de crear la base de datos. Por
supuesto, debers cambiar los nombres de los campos y tipos de datos a tu
conveniencia, pero de esta forma, tienes algo por dnde empezar.

Private Sub CrearBase(sBase As String)


'Crear la base de datos indicada
'
Dim Db As Database
Dim Fd As Field
Dim Tb As New TableDef 'Definir una Tabla
Dim Idx As New Index 'Para crear un ndice
Dim i As Integer

'Crear base de datos, idioma espaol y para la versin 2.0 del Jet
de Access

'=====================================================================
===========
'Si vas a adaptar este programa para VB3, usa dbVersion11 en lugar
de dbVersion20

'=====================================================================
===========
Set Db = CreateDatabase(sBase, dbLangSpanish, dbVersion20)
'
'La constante dbVersion20 no aparece en la ayuda, en su lugar lo
hace la dbVersion25
'pero sa no est creada!!!
'
'Primero la tabla de las tareas
Set Tb = Db.CreateTableDef("Tareas")
'Vamos a crear cada uno de los campos
Set Fd = Tb.CreateField("ID", dbLong)
'Ahora vamos a asignar las propiedades de contador, etc.
Fd.Attributes = dbAutoIncrField Or dbUpdatableField Or
dbFixedField
Tb.Fields.Append Fd
'El resto de los campos
Set Fd = Tb.CreateField("Fecha", dbDate)
Tb.Fields.Append Fd
Set Fd = Tb.CreateField("Asunto", dbText, 255)
Tb.Fields.Append Fd
Set Fd = Tb.CreateField("Descripcion", dbMemo)
Tb.Fields.Append Fd
Set Fd = Tb.CreateField("FechaInicio", dbDate)
Tb.Fields.Append Fd
Set Fd = Tb.CreateField("FechaTermino", dbDate)
Tb.Fields.Append Fd
Set Fd = Tb.CreateField("Terminada", dbInteger)
Tb.Fields.Append Fd
'Creamos un ndice con el ID
Idx.Name = "PrimaryKey"
Idx.Unique = True
Idx.Primary = True
Idx.Fields = "ID"
Tb.Indexes.Append Idx
'Aadimos la tabla a la base
Db.TableDefs.Append Tb
'
'Creamos la otra tabla: Anotaciones
Set Tb = Db.CreateTableDef("Anotaciones")
'El campo ID, es el contador, etc.
Set Fd = Tb.CreateField("ID", dbLong)
Fd.Attributes = dbAutoIncrField Or dbUpdatableField Or
dbFixedField
Tb.Fields.Append Fd
'El resto de los campos
Set Fd = Tb.CreateField("Fecha", dbDate)
Tb.Fields.Append Fd
Set Fd = Tb.CreateField("Tema", dbText, 50)
Tb.Fields.Append Fd
Set Fd = Tb.CreateField("Asunto", dbText, 255)
Tb.Fields.Append Fd
Set Fd = Tb.CreateField("Medio", dbText, 255)
Tb.Fields.Append Fd
Set Fd = Tb.CreateField("Localizacion", dbText, 255)
Tb.Fields.Append Fd
Set Fd = Tb.CreateField("Descripcion", dbMemo)
Tb.Fields.Append Fd
Set Fd = Tb.CreateField("Detalle", dbLongBinary)
Tb.Fields.Append Fd
'Creamos un ndice con el ID
Set Idx = Nothing 'Quitar la referencia anterior
Idx.Name = "PrimaryKey"
Idx.Unique = True
Idx.Primary = True
Idx.Fields = "ID"
Tb.Indexes.Append Idx
'Aadimos la segunda tabla a la base
Db.TableDefs.Append Tb
'Cerramos la base
Db.Close

MsgBox "Nueva base de datos " & sBase & " creada.", vbInformation
End Sub
15.- Un mtodo rpido para efectuar una bsqueda (8/Sep)

En este ejemplo, uso un recordset para hacer la bsqueda, el nico requisito es que
tenga un campo llamado ID, que ser el que se devuelva con el dato encontrado.
La rutina acepta bsquedas hacia delante y hacia atrs, para buscar hacia atrs la
variable buscAtras ser True.
Se supone que adems tienes una variable (Db) con la base de datos que ests
usando.
Aqu tienes el cdigo...

Private Function BuscarEnBase(Optional ByVal sBusqueda As String = "")


As Long
'Devuelve el nmero de ID ( 5/Jul/97)
Dim sSQL As String
Dim lID As Long

On Local Error Resume Next

If Len(sBusqueda) Then
sSQL = "SELECT * FROM " & sTabla & " WHERE " & sBusqueda
Set RsBuscar = Db.OpenRecordset(sSQL, dbOpenSnapshot)
If Not RsBuscar.EOF Then
'Primera bsqueda
If buscAtras Then
RsBuscar.MoveLast
End If
lID = CLng(RsBuscar("ID"))
Else
lID = 0&
End If
Else
If buscAtras Then
RsBuscar.MovePrevious
Else
RsBuscar.MoveNext
End If
lID = CLng(RsBuscar("ID"))
End If
If (lID = 0&) Or (Err <> 0) Then
lID = 0&
'para que al seguir buscando se empiece por el primero
If buscAtras Then
RsBuscar.MoveLast
RsBuscar.MoveNext
Else
RsBuscar.MoveFirst
RsBuscar.MovePrevious
End If
End If
Err = 0
BuscarEnBase = lID
End Function

Esto es un ejemplo de cmo se llamara a esta funcin, usando el dilogo de buscar


y reemplazar:

iFFAtras = True
If gsBuscar(sBuscar, cFFAc_Buscar + cFFAc_Atras, "Buscar datos") >
cFFAc_IDLE Then
sBuscar = Trim$(sBuscar)
If Len(sBuscar) Then
buscAtras = iFFAtras
'buscCompleta = iFFCompleta
YaEstoyAqui = True
LblStatus(1) = "Buscando " & sBuscar & "..."
DoEvents
'Usar una rutina del tipo consulta (SQL)
qID = BuscarEnBase(Text1(ControlActual).DataField & " LIKE '"
& sBuscar & "*'")
If qID Then
Data1.Recordset.FindFirst "ID = " & CStr(qID)
If Data1.Recordset.NoMatch Then
qID = 0&
End If
End If
If qID = 0& Then
Beep
MsgBox "No se ha hallado el dato buscado en el campo: " _
& Text1(ControlActual).DataField, vbOK + vbInformation,
"Buscar"

16.- Enumerar las tablas de una base de datos (17/Sep)

Aqu te muestro como saber las tablas que existen en una base de datos. De esta
forma puedes buscar si la que necesitas est en la base especificada o bien puedes
usarla para abrir "cualquier" tabla de una BD.
Las rutinas sirven igual para VB3 (ejemplo aparte) y VB4 o superior.

Para probar esta rutina, en un form, aade un ListBox (List1) y un botn que al
pulsarlo llame a EnumerarTablas, debers cambiar la localizacin de la base de
datos por la que sea en tu equipo...

'Ejemplo para VB4 o superior


Private Sub EnumerarTablas()
Dim Db As Database
Dim Td As TableDef

List1.Clear
Set Db = OpenDatabase("D:\VB\Biblio.MDB")
For Each Td In Db.TableDefs
'Slo las tablas con atributo igual a CERO,
'son tablas normales
If Td.Attributes = 0 Then
List1.AddItem Td.Name
End If
Next
Db.Close
Set Db = Nothing
End Sub

'Para VB3: (en VB4 tambin se puede usar de esta forma)


Private Sub EnumerarTablas()
Dim INListTabl As Snapshot
Dim Db As Database

List1.Clear
Set Db = OpenDatabase("D:\VB\Biblio.MDB")
Set INListTabl = Db.ListTables()
INListTabl.MoveFirst
Do Until INListTabl.EOF
If INListTabl("Attributes") = 0 Then
List1.AddItem INListTabl("Name")
End If
Loop
Db.Close
Set Db = Nothing
End Sub

Si lo que quieres es slo comprobar si existe, en lugar de aadirla a un list, haces


una comparacin:

If Td.Name = miTabla Then


ExisteTabla = True
End If

17.- Un consejo si instalas VB6 SP4 para acceder a bases de datos de


Access 2000 (10/Nov/00)

Si has leido el artculo sobre el acceso a bases de datos de Access 2000 usando el
DAO Datacontrol (Acceder a bases de datos de Access 2000 con el VB5), veras que
haba un comentario sobre que no se puede usar ese control para acceder al nuevo
formato de las bases de datos de Access 2000...
Eso es cierto para el VB5 y para el VB6 pre-SP4, ya que el DAO Datacontrol que
se incluye con la nueva "revisin" del VB6 SI reconoce dicho formato, adems de
que carga de forma automtica la Microsoft DAO 3.6 Object Library, sin la cual
no se puede acceder a las bases del Access 2000.
Pero puedes llevarte una sorpresa si, (a pesar de indicar en las referencias que se
use el nuevo motor de bases de datos 3.6), el VB te avisa de que no hay datos que
mostrar...
Esto es cierto si lo que ests probando es un proyecto que ya tuvieras hecho
anteriormente, ya que con los nuevos proyectos no hay problemas... la razn es
que, (si miras con un editor de textos el contenido de un formulario de VB), lo que
se asigna a la propiedad Connect, para un control existente, es diferente del que
se asigna para uno nuevo... con lo cual, si quieres que tus proyectos pre-SP4
funcionen sin problemas y sin tener que quitar el control existente y aadirlo de
nuevo, (que sera la forma lgica de hacerlo), simplemente tendrs que cambiar la
asignacin que se le hace a dicha propiedad:

Nuevo: (vb6, SP4)


------
Begin VB.Data Data1
Caption = "Data1"
Connect = "Access 2000;"

Antiguo: (vb6 SP3... o anterior)


--------
Begin VB.Data Data1
Caption = "Data1"
Connect = "Access"

Es decir, cambia el "Access" por "Access 2000;"

Espero que este "truquillo" te alivie algn que otro quebradero de cabeza...

Nos vemos
Guillermo

Das könnte Ihnen auch gefallen