0% encontró este documento útil (0 votos)
45 vistas15 páginas

Ejemplo de Acceso A Datos Con Una Base de Access Conexion A Datos

Este documento describe cómo acceder y manipular datos en una base de datos de Access usando ADO.NET. Explica cómo conectarse a la base de datos, mostrar las tablas y campos, crear y modificar registros, y mostrar los datos en un ListView. También incluye funciones para obtener los nombres de las tablas y campos, asignar la cabecera del ListView, y llenar el ListView con los datos. El formulario principal permite seleccionar una base de datos y muestra sus tablas.
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
45 vistas15 páginas

Ejemplo de Acceso A Datos Con Una Base de Access Conexion A Datos

Este documento describe cómo acceder y manipular datos en una base de datos de Access usando ADO.NET. Explica cómo conectarse a la base de datos, mostrar las tablas y campos, crear y modificar registros, y mostrar los datos en un ListView. También incluye funciones para obtener los nombres de las tablas y campos, asignar la cabecera del ListView, y llenar el ListView con los datos. El formulario principal permite seleccionar una base de datos y muestra sus tablas.
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
Está en la página 1/ 15

Ejemplo de acceso a datos con una base de Access

En este ejemplo veremos cómo acceder a una base de datos de Access, usando los objetos del
espacio de nombres OLEDB.
Los conceptos que se tratarán serán los siguientes:
- Crear una conexión a la base de datos.
- Mostrar las tablas de la base de datos indicada.
- Mostrar las columnas (o campos) de una tabla.
- Crear un DataAdapter para acceder a los datos devueltos por una consulta.
- Crear un DataSet basado en los datos asociados al DataAdapter.
- Crear nuevos registros.
- Modificar registros.
- Eliminar registros.
- Mostrar el contenido de la tabla en un control ListView.

Los objetos a usar en el proyecto.


Los objetos que vamos a usar en este ejemplo, en su gran mayoría residen en el
espacio de nombres System.Data.OleDb, aunque también se usarán objetos
genéricos (DataSet, DataRow, DataColumn) que residen en System.Data.
Para que nos sea más fácil declarar esos objetos, importaremos el espacio de
nombres System.Data.OleDb y dado que usaremos procedimientos genéricos,
estos los incluiremos en un módulo, al que llamaremos: ADONETUtil, veamos el
código con las declaraciones de los objetos que usaremos en el proyecto:

La variable CadenaConexion será la cadena con la que conectaremos a la base de


datos.
La variable CadenaSelect será el código SQL que usaremos para acceder a la tabla
de esa base de datos.
La variable ArchivoDatos será el nombre completo de la base de datos (Path
incluido).
La variable NombreTabla será el nombre que usaremos para identificar a los datos
que cargaremos en el objeto DataAdapter, ese nombre no tiene nada que ver con
el nombre de la tabla a la que vamos a acceder, es sólo un nombre que usaremos
con los distintos objetos de ADO.NET.
Conectar a una base de datos del tipo Access
Para conectar a la base de datos y crear los objetos que cargarán la tabla (definida
en la consulta SQL contenida en la variable CadenaSelect), vamos a crear un
procedimiento en el mismo módulo ADONETUtil:

A este procedimiento se le pueden indicar dos parámetros:


El primero indicará el nombre de la base de datos (path incluido), mientras que el
segundo será la instrucción SQL que nos permitirá acceder a la tabla. Cuando
veamos el código del formulario, tendremos ocasión de ver cómo se llama a este
procedimiento.

Lo que aquí tenemos que destacar es lo siguiente:


La cadena de conexión que tenemos que usar para conectar con la base de datos es
igual que la usada en las versiones anteriores de ADO, en esto no ha cambiado
nada; se le indica el tipo de proveedor y el nombre de la base de datos.
Creamos un nuevo objeto del tipo DataSet, que será el que nos permita acceder a
los datos.
Creamos un objeto del tipo DataAdapter, este será el que realmente nos permita
acceder a los datos físicos de la base de datos, primero para rellenar el DataSet y
posteriormente para actualizar los cambios realizados en la base de datos.
Es importante saber que los datos contenidos en el objeto DataSet están en
memoria y se acceden y manipulan de forma independiente, sin ninguna relación
directa con la base de datos original. Para que los cambios realizados en memoria
se puedan reflejar de forma permanente en la base de datos, tenemos que usar el
objeto DataAdapter.
Una vez creado el DataAdapter, al que se le indica la cadena de selección y la
cadena de conexión o el objeto del tipo Connection. En este caso, le he indicado el
objeto Connection, pero si no queremos crear una conexión permanente, también
podemos usar la misma cadena de conexión usada para crear el objeto
Connection en lugar de ese objeto.
Para poder realizar cambios en la base de datos, hay que indicarle al DataAdapter
los comandos SQL que habría que usar para añadir, modificar y eliminar, pero esos
comandos se pueden crear de forma automática creando un nuevo objeto del tipo
CommandBuilder, al que se le pasará como parámetro el adaptador que usará
dichos comandos, en realidad el objeto CommandBuilder no se usa nada más que
para que de esta forma se asignen dichos comandos de actualización de datos.
Si la tabla a la que queremos acceder tiene clave principal (cosa que es común o
debería serlo en todas las tablas), le indicamos mediante la asignación a la
propiedad MissingSchemaAction el valor de añadir con clave. Si no hacemos esta
asignación y la tabla tiene un campo que se incrementa automáticamente, no
podríamos crear varios registros (o filas) en memoria y después actualizar esas
nuevas filas de forma permanente, ya que nos daría un error de que hay duplicidad
en el campo (o columna) autoincremental.
Por último, llenamos el objeto DataSet con los datos del DataAdapter, el segundo
parámetro es el nombre que le vamos a dar a la tabla virtual (la que se crea en
memoria), si no le damos un nombre a esa tabla virtual del DataSet, se asignará
de forma predeterminada con el nombre Table. Es conveniente asignar un nombre,
ya que un objeto DataSet permite tener en memoria distintos datos, de la misma o
de otras tablas o consultas. Ese nombre será el que usaremos para acceder a esos
datos en memoria, ya que todos los accesos al contenido del DataSet, como he
comentado antes, se realizan de forma desconectada, es decir sin relación ninguna
con la base de datos física.

Los nombres de las tablas de una base de datos


Vamos a crear una función que devuelva una matriz (o array) del tipo String, con
los nombres de las tablas de la base de datos.
Antes de llamar a esta función tendremos que tener asignada la cadena de
conexión o, mejor aún, creada la conexión a la base de datos. Eso es lo que se hace
en las primeras líneas, si el objeto del tipo Connection no está creado, se crea un
nuevo objeto, usando la cadena de conexión. En caso de que esté creado el objeto,
se comprueba si está abierta dicha conexión, de no ser así, se abre.
A continuación asignamos un objeto del tipo DataTable con el "esquema" de las
tablas contenidas en la base de datos a la que apunta el objeto Connection. El
"truco" para conseguir los nombres de las tablas, está en el array restrictions,
particularmente en el cuarto elemento: "TABLE".
Recorremos el contenido del objeto DataTable y accedemos a cada una de las filas
cuyo elemento contenga la cadena "TABLE_NAME", el cual nos dará el nombre de
cada una de las tablas. Ese nombre lo asignamos a cada uno de los elementos del
array que estamos usando de forma interna, el cual será el que la función devuelva.

Los nombres de los campos (o columnas) de una tabla


Para saber los nombres de los campos o columnas de una tabla, usaremos el
contenido del objeto DataSet que hace referencia a la tabla que hemos cargado
mediante el DataAdapter, aunque también podría servirnos para acceder a
cualquier tabla virtual contenida en el DataSet.
También vamos a crear una función que devuelva una matriz del tipo String:
Asignar la cabecera de un control ListView con los
nombres de las columnas o campos de una tabla
Para terminar con el código del módulo ADONETUtil, vamos a ver unos métodos
que usaremos para asignar las columnas (o cabecera) de un ListView con los
nombres de las columnas o campos de la tabla que vamos a utilizar.
El método se llama AsignarCabeceraLista y tendrá dos implementaciones, una
indicando sólo el nombre del ListView y la otra en la que además se indicará un
control ComboBox en el cual se asignarán también esos nombres de las columnas
de la tabla.

Creo que tampoco necesita explicación, ya que lo único que se hace es llamar a la
función NombresColumnas y el contenido de ese array es el que se asigna a la
cabecera del ListView que se ha indicado en el parámetro.
En cuanto a la segunda implementación, se asigna al control ComboBox pasado
como parámetro esos mismos nombres.
Cuando veamos el código de los formularios, sabremos cuando usar una u otra
versión de este método.

Llenar un ListView con el contenido de una tabla


El siguiente método del módulo ADONETUtil rellenará un control ListView con los
datos de la tabla cargada en el objeto DataSet.
El código es también bastante simple, sólo quiero aclarar un detalle: La asignación
del objeto fila al TAG del elemento del ListView.
Realmente no es necesario, pero yo lo utilizo esa fila para acceder a cada uno de
los registros de la tabla, ya que al modificar los datos, sólo los reflejaremos en el
contenido del ListView y de esa forma sabremos a que fila estamos accediendo.
Cuando actualicemos los datos, usaremos el objeto que hemos guardado en la
propiedad Tag del objeto ListViewItem, y ese mismo objeto será el que usaremos
para eliminar una fila del DataSet.

Para terminar con el código del módulo, una función que usaremos para mostrar
información de la base de datos a la que estamos accediendo. En este caso es una
función que recibe como parámetro un path completo y devuelve sólo el nombre de
la base de datos:

Aquí se podrían haber usado funciones "clásicas" de Visual Basic, como InStr o
Mid, pero he preferido usar sus equivalentes de VB.NET, entre otras cosas porque
forman parte del objeto String. En el caso de LastIndexOf, busca la última
ocurrencia de la cadena indicada en el parámetro, si dicha cadena no forma parte
del objeto, (en este caso la variable path), se devuelve un valor -1 y en caso de
que si esté, se devuelve la posición, pero hay que tener en cuenta que la primera
posición está representada por el valor cero.

El formulario principal
Este es el aspecto del formulario principal (Form1) en tiempo de diseño:
este formulario permitirá que se arrastre una base de datos y ese nombre se
asignará a la caja de textos del nombre de la base de datos. Los controles tienen
asignados los valores de la propiedad Anchor para que se ajusten al tamaño que el
usuario quiera darle al formulario, esos detalles podremos verlo en el código
completo, ya que aquí sólo mostraré la parte que realmente interesa, es decir lo
que está relacionado con el acceso a la base de datos.

Empecemos por el código del botón "Mostrar tablas" y el evento producido cuando
se selecciona una tabla del ComboBox:
El primer procedimiento intercepta la pulsación en el botón y asigna los nombres de
las tablas en el combo.
El segundo, simplemente crea la cadena SQL que se usará para acceder a dicha
tabla.
El código que está comentado sirve para mostrar los nombres de los campos o
columnas de forma individual.

Cuando pulsamos en el botón "Mostrar", se muestra el contenido de la tabla


indicada, información que se obtiene del DataSet que contiene los datos en
memoria. Aunque, el código mostrado, realmente refresca esa información, esto lo
he hecho así para que al volver de modificar los datos, se pueda comprobar que los
datos realmente se han guardado en la base de datos.

Como podemos comprobar, aquí se llaman a los métodos del módulo ADONETUtil,
por tanto al principio del código del formulario debemos hacer la importación del
espacio de nombres de ese módulo para no tener que especificarlo cada vez que
queramos acceder a cualquiera de los procedimientos o variables en el declarado:
ADONET1 es el nombre del "espacio de nombres" (Namespace) de este proyecto.

Para acabar con el código de este formulario, veamos los eventos que se producen
al cargarse el formulario (Load) y al cerrarse (Closing), además del evento
producido al pulsar en el botón "Mostrar", el cual mostrará el formulario en el que
se editan los datos de la tabla indicada.

En el evento Load, asignamos los valores iniciales, en el evento Closing,


comprobamos si tenemos la conexión abierta y de ser así la cerramos, debido a que
puede ser que se cierre el formulario sin necesidad de haber creado dicho objeto,
interceptamos el error que se pudiera producir.
Por otro lado, cuando pulsamos en el botón Modificar, creamos una nueva
instancia del formulario en el que modificaremos la información y asignamos los
valores de la base de datos y la cadena SQL que usaremos para conectar, esto lo
hago así por si se pulsa en dicho botón sin haber creado la conexión.

El formulario de edición de datos


Para terminar con este ejemplo de acceso a datos usando ADO.NET, veamos el
formulario que usaremos para modificar la información de la base de datos.

El aspecto del formulario (FORM2) será el mostrado en la siguiente imagen:


El formulario de introducción de datos

En este formulario, los controles también están "anclados" para que se adapten al
tamaño que el usuario quiera darle al formulario.

Empecemos por las variables o propiedades que este formulario expone al mundo
externo:

También usamos el Imports para poder usar los procedimientos del módulo
ADONETUtil y declaramos dos propiedades: DataSource y CommandString, las
cuales usaremos para acceder a la base de datos.
La variable lwItemActual hará referencia al elemento del ListView que esté
actualmente seleccionado.

En el evento Load del formulario, se asignarán algunos valores por defecto y se


mostrará el contenido de la tabla indicada en el ListView:
Cuando seleccionamos un nuevo elemento del ListView, se asigna la variable que
contiene el elemento actual y se muestra la información o datos de dicha fila.

Como podemos comprobar, el procedimiento ListView1_Click realmente


intercepta dos eventos, el evento Click del ListView y el evento
SelectedIndexChanged del Combo, de forma que se muestre la información del
campo seleccionado en el ComboBox. De eso se encarga el procedimiento
MostrarCampo:

Este procedimiento simplemente muestra el contenido del campo que está


seleccionado en el control ComboBox.
Asignar los datos
Cuando pulsamos en el botón Asignar, el cual hemos asignado como botón
"Aceptar" del formulario, es decir el que tomará el foco cuando pulsemos la tecla
Intro, se asignarán los cambios realizados al campo (o columna) que estamos
editando:

Eliminar una fila


Cuando pulsamos en el botón Eliminar, borramos la fila seleccionada del ListView
y también esa misma fila del DataSet, y como comenté anteriormente, en la
propiedad Tag del elemento del ListView tenemos una referencia a la fila de
datos, por tanto usamos ese objeto para eliminar la fila de la colección Rows del
objeto DataSet, ya que el método Remove de la colección Rows acepta como
parámetro un objeto del tipo DataRow:

Crear una nueva fila (o registro)


Para crear un nuevo registro (o fila), tendremos que asignar unos valores nulos o
por defecto a una nueva fila creada en la memoria, después esa fila la añadiremos
a la tabla que mantenemos en el DataSet.
Debido a que algunos campos no permiten valores nulos, tendremos que tener ese
detalle en cuenta y de ser así, asignaremos un valor adecuado al tipo de datos de
cada una de las columnas (o campos) del registro que hemos creado, esto lo
conseguimos comprobando el tipo de datos de cada una de las columnas de la
nueva fila. Hay que tener en cuenta que los tipos de datos se guardan usando el
que se define en .NET Framework, no los tipos que utiliza Visual Basic, por tanto,
para saber si el tipo de una columna es del tipo Integer, tendremos que usar
System.Int32, de todas formas, para saber el tipo de dato, (que lo da la
propiedad DataType del objeto DataColumn), he utilizado la conversión a cadena
generada por ToString, por lo que dicho tipo se convierte en el formato
"System.Tipo", veamos el código para aclarar todo este lío:
Private Sub btnNuevo_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles btnNuevo.Click
' Añadir una nueva fila (o registro)
Dim fila As Data.DataRow
Dim i As Integer
Dim lwItem As ListViewItem
Dim columna As Data.DataColumn
'
fila = dbDataSet.Tables(NombreTabla).NewRow
fila.BeginEdit()
For i = 0 To dbDataSet.Tables(NombreTabla).Columns.Count - 1
columna = dbDataSet.Tables(NombreTabla).Columns(i)
'Debug.WriteLine(columna.DataType.ToString)
If columna.AutoIncrement = False Then
Select Case columna.DataType.ToString
Case "System.String"
fila(i) = columna.ColumnName
Case "System.Boolean"
fila(i) = False
Case "System.Byte", "System.SByte"
fila(i) = CByte(0)
Case "System.Char"
fila(i) = " "c
Case "System.DateTime", "System.TimeSpam"
fila(i) = Now
Case "System.Decimal", "System.Double",
"System.Single"
fila(i) = 0
Case Else
'Case "System.Int32","System.UInt32"
' fila(i) = 0
If
columna.DataType.ToString.IndexOf("System.Int") > -1 Then
fila(i) = 0
ElseIf
columna.DataType.ToString.IndexOf("System.UInt") > -1 Then
fila(i) = 0
End If
End Select
End If
Next
fila.EndEdit()
' Añadir la fila a la tabla
dbDataSet.Tables(NombreTabla).Rows.Add(fila)
'
' Mostrar la nueva fila en el ListView
For i = 0 To ListView1.Columns.Count - 1
If i = 0 Then
lwItem = ListView1.Items.Add(fila(i).ToString)
lwItem.Tag = fila
Else
lwItem.SubItems.Add(fila(i).ToString)
End If
Next
'
End Sub

Lo que en este evento hacemos es crear una nueva fila mediante el método
NewRow, asignamos los campos (o columnas) de dicha fila y la añadimos a la
colección Rows de la tabla. Hay que tener en cuenta que al crear una nueva fila
con NewRow no se añade a la colección de filas (o registros), simplemente se
devuelve un objeto que está preparado para que se le asignen los datos
correspondientes. Antes de asignar cada una de las columnas, comprobamos si
dicha columna está marcada como autoincremental, de ser así, no asignamos nada,
ya que es el propio DataAdapter el que se encarga de asignar el valor de dicha
columna.

En este punto quiero hacer una aclaración, debido a que los datos los estamos
asignando a un objeto que mantiene la información en la memoria, si existen varias
aplicaciones que acceden a la misma base de datos y cada una de ellas crea nuevas
filas, el valor asignado al campo (o columna) AutoIncrement puede que no sea el
que definitivamente tenga en la base de datos. Por tanto, debemos tener esto
presente si el valor asignado a esa columna lo utilizamos para otros menesteres.

Una vez que hemos añadido la nueva fila a la tabla, asignamos el contenido de la
misma al ListView y también asignamos a la propiedad Tag una referencia a dicha
fila.

Guardar la información en la base de datos


Por último vamos a ver cómo pasar la información mantenida en la memoria a la
base de datos, con idea de que los cambios realizados se queden guardados
permanentemente.
Esto lo hacemos cuando el usuario pulsa en el botón de "Actualizar Base" y el
código usado es el siguiente:

Private Sub btnActualizarBase_Click(ByVal sender As System.Object,


_
ByVal e As System.EventArgs) _
Handles btnActualizarBase.Click
' Actualizar la base de datos con los cambios realizados
Dim fila As Data.DataRow
Dim i, j As Integer
Dim lwItem As ListViewItem
Dim columna As Data.DataColumn
'
lblInfo.Tag = lblInfo.Text
lblInfo.Text = "Actualizando los datos..."
lblInfo.Refresh()
Try
For i = 0 To ListView1.Items.Count - 1
lwItem = ListView1.Items(i)
fila = CType(ListView1.Items(i).Tag, Data.DataRow)
fila.BeginEdit()
j = 0
For Each columna In
dbDataSet.Tables(NombreTabla).Columns
If j = 0 Then
If columna.AutoIncrement = False Then
fila(j) = lwItem.Text
End If
Else
If columna.AutoIncrement = False Then
fila(columna.ColumnName) =
lwItem.SubItems(j).Text
End If
End If
'
j += 1
Next
fila.EndEdit()
Next
'
'
dbDataAdapter.Update(dbDataSet, NombreTabla)
dbDataSet.AcceptChanges()
'
'
lblInfo.Text = CStr(lblInfo.Tag)
Catch errActualizar As Exception
lblInfo.Text = errActualizar.Message
MsgBox(errActualizar.Message)
End Try
End Sub

En este procedimiento actualizamos la información de cada una de las filas, para


ello usamos el objeto almacenado en la propiedad Tag de cada uno de los
elementos del ListView que como recordarás era en realidad una referencia a cada
una de las filas de la tabla, (realmente un objeto del tipo DataRow). Recorremos
cada una de las columnas y asignamos sólo los datos si no es una columna del tipo
AutoIncrement.
La llamada a los métodos BeginEdit y EndEdit de cada fila es para que no se
produzcan los eventos asociados a un objeto de este tipo, no son realmente
necesarios para poder cambiar los contenidos de las columnas.

Una vez que hemos asignado todos los datos del ListView, llamamos al método
Update del DataAdapter, este método es el que realmente hace que los datos se
guarden físicamente en la base de datos.
Después llamamos al método AcceptChanges del objeto DataSet para que "sepa"
que hemos aceptado la nueva información y marque la información de forma que
sean iguales a los datos que tiene la base de datos real.

También podría gustarte