Beruflich Dokumente
Kultur Dokumente
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.
'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"
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)
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
-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)
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 & ";"
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.
Nunca usar SELECT * FROM TuTabla., especifica siempre que campos son
los que se quieren seleccionar en ese momento y que record o records
Que lo disfrutes!
Guillermo
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:
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 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.
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"
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;
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.
Seguramente cuando te explique la situacin en la que puede ser til saber lo que
te voy a contar, cambies de opinin.
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.
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).
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)
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.
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.
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.
-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.
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.
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:
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.
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.
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
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:
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.
Nota:
Si no quieres tragarte esta batallita, puedes pasar al cdigo "propuesto" usando la
funcin FechaSQL o bien pasar a ver el ejemplo prctico.
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)
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
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...)
Aqu te muestro las capturas de los dos formularios usados por los ejemplos.
Nos vemos.
Guillermo
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)
'---------------------------------------------------------------------
---------
' 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
'---------------------------------------------------------------------
---------
' 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
'---------------------------------------------------------------------
-----
' 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
'---------------------------------------------------------------------
---------
' 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
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...
'---------------------------------------------------------------------
---------
' 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
'---------------------------------------------------------------------
---------
' Procedimientos privados (no de eventos)
'---------------------------------------------------------------------
---------
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
'---------------------------------------------------------------------
-----
' 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
'---------------------------------------------------------------------
---------
' 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
http://www.elguille.info/vb/bases/ADO/indiceADO.htm#ado18Dic03
Bases de Datos usando DAO
y Visual Basic (clsico)
Para copiar/duplicar la estructura de una tabla en una base de datos Access, sigue
estos pasos:
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.
UPDATE tabla
SET nombre_campo = 'nuevo_valor'
WHERE opciones_a_tener_en_cuenta
Para ejecutar una orden SQL en una base de datos, usar la orden Execute en la
variable de una base de datos (Database)
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'"
MySnap.MoveFirst
Do Until MySnap.EOF
'Procesar los datos...
'
List1.AddItem MySnap("Cantante") & " " & MySnap("[Cancin]")
'...y dems datos
MySnap.MoveNext
Loop
MySnap.Close
Para cadenas:
Para nmeros:
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
Para asignar a un Data (Recordset) los datos que quieras de una tabla, usa la
propiedad Recordsource.
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.
'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
'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...
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
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"
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...
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
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 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:
Espero que este "truquillo" te alivie algn que otro quebradero de cabeza...
Nos vemos
Guillermo