Vous êtes sur la page 1sur 18

Agenda telefnica en Visual Basic .

NET
Usando el Asistente para Formulario de Datos para crear una conexin con una base de datos de Microsoft Access
Explicacin del ejercicio: La base de este ejercicio est en crear una conexin entre una base de datos de Microsoft Access y un formulario de datos (DataForm) de Visual Basic .NET. De esta manera se consigue mostrar en el programa los registros almacenados en la base de datos de Access. En este sitio web ya existe un tutorial en la seccin de ADO.NET llamado "Ejemplo de acceso a datos con una base de Access" (autor: Guille) que propone realizar todo sto mediante cdigo escrito "a mano", pero exige un nivel de conocimientos avanzado, por ello propongo este otro ejercicio en el que es muy poco el cdigo que debe escribir el usuario, aunque s conviene entenderlo para poder retocarlo a nuestro gusto. Los pasos que debemos seguir son: - crear una base de datos de Microsoft Access que tenga al menos una tabla (no es imprescindible nada ms en la base de datos) con los campos que nos interesen. En el ejercicio son ID, Nombre,Direccin, Telfono 1 y Telfono 2. Podemos dejar la tabla (aqu llamada tbAgenda) en blanco, sin registros, y agregarlos directamente desde la aplicacin de Visual Basic, pero he comprobado que es ms prctico rellenar desde Access unos pocos registros (bastan 3 o 4) para que, al probar la aplicacin, sea ms ilustrativo cmo se cargan los datos en el formulario de datos. - comenzar un proyecto nuevo de Visual Basic .NET, del tipo Aplicacin de Windows. - nos olvidamos por ahora del formulario creado por defecto Form1.vb. - agregar un elemento nuevo, eligiendo el "Asistente para formulario de datos", lo que inicia un asistente. - elegir el conjunto de datos que deseas utilizar: creamos un nuevo conjunto de datos al que ponemos nombre. - elegir una conexin de datos: desde el botn "Nueva conexin" abrimos las "Propiedades el vnculo de datos" con 4 pestaas: - proveedor: elegimos Microsoft Jet 4.0 OLEDB Provider. - conexin: buscamos la base de datos de Access para que aparezca en el cuadro "Seleccione el nombre de una base de datos". Mediante el botn "Probar conexin"

sabremos si es factible realizarla. - el resto de opciones las dejamos como estn. - elegir tablas de la base de datos: elegimos tbAgenda (o el nombre que le hayamos dado). - elegir tablas y columnas para mostrar en el formulario: marcamos las deseadas. - elegir el estilo de presentacin: Registro nico en controles individuales, y marcamos aquellos controles que deseamos que aparezcan como botones de comando en el formulario. - finalizar, y podemos incluir la contrasea en el cuadro de dilogo que nos pregunta sobre ello (por el momento nos despreocupamos de las medidas de seguridad). - ahora slo queda modificar el diseo del formulario de datos a nuestro gusto, recordando que es imprescindible cambiar el objeto inicial del proyecto que, por defecto, estar configurado en Form1.vb y debe ser el formulario de datos (aqu DataForm1.vb). Incluso podemos eliminar el formulario Form1.vb despus de ello.

NOTA acerca de ordenar los datos y los comandos SQL


Si deseamos que los registros aparezcan ordenados por algn campo, podemos modificar fcilmente la instruccin SQL que se encarga de seleccionar los datos de la tabla que son mostrados en el formulario. En este ejercicio usamos la clase OleDb del espacio de nombres System.Data que permite el acceso a proveedores de datos que trabajan directamente contra los controladores basados en ActiveXde Microsoft. Si en vez de ello conectsemos con proveedores SQL Server usaramos la clase SqlClient del mismo espacio de nombres System.Data. La clase OleDb tiene subclases especficas de cada proveedor de datos. De estas subclases, nos interesa la clase OleDbCommand, que representa un comando SQL enviado contra el gestor de datos. En el ejercicio, dentro de la regin "Cdigo generado por el Diseador de Windows Forms", tenemos un objeto del tipo OleDbCommand llamado OleDbSelectCommand1 que se crea en 2 lneas no consecutivas:

Friend WithEvents OleDbSelectCommand1 As System.Data.OleDb.OleDbCommand Me.OleDbSelectCommand1 = New System.Data.OleDb.OleDbCommand

Este objeto OleDbSelectCommand1 tiene una propiedad de tipo String, CommandText, que contiene la cadena con la sentencia SQL de seleccin para cargar la tabla en el formulario. Por defecto el comando SQL es:

Me.OleDbSelectCommand1.CommandText = "SELECT Direccin, ID, Nombre, [Telfono 1], [Telfono 2] FROM tbAgenda" Esa instruccin SQL simplemente selecciona todos los registros de esos campos de la tabla tbAgenda y los muestra. Pero si queremos ordenarlos por algn criterio, podemos modificar la instruccin en esa lnea de cdigo. Por ejemplo, si queremos que los datos aparezcan ordenados por el campo Nombre en sentido ascendente, tendramos que escribir:

Me.OleDbSelectCommand1.CommandText = "SELECT Direccin, ID, Nombre, [Telfono 1], [Telfono 2] FROM tbAgenda ORDER BY Nombre ASC" De esta manera comprobaremos cmo los registros mostrados en el formulario de datos estn ordenados por el campo Nombre, lo que puede resultarnos ms til a la hora de desplazarnos por ellos.

A continuacin sigue cdigo en Visual Basic:

'Cargar la base de datos Private Sub btnLoad_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnLoad.Click Try 'Intenta cargar el conjunto de datos. Me.LoadDataSet() 'Avisa de que se ha cargado la base de datos predeterminada MessageBox.Show("La base de datos se ha cargado en el DataSet", "Datos cargados", MessageBoxButtons.OK, MessageBoxIcon.Information) 'Informar en la barra de ttulo del formulario Me.Text = "Agenda telefnica - DATOS CARGADOS" Catch eLoad As System.Exception 'Agregar aqu el cdigo de control de errores. 'Mostrar mensaje de error, si hay alguno. System.Windows.Forms.MessageBox.Show(eLoad.Message) End Try Me.objemiData_PositionChanged() End Sub 'Aadir un registro Private Sub btnAdd_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAdd.Click Try 'Borrar las ediciones actuales Me.BindingContext(objemiData, "tbAgenda").EndCurrentEdit() Me.BindingContext(objemiData, "tbAgenda").AddNew() Catch eEndEdit As System.Exception System.Windows.Forms.MessageBox.Show(eEndEdit.Message) End Try Me.objemiData_PositionChanged() End Sub

'Borrar un registro Private Sub btnDelete_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDelete.Click If (Me.BindingContext(objemiData, "tbAgenda").Count > 0) Then Me.BindingContext(objemiData, "tbAgenda").RemoveAt(Me.BindingContext(objemiData, "tbAgenda").Position) Me.objemiData_PositionChanged() End If End Sub Private Sub btnUpdate_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnUpdate.Click Try 'Intenta actualizar el origen de datos. Me.UpdateDataSet() Catch eUpdate As System.Exception 'Agregar aqu el cdigo de control de errores. 'Mostrar mensaje de error, si hay alguno. System.Windows.Forms.MessageBox.Show(eUpdate.Message) End Try Me.objemiData_PositionChanged() End Sub 'Ir al primer registro Private Sub btnNavFirst_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnNavFirst.Click Me.BindingContext(objemiData, "tbAgenda").Position = 0 Me.objemiData_PositionChanged() End Sub 'Ir al ltimo registro Private Sub btnLast_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnLast.Click Me.BindingContext(objemiData, "tbAgenda").Position = (Me.objemiData.Tables("tbAgenda").Rows.Count - 1) Me.objemiData_PositionChanged() End Sub 'Retroceder un registro Private Sub btnNavPrev_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnNavPrev.Click Me.BindingContext(objemiData, "tbAgenda").Position = (Me.BindingContext(objemiData, "tbAgenda").Position - 1) Me.objemiData_PositionChanged() End Sub 'Avanzar un registro Private Sub btnNavNext_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnNavNext.Click Me.BindingContext(objemiData, "tbAgenda").Position = (Me.BindingContext(objemiData, "tbAgenda").Position + 1) Me.objemiData_PositionChanged() End Sub 'Rellenar la etiqueta del panel de navegacin Private Sub objemiData_PositionChanged()

Me.lblNavLocation.Text = (((Me.BindingContext(objemiData, "tbAgenda").Position + 1).ToString + " de ") _ + Me.BindingContext(objemiData, "tbAgenda").Count.ToString) End Sub 'Actualizar el origen de datos Public Sub UpdateDataSet() 'Crear un conjunto de datos para alojar los cambios realizados en el conjunto de datos principal. Dim objDataSetChanges As Agenda_telefnica.emiData = New Agenda_telefnica.emiData 'Detener las ediciones actuales. Me.BindingContext(objemiData, "tbAgenda").EndCurrentEdit() 'Obtener los cambios realizados en el conjunto de datos principal. objDataSetChanges = CType(objemiData.GetChanges, Agenda_telefnica.emiData) 'Comprobar si se han realizado cambios. If (Not (objDataSetChanges) Is Nothing) Then Try 'Hay cambios que necesitan aplicarse, por tanto, intente actualizar el origen de datos 'llamando al mtodo de actualizacin y pasando el conjunto de datos y los parmetros. Me.UpdateDataSource(objDataSetChanges) objemiData.Merge(objDataSetChanges) objemiData.AcceptChanges() Catch eUpdate As System.Exception 'Agregar aqu el cdigo de control de errores. Throw eUpdate End Try 'Agregar cdigo para comprobar en el conjunto de datos devuelto los errores que se puedan haber 'introducido en el error del objeto de fila. End If End Sub 'Cargar la base de datos Public Sub LoadDataSet() 'Crear un conjunto de datos para alojar los registros devueltos de la llamada a FillDataSet. 'Se utiliza un conjunto de datos temporal porque el relleno del conjunto de datos existente 'requerira que se volvieran a enlazar los enlaces de datos. Dim objDataSetTemp As Agenda_telefnica.emiData objDataSetTemp = New Agenda_telefnica.emiData Try 'Intenta rellenar el conjunto de datos temporal. Me.FillDataSet(objDataSetTemp) Catch eFillDataSet As System.Exception 'Agregar aqu el cdigo de control de errores. Throw eFillDataSet End Try Try 'Vaciar los registros obsoletos del conjunto de datos. objemiData.Clear()

'Combinar los registros en el conjunto de datos principal. objemiData.Merge(objDataSetTemp) Catch eLoadMerge As System.Exception 'Agregar aqu el cdigo de control de errores. Throw eLoadMerge End Try End Sub 'Actualizar el origen de datos Public Sub UpdateDataSource(ByVal ChangedRows As Agenda_telefnica.emiData) Try 'Slo es necesario actualizar el origen de datos si hay cambios pendientes. If (Not (ChangedRows) Is Nothing) Then 'Abra la conexin. Me.OleDbConnection1.Open() 'Intenta actualizar el origen de datos. OleDbDataAdapter1.Update(ChangedRows) End If Catch updateException As System.Exception 'Agregar aqu el cdigo de control de errores. Throw updateException Finally 'Cerrar la conexin independientemente de si se inici una excepcin o no. Me.OleDbConnection1.Close() End Try End Sub 'Rellenar el DataSet con los datos Public Sub FillDataSet(ByVal dataSet As Agenda_telefnica.emiData) 'Desactiva la comprobacin de restricciones antes de rellenar el conjunto de datos. 'De esta forma los adaptadores pueden rellenar el conjunto de datos sin preocuparse 'de las dependencias entre las tablas. dataSet.EnforceConstraints = False Try 'Abrir la conexin. Me.OleDbConnection1.Open() 'Intenta rellenar el conjunto de datos a travs de OleDbDataAdapter1. Me.OleDbDataAdapter1.Fill(dataSet) Catch fillException As System.Exception 'Agregar aqu el cdigo de control de errores. Throw fillException Finally 'Volver a activar la comprobacin de restricciones. dataSet.EnforceConstraints = True 'Cerrar la conexin independientemente de si se inici una excepcin o no. Me.OleDbConnection1.Close() End Try End Sub

Private Sub btSalir_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btSalir.Click Me.Close() 'cerrar el formulario End Sub End Class

Comentarios finales y propuestas de mejora


Como resumen, hemos visto que, mediante el asistente de formularios de datos, el propio entorno de Visual Studio .NET escribe gran cantidad de cdigo til por nosotros, lo que facilita la construccin de programas relativamente complejos sin tener conocimientos avanzados de programacin. El programa se mejorara aadiendo funciones de filtrado o de bsqueda de registros concretos, impresin de informes con listados, etc. Por mi parte, por ahora se queda como est ;-)

Imagen del programa en funcionamiento

(El botn "Abrir datos" se conecta a la base de datos predeterminada)

Agenda telefnica 2 en Visual Basic .NET


Usando DataBinding (enlace de los datos a los controles del formulario) y una base de datos de Microsoft Access
Recordando mi anterior ejercicio "Agenda telefnica en VBasic .NET", publicado en esta seccin, se propona una manera muy sencilla (posiblemente la que ms) de conectar con una base de datos de Access, usando el Asistente para Formularios de Datos del propio IDE de Visual Studio. Esta manera de trabajar tiene ventajas evidentes para el principiante: y y y el asistente realiza la mayor parte del trabajo, de manera que, con pocos conocimientos y en poco tiempo, se tiene una aplicacin que funciona. el cdigo creado automticamente es bastante complejo, con buena proteccin de errores, y suele funcionar bien casi desde el principio. la aplicacin realizada de esta manera entra de lleno en ADO .NET (ActiveX Data Objects .NET), que es la tecnologa de acceso a datos ms avanzada de la plataforma .NET, proporcionando pleno acceso desconectado a los datos.

Pero, junto a esas ventajas, aparecen algunos inconvenientes, de los que, al menos 3, son para tener en cuenta: y el cdigo creado automticamente reside en gran parte en la seccin #Region " Cdigo generado por el Diseador de Windows Forms " lo que lo hace menos manipulable por el programador. el cdigo creado automticamente, como ya se ha dicho antes, es bastante complejo, y puede darse el caso de que el usuario principiante ponga a punto una aplicacin de este tipo con rapidez y, sin embargo, no comprenda grandes fragmentos del cdigo de su propio programa (como me pas a m mismo ;-). el cdigo creado automticamente recurre a un mecanismo de la plataforma .NET llamado DataBinding, que consiste en crear enlaces entre los objetos contenedores de los datos y los controles del formulario, lo que permite que las operaciones de navegacin y edicin de registros se automaticen en grado elevado. Este mecanismo de enlace automtico de datos a controles usa numerosos elementos del conjunto de tipos de .NET Framework: clases, colecciones, enumeraciones... Todo ello pasa desapercibido al realizar este tipo de aplicaciones con el Asistente para Formularios de Datos.

De todo lo anterior nace la idea del ejercicio actual, esta "Agenda telefnica 2", con 2 premisas fundamentales:

debe usar un mecanismo similar al de la primera Agenda telefnica, realizando otro ejercicio en el que sea el propio usuario el que construya el cdigo "a mano", recurriendo tambin al empleo de DataBinding. debe seguir siendo un ejercicio proyectado para principiantes, por lo que el cdigo debe ser sencillo en todo lo que se pueda y debe estar explicado al mximo en cualquiera de sus pasos.

Introduccin simple a ADO .NET y DataBinding Acceso desconectado a datos: En la arquitectura tradicional de tipo cliente / servidor, cada cliente se conectaba a la base de datos, manteniendo la conexin el tiempo necesario para realizar operaciones directamente contra el servidor de base de datos al que est conectado. Obligaba a mantener conexiones de base de datos para todos y cada uno de los usuarios. Al crecer el tamao de las bases de datos y el nmero de clientes (usuarios) potenciales, sobre todo en relacin con el fenmeno de Internet, se vio la necesidad de establecer conexiones lo ms breves posibles, simplemente para las operaciones inicial (lectura o recuperacin de datos) y final (escritura o actualizacin de datos) sobre el origen de los datos (la base de datos) y trabajar el resto del tiempo sobre una copia desconectada local del origen de los datos (DataSet). En versiones anteriores de Visual Basic ya exista ADO (ActiveX Data Objects) que permite acceder a todo tipo de bases de datos desde Visual Basic y trabajar en modo desconectado. Visual Basic .NET puede usar ADO, pero ADO .NET es el mtodo preferido por Visual Studio .NET para conectar a bases de datos. ADO .NET usa clases especficas para efectuar operaciones en bases de datos. Una de las diferencias con respecto a ADO es el uso de comandos especficos de conexin con SQL Server: varias de las clases principales de ADO .NET tienen 2 versiones diferentes, una para conectar a una base de datos SQL Server y otra para proveedores OLE-DB. Como ejemplo, tenemos SQLCommand yOLEDBCommand, SQLConnection y OLEDBConnection, etc. ODBC est desaconsejado, es conveniente usar OLE-DB en su lugar. DataBinding: es el mecanismo de la plataforma .NET que, en aplicaciones con interfaz WindowsForms, permite crear enlaces entre los objetos que contienen los datos y los controles del formulario. Como ejemplo, se puede enlazar la propiedad Text de un control TextBox con una columna de una tabla del DataSet (la base de datos desconectada), lo que simplifica enormemente las operaciones de navegacin por los registros de la tabla. Objetos importantes del DataBinding: y Binding: clase que permite crear el enlace, necesita: o propiedad del control que muestra los datos o DataSet que proporciona la informacin o tabla y columna cuyos datos pasan a la propiedad del control DataBinding: coleccin de los enlaces a datos que tienen los controles BindingContext: propiedad de la clase Form con informacin de los enlaces establecidos entre controles y datos. Devuelve un objeto BindingManagerBase BindingManagerBase: encargado de administrar un conjunto de enlaces de un formulario, obtenidos desde la propiedad BindingContext del formulario.

y y y

A continuacin sigue cdigo en Visual Basic:

'Agenda telefonica 2 --- Miliuco 07/09/2003 'Ejercicio de acceso a datos: '- base de datos de Microsoft Access '- usando DataBinding (enlace de datos a controles del formulario) Imports System.Data Imports System.Data.OleDb Public Class Inicio Inherits System.Windows.Forms.Form 'Variables declaradas a nivel de clase para poder usarlas desde 'cualquier procedimiento o funcin Private conn As OleDbConnection = New OleDbConnection 'conexin de tipo OleDb Private adaptador As OleDbDataAdapter 'DataAdapter: adaptador de datos Private datos As DataSet 'DataSet: conjunto de datos desconectados Private enlaceBase As BindingManagerBase 'administrador de los objetos de enlace a datos Private comando As OleDbCommandBuilder 'constructor de comandos para el DataAdapter Private ruta As String 'almacena la ruta a la base de datos Private abierto As Boolean = False 'para saber si ya est abierta la base de datos Private cambios As Boolean = False 'para saber si hay cambios pendientes de guardar #Region " Cdigo generado por el Diseador de Windows Forms " #End Region 'Al cargar el formulario Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 'Crear tooltip de 2 lneas en el control Icono Me.ToolTip1.SetToolTip(Icono, "Emilio Prez Egido (Miliuco)" & ControlChars.CrLf _ & Space(2) & "8 de Septiembre de 2003") 'Texto inicial de las etiquetas lbPrimera.Text = "Pulsa en ""Cargar datos"" para conectarte a la base de datos." & _ vbCrLf & "Elige la base de datos en el cuadro de dilogo." lbSegunda.Text = "Desconectado. Conjunto de datos vaco." 'Altura inicial del separador Panel1 Panel1.Height = 5 End Sub Private Sub btCargar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btCargar.Click 'Si la base de datos est abierta, simplemente informar

If abierto = True Then Dim aviso As String = "La base de datos ya est cargada en el DataSet" lbPrimera.Text = aviso.ToUpper End If 'Si la base de datos NO est abierta If abierto = False Then Try 'Cuadro de dilogo para elegir la base de datos dlgFile = New OpenFileDialog dlgFile.Filter = "Base de datos Agenda (*.mdb)|*.mdb" dlgFile.Title = "Selecciona la base de datos Agenda" 'Si el dilogo devuelve OK If dlgFile.ShowDialog() = DialogResult.OK Then 'Nombre del archivo elegido, con su ruta completa, 'equivale a la base de datos ruta = dlgFile.FileName 'Cadena de conexin tpica de base de datos de Microsoft Access conn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" _ & ruta & ";User Id=admin;Password=;" 'DataAdapter: objeto que hace de puente entre la base de datos 'y el DataSet o conjunto de datos adaptador = New OleDbDataAdapter("SELECT * FROM Agenda ORDER BY Nombre", conn) 'DataAdapter puede contener sentencias SQL y objetos Command comando = New OleDbCommandBuilder(adaptador) 'DataSet: contiene una copia de la base de datos, en esquema XML, 'independiente del proveedor, con sus elementos tablas y relaciones. 'Es el verdadero almacn de datos desconectados: actuamos sobre 'el DataSet desconectado y el DataAdapter se conecta para volcar 'los datos entre base de datos y DataSet, en ambos sentidos datos = New DataSet 'Abrir la conexin, el DataAdapter llena el DataSet, 'cerrar la conexin conn.Open() adaptador.Fill(datos, "Agenda") conn.Close() 'Para enlazar controles del formulario con el DataSet usamos 'DataBinding; al objeto Binding le pasamos la propiedad del

'control que se debe enlazar, el DataSet y la tablacolumna. 'Despus, el objeto Binding se aade a la coleccin de enlaces 'de datos (DataBinding) del control elegido, con el mtodo Add() Dim enlace As Binding enlace = New Binding("Text", datos, "Agenda.Nombre") txNombre.DataBindings.Add(enlace) enlace = Nothing enlace = New Binding("Text", datos, "Agenda.Telfono1") txTel1.DataBindings.Add(enlace) enlace = Nothing enlace = New Binding("Text", datos, "Agenda.Telfono2") txTel2.DataBindings.Add(enlace) enlace = Nothing 'Al objeto BindingManagerBase le pasamos el DataSet y la tabla, 'desde el contexto de enlace del formulario (BindingContext) Me.enlaceBase = Me.BindingContext(datos, "Agenda") lbPrimera.Text = "Base de datos cargada en el conjunto de datos," & _ vbCrLf & "usando DataBinding: Enlace de datos a controles." & _ vbCrLf & "Para insertar un registro nuevo, pulsa ""Limpiar campos""," & _ vbCrLf & "escribe los datos y pulsa ""Insertar""" lbSegunda.Text = "Archivo de datos: " & ruta 'Procedimiento descrito ms abajo Call verCuenta() 'Para saber que la base de datos ya est cargada abierto = True End If Catch pollo As Exception lbPrimera.Text = pollo.Message.ToUpper End Try End If End Sub 'Mostrar el registro actual y el total de registros de la tabla del DataSet Private Sub verCuenta() lbRegistro.Text = "Registro " & Me.enlaceBase.Position + 1 & " de " _ & Me.enlaceBase.Count End Sub

'Gracias al enlace automtico entre controles y datos (DataBinding) 'es muy sencillo navegar entre los registros y se necesita muy poco 'cdigo para ello, el objeto enlaceBase (BindingManagerBase) se encarga 'de actualizar de manera automtica el control con los datos de la fila 'de la tabla en que estamos posicionados Private Sub btAvanzar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btAvanzar.Click 'Si la base de datos est abierta If abierto = True Then Try 'Si ya estamos en el ltimo registro If Me.enlaceBase.Position = Me.enlaceBase.Count - 1 Then Dim aviso1 As String = "Ya ests en el ltimo registro de la tabla" lbPrimera.Text = aviso1.ToUpper Else lbPrimera.Text = "Base de datos cargada en el conjunto de datos." & _ vbCrLf & "Usando DataBinding: Enlace de datos a controles." 'avanzar un registro Me.enlaceBase.Position += 1 verCuenta() End If Catch pollo As Exception lbPrimera.Text = pollo.Message.ToUpper End Try 'Si la base de datos NO est abierta Else Dim aviso As String = "Primero has de cargar la base de datos" lbPrimera.Text = aviso.ToUpper End If End Sub Private Sub btRetroceder_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btRetroceder.Click 'Si la base de datos est abierta If abierto = True Then Try 'Si ya estamos en el primer registro If Me.enlaceBase.Position = 0 Then Dim aviso2 As String = "Ya ests en el primer registro de la tabla" lbPrimera.Text = aviso2.ToUpper Else lbPrimera.Text = "Base de datos cargada en el conjunto de datos." & _ vbCrLf & "Usando DataBinding: Enlace de datos a controles." 'retroceder un registro Me.enlaceBase.Position -= 1 verCuenta() End If Catch pollo As Exception

lbPrimera.Text = pollo.Message.ToUpper End Try 'Si la base de datos NO est abierta Else Dim aviso As String = "Primero has de cargar la base de datos" lbPrimera.Text = aviso.ToUpper End If End Sub Private Sub btPrimero_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btPrimero.Click 'Si la base de datos est abierta If abierto = True Then Try 'Si ya estamos en el primer registro If Me.enlaceBase.Position = 0 Then Dim aviso2 As String = "Ya ests en el primer registro de la tabla" lbPrimera.Text = aviso2.ToUpper Else lbPrimera.Text = "Base de datos cargada en el conjunto de datos." & _ vbCrLf & "Usando DataBinding: Enlace de datos a controles." 'ir al primer registro Me.enlaceBase.Position = 0 verCuenta() End If Catch pollo As Exception lbPrimera.Text = pollo.Message.ToUpper End Try 'Si la base de datos NO est abierta Else Dim aviso As String = "Primero has de cargar la base de datos" lbPrimera.Text = aviso.ToUpper End If End Sub Private Sub btUltimo_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btUltimo.Click 'Si la base de datos est abierta If abierto = True Then Try 'Si ya estamos en el ltimo registro If Me.enlaceBase.Position = Me.enlaceBase.Count - 1 Then Dim aviso1 As String = "Ya ests en el ltimo registro de la tabla" lbPrimera.Text = aviso1.ToUpper Else : lbPrimera.Text = "Base de datos cargada en el conjunto de datos." & _ vbCrLf & "Usando DataBinding: Enlace de datos a controles." 'ir al ltimo registro Me.enlaceBase.Position = Me.enlaceBase.Count - 1 verCuenta()

End If Catch pollo As Exception lbPrimera.Text = pollo.Message.ToUpper End Try 'Si la base de datos NO est abierta Else Dim aviso As String = "Primero has de cargar la base de datos" lbPrimera.Text = aviso.ToUpper End If End Sub 'Para borrar un registro Private Sub btBorrar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btBorrar.Click 'Si la base de datos est abierta If abierto = True Then Try 'Borrar el registro que se corresponde con la posicin actual Me.enlaceBase.RemoveAt(Me.enlaceBase.Position) lbPrimera.Text = "Se ha eliminado un registro." & vbCrLf _ & "Pulsa actualizar si deseas guardar los cambios." cambios = True Catch pollo As Exception lbPrimera.Text = pollo.Message.ToUpper End Try 'Si la base de datos NO est abierta Else Dim aviso As String = "Primero has de cargar la base de datos" lbPrimera.Text = aviso.ToUpper End If End Sub 'Para vaciar los campos de texto Private Sub btLimpiar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btLimpiar.Click 'Si la base de datos est abierta If abierto = True Then txNombre.Text = "" txTel1.Text = "" txTel2.Text = "" txNombre.Focus() 'Si la base de datos NO est abierta Else Dim aviso As String = "Primero has de cargar la base de datos" lbPrimera.Text = aviso.ToUpper End If End Sub 'Para aadir un registro Private Sub btInsertar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btInsertar.Click 'Si la base de datos est abierta

If abierto = True Then ''crear una nueva fila en la tabla Dim fila As DataRow fila = Me.datos.Tables("Agenda").NewRow() Try 'rellenar los campos de la fila nueva fila("Nombre") = txNombre.Text fila("Telfono1") = txTel1.Text fila("Telfono2") = txTel2.Text lbPrimera.Text = "Se ha insertado un registro nuevo." & vbCrLf _ & "Pulsa actualizar si deseas guardar los cambios." 'aadir la nueva fila a la tabla Me.datos.Tables("Agenda").Rows.Add(fila) cambios = True Catch pollo As Exception lbPrimera.Text = pollo.Message.ToUpper End Try 'Si la base de datos NO est abierta Else Dim aviso As String = "Primero has de cargar la base de datos" lbPrimera.Text = aviso.ToUpper End If End Sub 'Para actualizar el adaptador de datos (DataAdapter) con los cambios hechos en el DataSet Private Sub btActualizar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btActualizar.Click 'Si la base de datos est abierta If abierto = True Then 'Si ha habido cambios en el DataSet desde la ltima actualizacin If (cambios = True) Then Try conn.Open() 'Actualizar DataAdapter, se pueden pasar parmetros: ' - (datos as dataset, "tabla" as string) ' - (datos.tables("tabla") as dataset) --> usado aqu Me.adaptador.Update(Me.datos.Tables("Agenda")) 'Vaciar el DataSet: conserva los datos de tablas y registros y si no 'se limpia acumula las operaciones sucesivas de modificacin de filas Me.datos.Clear() 'Volver a llenar el DataSet desde el DataAdapter ya modificado Me.adaptador.Fill(datos, "Agenda") conn.Close() 'Actualizar la etiqueta lbRegistro Call verCuenta() 'Indicador de cambios pendientes a false cambios = False Dim aviso As String = "Base de datos actualizada con los cambios realizados" lbPrimera.Text = aviso.ToUpper

Catch pollo As Exception lbPrimera.Text = pollo.Message.ToUpper End Try Else ' 'Si NO ha habido cambios en el DataSet desde la ltima actualizacin Dim aviso2 As String = "No hay cambios pendientes de actualizar" lbPrimera.Text = aviso2.ToUpper End If 'Si la base de datos NO est abierta Else Dim aviso3 As String = "Primero has de cargar la base de datos" lbPrimera.Text = aviso3.ToUpper End If End Sub Private Sub btSalir_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btSalir.Click 'Si la base de datos NO est abierta If abierto = False Then 'Cerrar el formulario Me.Close() End If If abierto = True Then 'si NO ha habido cambios en el DataSet desde la ltima actualizacin If cambios = False Then 'Cerrar el formulario Me.Close() End If 'Si la base de datos est abierta y si adems 'ha habido cambios en el DataSet desde la ltima actualizacin If cambios = True Then If MessageBox.Show("Hay cambios pendientes de guardar." & vbCrLf _ & "Pulsa en ""Cancelar"" para volver al programa." & _ vbCrLf & "Pulsa en ""Aceptar"" para salir sin guardar", _ "Cambios sin guardar", MessageBoxButtons.OKCancel, _ MessageBoxIcon.Exclamation) = DialogResult.OK Then Me.Close() End If End If End If End Sub End Class

Imagen del programa en funcionamiento