Anda di halaman 1dari 5

Ejemplo bsico de acceso a datos con ADO.

NET a una base de datos de Access

Introduccin Este artculo en realidad consta de varias partes, aunque todas esas partes formarn un todo, y ese todo es un ejemplo muy bsico de cmo acceder a una base de datos de Access usando ADO.NET, permitiendo navegar entre los registros, aadir nuevos datos y modificar los existentes, NO he usado ningn botn de eliminar, pero eso es algo que puedes hacer fcilmente. Estructura de la base de datos de ejemplo
La base de datos se incluye en los links, y hay dos, una con varios datos que he hecho de prueba y otra vaca con solo la definicin de la tabla de forma que puedas ver cmo manejarte cuando no hay ningn dato. La base de datos solo tiene una tabla llamada Prueba. La estructura de esa tabla es como sigue:

Nombre campo ID Nombre e-mail FechaAlta Comentario El formulario para acceder a la base de datos

Tipo Numrico Texto Texto Fecha/Hora Memo

Comentario Clave principal autonumrica 50 caracteres 128 caracteres -

La aplicacin de ejemplo tiene un formulario con el siguiente aspecto:

El formulario de la aplicacin de ejemplo


Como vemos, este formulario utiliza los campos que tiene la tabla que vamos a usar, por tanto, si vas a usar otra tabla diferente a la usada en el ejemplo, tendrs que crear tu propio diseo del formulario. En el cdigo he intentado separar el cdigo que depende de los campos, de forma que te resulte fcil de modificar. Empezando por arriba, tenemos un botn para conectarnos a la base de datos (Conectar a la base) En ese botn se crea la conexin a la base de datos y se asigna el DataAdapter que usaremos para conectar directamente con la base de datos. Por tanto ser en el cdigo de ese botn donde tendrs que escribir el cdigo necesario para realizar la conexin, cargar los datos en la tabla (DataTable) y empezar a mostrar los datos. Tambin se comprueba si la base de datos indicada existe o no. La caja de textos que hay junto al botn "Conectar a la base" servir para indicar el path de la base de datos, el valor inicial lo asignamos en el evento Form_Load y ah ser donde debes indicar el path en el que la has copiado, por defecto tiene el path que he usado yo. El botn de Examinar nos permitir localizar la base de datos, cosa que tendremos que hacer antes de pulsar en Conectar a la base. En el GroupBox tenemos los controles para mostrar los datos, navegar entre las filas, actualiza y crear nuevos registros. Los botones de navegacin (o movimiento) nos servirn para ir a los distintos registros: Primero, anterior, siguiente y ltimo. El botn de Actualizar lo usaremos para actualizar los datos del registro actual. El botn Nuevo lo usaremos para aadir un nuevo registro. Cuando pulsamos en ese botn, se usarn los datos que actualmente tengamos en las cajas de textos, salvo el ID, ya que en la tabla de ejemplo es autonumrico, y por tanto se crea solo. El resto de controles simplemente los usamos para mostrar los datos.

Las variables comunes para todo el cdigo

A lo largo de la aplicacin usaremos algunas variables comunes, en realidad son tres: dt del tipo DataTable, ser la tabla a la que asignaremos los datos de la tabla de la base de datos da del tipo OleDbDataAdapter, ser el adaptador que nos permitir acceder a la base de datos, para leer los datos y actualizarlos. fila del tipo Integer, ser el ndice de la fila actual, con idea de saber cual ser la siguiente, la anterior o la fila que queremos actualizar. Este es el cdigo para Visual Basic, (el de C# lo puedes ver en este link):
Private dt As DataTable Private da As OleDbDataAdapter Private fila As Integer

Form_Load: Deshabilitar los controles y asignar el path de la base de datos Al empezar la aplicacin, en el evento Form_Load deshabilitaremos los controles que estn en el GroupBox, adems asignaremos el path inicial de la base de datos, que como te he comentado antes, debes indicar el que has usado, ya que seguramente ser diferente al que he usado yo. Este es el cdigo para Visual Basic, (el de C# lo puedes ver en este link):
Private Sub Form1_Load( _ ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles MyBase.Load ' Limpiar los controles del GroupBox y ' deshabilitarlos hasta que se conecte a la base de datos ' For Each c As Control In Me.GroupBox1.Controls ' Limpiar los textbox If TypeOf c Is TextBox Then c.Text = "" End If ' Deshabilitarlos c.Enabled = False Next Me.GroupBox1.Enabled = False Me.GroupBox1.Text = "Debes conectar antes de usar los datos" ' ' El nombre de la base de datos: ' (poner el path real de la base de datos de prueba) Me.txtBase.Text = "E:\gsCodigo_00\VS.NET\vb y cs\acceso a datos\ejemplo_elGuille\db2000.mdb" End Sub

Conectar a la base de datos Para conectar con la base de datos y obtener los datos necesitamos una cadena de conexin que indique que tipo de base de datos vamos a usar y dnde est localizada (el path). Los datos los obtendremos mediante una cadena de seleccin (SELECT). En el siguiente cdigo comprobamos tambin si la base de datos existe fsicamente, y si no existe (o se produce un error al comprobarlo), posicionamos el cursor en la caja de textos que indica el path de la base de datos y salimos del mtodo. En este caso, el nombre del mtodo se llama btnConectar_Click. Este sera parte del cdigo de ese evento para Visual Basic (el de C# lo tienes en este link):
' Conectar y mostrar los datos ' Comprobar si existe la bse de datos Try If System.IO.File.Exists(txtBase.Text) = False Then MessageBox.Show("No existe la base de datos indicada") txtBase.Focus() Exit Sub End If Catch ex As Exception MessageBox.Show("ERROR: " & ex.Message & vbCrLf & "Seguramente porque no existe la base de datos") txtBase.Focus() Exit Sub End Try ' ' La cadena de conexin Dim sCnn As String = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" & txtBase.Text ' La cadena de seleccin Dim sSel As String = "SELECT * FROM Prueba ORDER BY ID"

Obtener todos los datos (o los indicados en la cadena SELECT) y guardarlos en un objeto del tipo DataTable
Una vez que sabemos que la base de datos existe, crearemos los objetos que nos permitirn acceder a la base de datos (mediante el DataAdapter), y llenaremos el objeto DataTable con los datos que hayamos indicado en la cadena de seleccin. Crearemos los comandos de conexin, (por medio del OleDbCommandBuilder) y los asignaremos a los objetos correspondientes del adaptador, esto en realidad no es necesario, pero algunas veces me ha dado error al no hacerlo, as que... mejor estar seguros de que se asignan!. Debido a que la tabla de ejemplo utiliza un campo autoincremental, tendremos que asignar a la propiedad MissingSchemaAction el valor AddWithKey, de esta forma, al aadir nuevos registros se incrementar el valor del ID. En la tabla de ejemplo, estamos usando un campo que contiene caracteres que pueden ser conflictivos, en este caso es simplemente un guin, pero podra ser una vocal acentuada, una ee o contener espacios, en este caso lo que hacemos es indicar en el objeto del tipo CommandBuilder que utilice prefijo y sufijo para "envolver" automticamente esos campos conflictivos, esa indicacin la hacemos mediante las propiedades QuotePrefix y QuoteSufix.

Por ltimo creamos el nuevo objeto del tipo DataTable, que ser el que usemos con el mtodo Fill del adaptador, al usar el mtodo Fill, ser cuando se conecte con la base de datos y asigne a la tabla los datos indicados en la cadena de seleccin (SELECT). En este ejemplo, le indico que traiga todos los datos, pero tambin podra haber seleccionado con una clusula WHERE otros diferentes. Por ejemplo, si queremos solo los datos de los registros entre dos fechas podamos hacerlo de esta forma: sSel = "SELECT * FROM Prueba WHERE (FechaAlta >= #2006/01/05# AND FechaAlta <= #2006/01/06#)"

Otra cosa importante que debemos tener en cuenta con el cdigo de seleccin (SELECT) es que si en lugar de indicar un asterisco para que se utilicen todos los campos ( SELECT * ), indicamos solo los campos que nos interesan, en las actualizaciones y lecturas de datos solo podremos incluir los campos indicados. Por ejemplo, si hacemos: SELECT ID, Nombre FROM Prueba, tan solo tendremos acceso a esos dos campos, y cualquier intento de acceder a otros campos (aunque sean vlidos y existan en la tabla) dar error. Finalmente habilitamos nuevamente los controles que estn en el GroupBox para que podamos navegar, aadir, actualizar y escribir en las cajas de texto. Tambin comprobamos si hay datos, y en caso de que haya mostramos el primer registro, para ello usamos el mtodo del evento Click del botn de ir al primero. Si no hay datos, deshabilitamos el botn de Actualizar. Tambin podramos haber deshabilitado los botones de movimiento, pero... eso te lo dejo para que lo hagas t, como pista para volver a habilitarlos, decirte que cuando aadas uno nuevo, ya deberan estar habilitados... o casi. Este es el cdigo para Visual Basic, (el de C# lo tienes en este link):
' Comprobar si hay algn error Try ' Crear un nuevo objeto del tipo DataAdapter da = New OleDbDataAdapter(sSel, sCnn) ' Crear los comandos de insertar, actualizar y eliminar Dim cb As New OleDbCommandBuilder(da) ' Como hay campos con caracteres especiales, ' al usarlos incluirlos entre corchetes. cb.QuotePrefix = "[" cb.QuoteSuffix = "]" ' Asignar los comandos al DataAdapter ' (se supone que lo hace automticamente, pero...) da.UpdateCommand = cb.GetUpdateCommand da.InsertCommand = cb.GetInsertCommand da.DeleteCommand = cb.GetDeleteCommand ' ' Esta base de datos usa el ID con valores automticos da.MissingSchemaAction = MissingSchemaAction.AddWithKey ' dt = New DataTable ' Llenar la tabla con los datos indicados da.Fill(dt) ' ' Habilitar los controles For Each c As Control In Me.GroupBox1.Controls c.Enabled = True Next Me.GroupBox1.Enabled = True Me.GroupBox1.Text = "Conexin realizada" ' Y mostrar el primer registro If dt.Rows.Count > 0 Then btnFirst_Click(Nothing, Nothing) Else fila = -1 btnActualizar.Enabled = False End If Catch ex As Exception MessageBox.Show("ERROR al conectar o recuperar los datos:" & vbCrLf & _ ex.Message, "Conectar con la base", _ MessageBoxButtons.OK, MessageBoxIcon.Error) End Try

Aadir nuevos registros


Para aadir nuevos registros, lo primero que tenemos que hacer es crear una nueva fila. Para ello utilizamos el mtodo NewRow del objeto DataTable. Al usar ese mtodo, nos aseguramos que la nueva fila creada tiene todos los datos sobre la estructura de la tabla (o de la seleccin que hemos hecho), de forma que podamos asignar los campos, etc. La asignacin de los campos la hacemos mediante el mtodo asignarDatos, aunque podramos haberlo hecho directamente. El hacerlo mediante ese mtodo es para que nos resulte ms cmo adaptar este ejemplo a otra tabla diferente a la que yo propongo, ya que en ese mtodo haramos todas las asignaciones que debamos hacer, salvo la del campo ID ya que al ser autonumrico no podemos asignarle un valor, porque ese valor lo asignar automticamente ADO.NET. Una vez que la fila tiene asignados los valores de los campos, la aadimos a las fila de la tabla. Esto es necesario, ya que el mtodo NewRow solo crea una fila, pero no la "relaciona" (o aade) a la tabla actual. Finalmente actualizamos los datos mediante el mtodo Update del adaptador. En realidad no hace falta hacer esa actualizacin en este preciso momento, pero si no lo hacemos, debemos aadir otro botn para que los datos se asignen a la base de datos, ya que al aadir un nuevo valor a la tabla, lo haremos en la "copia" que tenemos localmente en memoria, y no directamente en la base de datos, como ocurra, por ejemplo, con VB6 y los Recordsets. Una vez actualizados los datos en la base de datos, le indicamos a la tabla que acepte los cambios que hayamos hecho, de forma que quede sincronizada nuevamente. Esto es necesario, ya que si no lo hacemos, la tabla mantendr los cambios que hayamos hecho y si nuevamente "sincronizamos" esos datos con la base real, se podran producir errores. Es importante que sepamos que cuando llamamos al mtodo Update del adaptador, se realizan todas las actualizaciones, es decir, no solo aadir nuevos datos, como "se supone" que es lo que hace este mtodo, sino que si hubisemos eliminado filas, o modificado algunas, esas modificaciones tambin se reflejaran en la base de datos.

Debido a cmo funcionan los campos autincrementales, para asegurarnos de que en realidad el valor de ese ID se actualiza correctamente, si es el primer registro que aadimos (o vale cero, como es la comprobacin que hacemos aqu), deberamos volver a leer los datos reales de la base de datos (que ser despus de haber aadido el primer registro) con idea de que ese ID tenga el valor correcto. Esto no es necesario en los siguientes datos que vayamos aadiendo, ya que en otros casos el valor del ID se asignar correctamente. Como ves, tambin controlamos los errores que se puedan producir... nunca est de ms! Este cdigo es para Visual Basic, (el de C# lo tienes en este link):
Private Sub btnNuevo_Click( _ ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles btnNuevo.Click ' Crear un nuevo registro Dim dr As DataRow = dt.NewRow() ' Asignar los datos de los textbox a la fila asignarDatos(dr) ' Aadir la nueva fila a la tabla dt.Rows.Add(dr) ' Guardar fsicamente los datos en la base Try da.Update(dt) dt.AcceptChanges() ' Si es el primer registro de la base, ' volver a leer los datos para actualizar los IDs If CInt("0" & dr("ID").ToString) = 0 Then dt = New DataTable da.Fill(dt) End If ' Posicionarlo en la ltima fila btnLast_Click(Nothing, Nothing) Catch ex As DBConcurrencyException MessageBox.Show("Error de concurrencia:" & vbCrLf & ex.Message) Catch ex As Exception MessageBox.Show(ex.Message) End Try End Sub Private Sub asignarDatos(ByVal dr As DataRow) ' Usar los datos que hay en los textbox dr("Nombre") = txtNombre.Text dr("e-mail") = txtEmail.Text dr("FechaAlta") = txtFechaAlta.Text dr("Comentario") = txtComentario.Text End Sub

Actualizar los registros modificados La actualizacin de los datos, es decir, cuando modificamos un registro (o fila) y queremos que esos datos se guarden, es muy simple. En el cdigo del mtodo de actualizar, primero comprobamos que el valor de la variable fila sea vlido, es decir, est dentro del rango de filas que tiene el DataTable. Si es as, asignamos a una variable del tipo DataRow la fila en cuestin y posteriormente llamamos al mtodo asignarDatos que vimos antes, que como sabes es el que se encarga de asignar las cajas de texto a los campos correspondientes. Una vez que la fila tiene los nuevos datos, volvemos a llamar al mtodo Update del adaptador, como coment antes, esta llamada al mtodo Update solo es necesario si queremos asignar directamente los datos en la base, es decir, hacer que los cambios se hagan en ese preciso momento. Tambin encerramos esa actualizacin dentro de un Try/Catch para detectar los errores que se puedan producir. Este es el cdigo para Visual Basic, (el de C# lo tienes en este link):
Private Sub btnActualizar_Click( _ ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles btnActualizar.Click ' Actualizar los datos en la fila actual If fila < 0 OrElse fila > dt.Rows.Count - 1 Then Exit Sub Dim dr As DataRow = dt.Rows(fila) ' Asignar los datos de los textbox a la fila asignarDatos(dr) ' Guardar fsicamente los datos en la base Try da.Update(dt) dt.AcceptChanges() Catch ex As DBConcurrencyException MessageBox.Show("Error de concurrencia:" & vbCrLf & ex.Message) Catch ex As Exception MessageBox.Show(ex.Message) End Try End Sub

Moverse entre registros, con comandos para ir al primero, al ltimo, al anterior y al siguiente Para movernos entre los registros usaremos cuatro mtodos, uno para ir al principio, otro para ir al final, otro para ir al registro anterior y otro para el siguiente. En estos cuatro mtodos usaremos un mtodo extra que ser el que se encargue de comprobar si todo est correcto (o casi) y de mostrar los datos adecuados en cada caja de texto. Al igual que antes con el mtodo asignarDatos, lo he puesto por separado, entre otras cosas para facilitar la modificacin del cdigo para otras tablas. Tambin para que no haya que estar repitiendo en el resto de los mtodos las comprobaciones de que el valor de fila indicado est dentro del rango vlido. Ese rango debe estar entre cero para el primer registro y uno menos del nmero total de filas para el ltimo, por tanto, si el valor del nmero de la fila indicado no es correcto, no hacemos nada, simplemente salimos del mtodo.

En caso de que sigamos, quiere decir que es un valor correcto, por tanto leemos esa fila (asignndola a una variable de tipo DataRow) y asignamos los valores a las cajas de texto, en este caso si que usamos el valor del campo ID con idea de que veamos ese valor. Por ltimo habilitamos el botn de actualizar, ya que se supone que hay datos. El cdigo mostrado es para Visual Basic, (el de C# lo tienes en este link):
Private Sub mostrarDatos(ByVal f As Integer) Dim uf As Integer = dt.Rows.Count - 1 If f < 0 OrElse uf < 0 Then Exit Sub ' Dim dr As DataRow = dt.Rows(f) txtID.Text = dr("ID").ToString txtNombre.Text = dr("Nombre").ToString txtEmail.Text = dr("e-mail").ToString txtFechaAlta.Text = dr("FechaAlta").ToString txtComentario.Text = dr("Comentario").ToString ' btnActualizar.Enabled = True End Sub

Los cuatro mtodos para movernos son los siguientes, veamos que es lo que hacemos en cada uno de ellos, aunque creo que viendo el cdigo queda clara la intencin. Nota: Como veremos en el cdigo, en realidad no hace falta pasarle ningn parmetro al mtodo mostrarDatos, ya que al tener la variable fila disponible en todo el formulario, pues podramos usar esa variable, pero... lo dejo as por si se te ocurre hacer cambios y no usar esa variable, que hay gente que no le gusta usar variables "globales" al formulario o clase... Para ir al primero, simplemente asignamos cero a la variable de la fila actual y llamamos al mtodo de mostrar los datos.
Private Sub btnFirst_Click( _ ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles btnFirst.Click ' Posicionarse en la primera fila fila = 0 ' Mostrar los datos de la fila indicada mostrarDatos(fila) End Sub

Para ir al ltimo, averiguamos cual es la ltima fila, que como vemos es el valor devuelto por la propiedad Count de la coleccin de filas (Rows), menos uno, ya que como sabemos todos los arrays y colecciones de .NET siempre empiezan con el ndice cero.
Private Sub btnLast_Click( _ ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles btnLast.Click ' Posicionarse en la ltima fila fila = dt.Rows.Count - 1 ' Mostrar los datos de la fila indicada mostrarDatos(fila) End Sub

Para ir al anterior simplemente le restamos uno al valor de la fila actual, pero debemos hacer una comprobacin de que no sea menor de cero, ya que es posible que estemos en el primer registro y pulsemos en el botn de ir al anterior. En caso de que estemos en el primero, seguiremos en ese mismo registro.
Private Sub btnPrev_Click( _ ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles btnPrev.Click ' Posicionarse en la fila anterior fila = fila - 1 If fila < 0 Then fila = 0 ' Mostrar los datos de la fila indicada mostrarDatos(fila) End Sub

Por ltimo, para ir al siguiente, hacemos lo mismo que antes, pero en lugar de restar uno, lo que hacemos es aadir uno al valor de la fila actual, y en el caso de que sea mayor que la ltima fila, pues nos quedamos en esa ltima fila.
Private Sub btnNext_Click( _ ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles btnNext.Click ' Posicionarse en la fila siguiente Dim uf As Integer = dt.Rows.Count - 1 fila = fila + 1 If fila > uf Then fila = uf ' Mostrar los datos de la fila indicada mostrarDatos(fila) End Sub

Anda mungkin juga menyukai