Sei sulla pagina 1di 37

Realizar altas, bajas y modificaciones con Visual Basic .

NET y SQL SERVER 2005


Posted by jororague under SQL SERVER 2005 | Etiquetas: SQL SERVER 2005, VISUAL BASIC | [24] Comments

Atendiendo a todos los usuarios de Visual Basic, vamos a realizar el uso de Procedmientos Almacenados en SQL Server 2005y Visual Basic. El primer paso , es disear nuestro formulario.

Hay que considerar que este ejemplo es similar al que hice con Visual C#. Los elementos a utilizar son: SQLConnection SQL Command Stored Procedured SQL SERVER 2005 Si ya tenemos el formulario, ahora hay que agregarle el cdigo. Empezaremos por agregarle en el encabezado antes de Public Class Form1 esto: Imports System.Data.SqlClient Este es mi formulario de ejemplo, es una pantalla para dar de alta a los clientes, en ella solo voy a estar afectando a los campos clave, nombre, direccion y negocio. Hay que agregrar una nueva conexion a una base de datos declaramos esto agregandole la cadena de conexin. Dim cnn As SqlConnection Dim cmd As SqlCommand Dim dr As DataRow Dim conexion As String = Data Source=.;Initial Catalog=dbDemo;Integrated Security=true Coloreo la linea de la conexion porque es importante recordar lo siguiente: Data Source: Se debe indicar el nombre del servidor, si se tiene SQLSERVER Express, sera necesario darselo, si se cuenta con una versin superior, podemos utilizar unicamente el . (punto) Initial Catalog: Debemos colocar el nombre de la base de datos a utilizar. Botn Altas.

Primero hay que crear el procedimiento almacenado, en la venta de Server Explorer , hay que escoger la Base de Datos, y de ahi la carpeta de Stored Procedure, damos un clic con el boton derecho y escogemos Add New Stored Procedure

Aqui vamos a crear los procedimientos almacenados (stored procedure). Esto har que muestre una pantalla para editar el respectivo cdigo en SQL, los siguientes procedimientos estn compuestos de dos partes, la primera donde se declaran los parametros a utilziar, y en la segunda donde se realiza la transaccin SQL.

El procedimiento de Insertar un registro queda de esta forma, recuerda que el nombre que le des al Store Proceudure ser como se almacenar y se llamar desde tu programa en VS.

Stored Procedure Altas ALTER PROCEDURE dbo.spAltaCliente @prmId int, @prmNombre nvarchar(50), @prmDireccion nvarchar(50), @prmNegocio nvarchar(50) AS INSERT INTO CLIENTES (ID,NOMBRE,DIRECCION,NEGOCIO) VALUES (@prmId,@prmNombre,@prmDireccion,@prmNegocio) RETURN Cdigo del Botn Altas cnn = New SqlConnection(conexion) cnn.Open(); cmd=New SqlCommand(spAltaCliente,cnn) cmd.CommandType = CommandType.StoredProcedure cmd.Parameters.Add(@prmClave, SqlDbType.Int).Value = Convert.ToInt16(TextBox1.Text) cmd.Parameters.Add(@prmNombre, SqlDbType.NVarChar).Value = TextBox2.Text cmd.Parameters.Add(@prmDireccion, SqlDbType.NVarChar).Value = TextBox3.Text cmd.Parameters.Add(@prmNegocio, SqlDbType.NVarChar).Value = TextBox4.Text cmd.ExecuteNonQuery() MessageBox.Show(Cliente Activado) TextBox1.Text = TextBox2.Text =

TextBox3.Text = TextBox4.Text = Stored Procedure Eliminar CREATE PROCEDURE dbo.spEliminaCliente @prmId int AS DELETE FROM CLIENTES WHERE ID=@prmId RETURN

Cdigo del Butn Eliminar cnn = New SqlConnection(conexion) cnn.Open() cmd = New SqlCommand(spEliminaCliente, cnn) cmd.CommandType = CommandType.StoredProcedure cmd.Parameters.Add(@prmClave, SqlDbType.Int).Value = Convert.ToInt16(TextBox1.Text) cmd.ExecuteNonQuery() MessageBox.Show(Cliente ELIMINADO) TextBox1.Text = TextBox2.Text = Stored Procedure Modificar CREATE PROCEDURE dbo.spModificaCliente

@prmId int, @prmNombre nvarchar(40) AS UPDATE clientes SET nombre=@prmNombre WHERE Id=@prmId RETURN Cdigo del Botn Modificar cnn = New SqlConnection(conexion) cnn.Open() cmd = new SqlCommand(spModificaCliente, cnn) cmd.CommandType = CommandType.StoredProcedure; cmd.Parameters.Add(@prmId, SqlDbType.Int).Value = Convert.ToInt16(TextBox1.Text) cmd.Parameters.Add(@prmNombre, SqlDbType.NVarChar).Value = TextBox2.Text cmd.ExecuteNonQuery() MessageBox.Show(Cliente Modificado) textBox1.Text = textBox2.Text = Y les anexo el botn de consulta mas tarde. Saludos!!!

el Guille, la Web del Visual Basic, C#, .NET y ms...


Lo+ - WinFX - .NET - ADO.NET - ASP.NET - Cmo... - Colabora VB6 - API - HTML - Vista - Links - Foros

ADO.NET

Ejemplo de acceso a datos a una base de SQL Server


Publicado: 19/Abr/2003 Actualizado: 21/May/2003

En este ejemplo veremos cmo acceder a una base de datos de SQL Server, usando los objetos del espacio de nombres System.Data.SqlClient. Los conceptos que se tratarn sern los siguientes: - Crear una conexin 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.

Nota: Tambin puedes ver estos mismos conceptos, pero con una base de datos de Access. Si notas parecido entre esta pgina y la de Access, no te extrae, ya que son hermanitas, pero cada una de ellas mostrando los datos de tipos de bases distintas.

Los objetos a usar en el proyecto.


Los objetos que vamos a usar en este ejemplo, en su gran mayora residen en el espacio de nombres System.Data.SqlClient, aunque tambin se usarn objetos genricos (DataSet,

DataRow, DataColumn) que residen en System.Data. Para que nos sea ms fcil declarar esos objetos, importaremos el espacio de nombres System.Data.SqlClient y dado que usaremos procedimientos genricos, estos los incluiremos en un mdulo, al que llamaremos: ADONETUtil, veamos el cdigo con las declaraciones de los objetos que usaremos en el proyecto:
'----------------------------------------------------------------------------' Prueba de acceso a base de tipo SQL Server con ADO.NET (25/May/02) ' Mdulo con las declaraciones de objetos ' ' Guillermo 'guille' Som, 2002-2003 '----------------------------------------------------------------------------Imports System.Data.SqlClient Module ADONETUtil Friend dbConnection As Data.SqlClient.SqlConnection Friend dbCommand As Data.SqlClient.SqlCommand Friend dbDataReader As Data.SqlClient.SqlDataReader ' Friend dbDataTable As Data.DataTable Friend dbDataSet As Data.DataSet Friend dbDataAdapter As Data.SqlClient.SqlDataAdapter ' Friend CadenaConexion As String Friend CadenaSelect As String ' ' Friend ArchivoDatos As String Friend NombreTabla As String = "Tabla1" '

La variable CadenaConexion ser la cadena con la que conectaremos a la base de datos. La variable CadenaSelect ser el cdigo 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 slo un nombre que usaremos con los distintos objetos de ADO.NET.

Conectar a una base de datos de SQL Server


Para conectar a la base de datos y crear los objetos que cargarn la tabla (definida en la consulta SQL contenida en la variable CadenaSelect), vamos a crear un procedimiento en el mismo mdulo ADONETUtil:
Friend Sub Conectar(Optional ByVal nombreBaseDatos As String = "", _ Optional ByVal commandString As String = "") If nombreBaseDatos = "" Then nombreBaseDatos = ArchivoDatos End If ArchivoDatos = nombreBaseDatos If ArchivoDatos = "" Then Exit Sub End If ' If CadenaSelect = "" Then CadenaSelect = "SELECT * FROM Table1" End If If commandString = "" Then commandString = CadenaSelect End If CadenaSelect = commandString ' If CadenaConexion = "" Then ' ' Nota: Deberas cambiar el nombre del equipo, etc. (16/Abr/03) '

CadenaConexion = "data source=GUILLEACER\NETSDK;" & _ "initial catalog=" & ArchivoDatos & ";" & _ "integrated security=SSPI;persist security info=True;" & _ "workstation id=GUILLEACER;packet size=4096" End If ' Try dbConnection = New Data.SqlClient.SqlConnection(CadenaConexion) Catch e As Exception MessageBox.Show("Error al crear la conexin:" & vbCrLf & e.Message) Exit Sub End Try ' dbConnection.Open() ' dbDataSet = New Data.DataSet() ' dbDataAdapter = New Data.SqlClient.SqlDataAdapter(CadenaSelect, dbConnection) ' Dim commandBuilder As New Data.SqlClient.SqlCommandBuilder(dbDataAdapter) ' dbDataAdapter.MissingSchemaAction = MissingSchemaAction.AddWithKey Try dbDataAdapter.Fill(dbDataSet, NombreTabla) Catch ex As Exception MessageBox.Show(ex.Message) End Try ' End Sub

A este procedimiento se le pueden indicar dos parmetros: El primero indicar el nombre de la base de datos de SQL Server, mientras que el segundo ser la instruccin SQL que nos permitir acceder a la tabla. Cuando veamos el cdigo del formulario, tendremos ocasin de ver cmo se llama a este procedimiento.

Lo que aqu tenemos que destacar es lo siguiente: La cadena de conexin deberamos tenerla asignada antes de llamar a este procedimiento, de no ser as, se usar la que hemos indicado en el cdigo, aunque deberas cambiarla para adaptarla a tu configuracin. 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 fsicos 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 estn en memoria y se acceden y manipulan de forma independiente, sin ninguna relacin 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 seleccin y la cadena de conexin o el objeto del tipo Connection. En este caso, le he indicado el objeto Connection, pero si no queremos crear una conexin permanente, tambin podemos usar la misma cadena de conexin 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 habra que usar para aadir, modificar y eliminar, pero esos comandos se pueden crear de forma automtica creando un nuevo objeto del tipo CommandBuilder, al que se le pasar como parmetro el adaptador que usar dichos comandos, en realidad el objeto CommandBuilder no se usa nada ms que para que de esta forma se asignen dichos comandos de actualizacin de datos. Si la tabla a la que queremos acceder tiene clave principal (cosa que es comn o debera serlo en todas las tablas), le indicamos mediante la asignacin a la propiedad MissingSchemaAction el valor de aadir con clave. Si no hacemos esta asignacin y la tabla tiene un campo que se incrementa automticamente, no podramos crear varios registros (o filas) en memoria y despus actualizar esas nuevas filas de forma permanente, ya que nos dara 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 parmetro 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 relacin ninguna con la base de datos fsica.

Los nombres de las tablas de una base de datos de SQL Server


Vamos a crear una funcin que devuelva una matriz (o array) del tipo String, con los nombres de las tablas de la base de datos.
Friend Function NombresTablas(Optional ByVal nombreBase As String = "") As String() ' Dim nomTablas() As String Dim dataTable As New Data.DataTable() Dim i As Integer ' If dbConnection Is Nothing Then dbConnection = New Data.SqlClient.SqlConnection(CadenaConexion) End If If dbConnection.State <> ConnectionState.Open Then dbConnection.Open() End If ' Dim schemaDA As New Data.SqlClient.SqlDataAdapter( _ "SELECT * FROM INFORMATION_SCHEMA.TABLES " & _ "WHERE TABLE_TYPE = 'BASE TABLE' " & _ "ORDER BY TABLE_TYPE", _ dbConnection) ' schemaDA.Fill(dataTable) i = dataTable.Rows.Count - 1 If i > -1 Then ReDim nomTablas(i) For i = 0 To dataTable.Rows.Count - 1 nomTablas(i) = dataTable.Rows(i).Item("TABLE_NAME").ToString() Next End If '

Return nomTablas End Function

Antes de llamar a esta funcin tendremos que tener asignada la cadena de conexin o, mejor an, creada la conexin a la base de datos. Eso es lo que se hace en las primeras lneas, si el objeto del tipo Connection no est creado, se crea un nuevo objeto, usando la cadena de conexin. En caso de que est creado el objeto, se comprueba si est abierta dicha conexin, de no ser as, se abre. A continuacin 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. Para conseguir los nombres de las tablas, buscamos las tablas del tipo "BASE 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 funcin 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 tambin podra servirnos para acceder a cualquier tabla virtual contenida en el DataSet. Tambin vamos a crear una funcin que devuelva una matriz del tipo String:

Friend Function NombresColumnas() As String() Dim columna As Data.DataColumn Dim i, j As Integer Dim nomCol() As String ' j = dbDataSet.Tables(NombreTabla).Columns.Count - 1 ReDim nomCol(j) For i = 0 To j columna = dbDataSet.Tables(NombreTabla).Columns(i) nomCol(i) = columna.ColumnName

Next Return nomCol End Function

Creo que el cdigo es bastante auto-explicativo y no necesita ms aclaracin.

Asignar la cabecera de un control ListView con los nombres de las columnas o campos de una tabla
Para terminar con el cdigo del mdulo ADONETUtil, vamos a ver unos mtodos 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 mtodo se llama AsignarCabeceraLista y tendr dos implementaciones, una indicando slo el nombre del ListView y la otra en la que adems se indicar un control ComboBox en el cual se asignarn tambin esos nombres de las columnas de la tabla.
Friend Sub AsignarCabeceraLista(ByVal ListView1 As ListView) Dim columna As Data.DataColumn Dim i, j As Integer ' With ListView1 .View = View.Details .FullRowSelect = True .GridLines = True .LabelEdit = False .HideSelection = False .Columns.Clear() End With ' Dim lasColumnas() As String lasColumnas = NombresColumnas(CadenaConexion, CadenaSelect) ' If Not lasColumnas Is Nothing Then For i = 0 To lasColumnas.Length - 1 ListView1.Columns.Add(lasColumnas(i), 100, HorizontalAlignment.Left) Next

End If ' End Sub

Friend Sub AsignarCabeceraLista(ByVal ListView1 As ListView, _ ByVal cboCampos As ComboBox) Dim i As Integer ' AsignarCabeceraLista(ListView1) cboCampos.Items.Clear() For i = 0 To ListView1.Columns.Count - 1 cboCampos.Items.Add(ListView1.Columns(i).Text) Next ' If cboCampos.Items.Count > 0 Then cboCampos.SelectedIndex = 0 End If End Sub

Creo que tampoco necesita explicacin, ya que lo nico que se hace es llamar a la funcin NombresColumnas y el contenido de ese array es el que se asigna a la cabecera del ListView que se ha indicado en el parmetro. En cuanto a la segunda implementacin, se asigna al control ComboBox pasado como parmetro esos mismos nombres. Cuando veamos el cdigo de los formularios, sabremos cuando usar una u otra versin de este mtodo.

Llenar un ListView con el contenido de una tabla


El siguiente mtodo del mdulo ADONETUtil rellenar un control ListView con los datos de la tabla cargada en el objeto DataSet.

Friend Sub LLenarLista(ByVal unListView As ListView) Dim i As Integer Dim lwItem As ListViewItem Dim fila As Data.DataRow

' unListView.Items.Clear() ' For Each fila In dbDataSet.Tables(NombreTabla).Rows For i = 0 To unListView.Columns.Count - 1 If i = 0 Then lwItem = unListView.Items.Add(fila(i).ToString) lwItem.Tag = fila Else lwItem.SubItems.Add(fila(i).ToString) End If Next Next End Sub

El cdigo es tambin bastante simple, slo quiero aclarar un detalle: La asignacin 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, slo 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.

El formulario principal
Este es el aspecto del formulario principal (Form1) en tiempo de diseo:

El formulario principal en tiempo de diseo 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 tamao que el usuario quiera darle al formulario, esos detalles podremos verlo en el cdigo completo, ya que aqu slo mostrar la parte que realmente interesa, es decir lo que est relacionado con el acceso a la base de datos. Empecemos por el cdigo del botn "Mostrar tablas" y el evento producido cuando se selecciona una tabla del ComboBox:
Private Sub btnAbrirBase_Click( _ ByVal sender As Object, ByVal e As EventArgs) _ Handles btnAbrirBase.Click ' Dim nomTablas() As String Dim i As Integer ' nomTablas = NombresTablas(txtNombreBase.Text) cboTablas.Items.Clear() If Not nomTablas Is Nothing Then For i = 0 To nomTablas.Length - 1 cboTablas.Items.Add(nomTablas(i))

Next End If If cboTablas.Items.Count > 0 Then cboTablas.SelectedIndex = 0 End If ' End Sub

Private Sub cboTablas_SelectedIndexChanged( _ ByVal sender As Object, ByVal e As EventArgs) _ Handles cboTablas.SelectedIndexChanged txtSelect.Text = "SELECT * FROM " & cboTablas.Text ' '' Si se quieren mostrar individualmente los nombres de los campos 'Dim lasColumnas() As String 'Dim s As String, i As Integer '' 'CadenaSelect = txtSelect.Text 'lasColumnas = NombresColumnas(CadenaConexion, CadenaSelect) 'For i = 0 To lasColumnas.Length - 1 ' 'Next '' Quitar la ltima coma 'i = s.LastIndexOf(", ") 's = s.Substring(0, i) 's = "SELECT " & s & " FROM " & cboTablas.Text 'txtSelect.Text = s End Sub s &= lasColumnas(i) & ", "

El primer procedimiento intercepta la pulsacin en el botn 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 cdigo que est comentado sirve para mostrar los nombres de los campos o columnas de forma individual.

Cuando pulsamos en el botn "Mostrar", se muestra el contenido de la tabla indicada, informacin que se obtiene del DataSet que contiene los datos en memoria. Aunque, el cdigo mostrado, realmente refresca esa informacin, 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.

Private Sub btnMostrar_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles btnMostrar.Click ' With ListView1 .View = View.Details .FullRowSelect = True .GridLines = True .LabelEdit = False .HideSelection = False .Columns.Clear() End With ' ' Volver a reconectar para actualizar los datos desde la base If Not dbConnection Is Nothing Then dbConnection.Close() End If Conectar(txtNombreBase.Text, txtSelect.Text) ' AsignarCabeceraLista(ListView1) LLenarLista(ListView1) End Sub

Como podemos comprobar, aqu se llaman a los mtodos del mdulo ADONETUtil, por tanto al principio del cdigo del formulario debemos hacer la importacin del espacio de nombres de ese mdulo para no tener que especificarlo cada vez que queramos acceder a cualquiera de los procedimientos o variables en el declarado:
' Importamos el mdulo con las declaraciones de los objetos a usar Imports ADONET_SQL.ADONETUtil

ADONET_SQL es el nombre del "espacio de nombres" (Namespace) de este proyecto. Para acabar con el cdigo de este formulario, veamos los eventos que se producen al cargarse el formulario (Load) y al cerrarse (Closing), adems del evento producido al pulsar en el botn "Mostrar", el cual mostrar el formulario en el que se editan los datos de la tabla indicada.
Private Sub Form1_Load(ByVal sender As Object, _ ByVal e As System.EventArgs) _ Handles MyBase.Load Me.txtNombreBase.Text = "pubs" Me.txtSelect.Text = "SELECT * FROM authors" ' ArchivoDatos = txtNombreBase.Text CadenaConexion = "data source=GUILLEACER\NETSDK;" & _ "initial catalog=" & ArchivoDatos & ";" & _ "integrated security=SSPI;persist security info=True;" & _ "workstation id=GUILLEACER;packet size=4096" ' With ListView1 .View = View.Details .FullRowSelect = True .GridLines = True .LabelEdit = False End With ' cboTablas.Text = "" End Sub

Private Sub Form1_Closing(ByVal sender As Object, _ ByVal e As System.ComponentModel.CancelEventArgs) _ Handles MyBase.Closing ' Cerrar la conexin Try If dbConnection.State = ConnectionState.Open Then

dbConnection.Close() End If Catch End Try End Sub

Private Sub btnModificar_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles btnModificar.Click Dim f2 As New Form2() With f2 .DataSource = txtNombreBase.Text .CommandString = txtSelect.Text .ShowDialog() End With btnMostrar_Click(btnMostrar, e) End Sub

En el evento Load, asignamos los valores iniciales, en el evento Closing, comprobamos si tenemos la conexin 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 botn Modificar, creamos una nueva instancia del formulario en el que modificaremos la informacin 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 botn sin haber creado la conexin.

El formulario de edicin de datos


Para terminar con este ejemplo de acceso a datos usando ADO.NET, veamos el formulario que usaremos para modificar la informacin de la base de datos. El aspecto del formulario (FORM2) ser el mostrado en la siguiente imagen:

El formulario de introduccin de datos En este formulario, los controles tambin estn "anclados" para que se adapten al tamao que el usuario quiera darle al formulario. Empecemos por las variables o propiedades que este formulario expone al mundo externo:

' Importamos el mdulo con las declaraciones de los objetos a usar Imports ADONET_SQL.ADONETUtil Public Class Form2 Inherits System.Windows.Forms.Form Friend DataSource As String Friend CommandString As String ' Private lwItemActual As ListViewItem

Tambin usamos el Imports para poder usar los procedimientos del mdulo 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 asignarn algunos valores por defecto y se mostrar el contenido de la tabla indicada en el ListView:
Private Sub Form2_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles MyBase.Load Me.txtCampo1.Text = "" ' ' para usar este formulario como formulario inicial If DataSource = "" Then DataSource = "pubs" End If If CommandString = "" Then CommandString = "SELECT * FROM authors" End If ' lblInfo.Text = _ "Base: " & NombreBase(DataSource) & ", Select: " & CommandString ' If Not dbConnection Is Nothing Then dbConnection.Close() End If Conectar(DataSource, CommandString) ' AsignarCabeceraLista(ListView1, cboCampos) LLenarLista(ListView1) ' Me.AcceptButton = btnAsignar End Sub

Cuando seleccionamos un nuevo elemento del ListView, se asigna la variable que contiene el elemento actual y se muestra la informacin o datos de dicha fila.

Private Sub ListView1_SelectedIndexChanged(ByVal sender As Object, _ ByVal e As System.EventArgs) _

Handles ListView1.SelectedIndexChanged Try lwItemActual = ListView1.SelectedItems(0) Catch End Try End Sub Private Sub ListView1_Click(ByVal sender As Object, _ ByVal e As System.EventArgs) _ Handles ListView1.Click, _ cboCampos.SelectedIndexChanged Try lwItemActual = ListView1.SelectedItems(0) MostrarCampo() Catch End Try End Sub

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 informacin del campo seleccionado en el ComboBox. De eso se encarga el procedimiento MostrarCampo:

Private Sub MostrarCampo() Dim i As Integer ' Try i = cboCampos.SelectedIndex If i = 0 Then txtCampo1.Text = lwItemActual.Text ElseIf i > -1 Then txtCampo1.Text = lwItemActual.SubItems(i).Text End If Catch End Try

End Sub

Este procedimiento simplemente muestra el contenido del campo que est seleccionado en el control ComboBox.

Asignar los datos


Cuando pulsamos en el botn Asignar, el cual hemos asignado como botn "Aceptar" del formulario, es decir el que tomar el foco cuando pulsemos la tecla Intro, se asignarn los cambios realizados al campo (o columna) que estamos editando:

Private Sub AsignarCampo(ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles btnAsignar.Click ' Asignar al ListView el campo modificado Dim i As Integer ' i = cboCampos.SelectedIndex If i = 0 Then lwItemActual.Text = txtCampo1.Text ElseIf i > -1 Then lwItemActual.SubItems(i).Text = txtCampo1.Text End If End Sub

Eliminar una fila


Cuando pulsamos en el botn Eliminar, borramos la fila seleccionada del ListView y tambin 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 coleccin Rows del objeto DataSet, ya que el mtodo Remove de la coleccin Rows acepta como parmetro un objeto del tipo DataRow:

Private Sub btnEliminar_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles btnEliminar.Click ' Eliminar la fila indicada Dim fila As Data.DataRow ' fila = CType(ListView1.SelectedItems(0).Tag, Data.DataRow) dbDataSet.Tables(NombreTabla).Rows.Remove(fila) ListView1.Items.Remove(ListView1.SelectedItems(0)) End Sub

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, despus esa fila la aadiremos 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 conversin a cadena generada por ToString, por lo que dicho tipo se convierte en el formato "System.Tipo", veamos el cdigo para aclarar todo este lo:
Private Sub btnNuevo_Click(ByVal sender As Object, _ ByVal e As EventArgs) _ Handles btnNuevo.Click ' Aadir 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" ' 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() ' Aadir 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 fila(i) = 0

If columna.DataType.ToString.IndexOf("System.Int") > -1

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 mtodo NewRow, asignamos los campos (o columnas) de dicha fila y la aadimos a la coleccin Rows de la tabla. Hay que tener en cuenta que al crear una nueva fila con NewRow no se aade a la coleccin 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 aclaracin, debido a que los datos los estamos asignando a un objeto que mantiene la informacin 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 aadido la nueva fila a la tabla, asignamos el contenido de la misma al ListView y tambin asignamos a la propiedad Tag una referencia a dicha fila.

Guardar la informacin en la base de datos


Por ltimo vamos a ver cmo pasar la informacin 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 botn de "Actualizar Base" y el cdigo usado es el siguiente:
Private Sub btnActualizarBase_Click(ByVal sender As Object, _ ByVal e As 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 informacin 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 recordars 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 slo los datos si no es una columna del tipo AutoIncrement. La llamada a los mtodos 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 mtodo Update del DataAdapter, este mtodo es el que realmente hace que los datos se guarden fsicamente en la base de datos. Despus llamamos al mtodo AcceptChanges del objeto DataSet para que "sepa" que hemos aceptado la nueva informacin y marque la informacin de forma que sean iguales a los datos que tiene la base de datos real.

Como habrs podido comprobar, si lo comparas con el ejemplo de Access, el cdigo es prcticamente igual, slo cambia la "procedencia" de algunos objetos, (espacios de nombres), as como el nombre de los mismos, pero en general el cdigo no tiene apenas cambios. En otra ocasin, espero que no se haga tanto de rogar como esta con respecto a la de Access, veremos un cdigo an ms genrico para acceder tanto a bases de datos de Access como de SQL Server; si veo que tardo mucho en "depurar" ese cdigo, lo publicar como est y ya habr tiempo de actualizarlo o mejorarlo. Nos vemos. Guillermo

Si quieres bajarte el cdigo completo de este ejemplo, usa este link: ADONETSQL.zip 14.9 KB

Saludos bueno el problema que tengo es que estoy haciendo un sistema para entregar solo que con base de datos ya lo habia hecho pero de una forma sencilla, ahora lo que quiero es que se conecte a la base de datos, cuando lo lea primero verifique el usuario si el usuario existe se va a ir a otra condicion que es el del password y dentro del password llamo el otro formulario que es menu dejo codigo para que me digan en que me equivoco

lo que pasa es que a la hora de que lea el password en la lectura me da el daot de la caja de texto y no de la base de datos, y con el and en el comando si no esta bien cualquiera de los dos pues no entra a la primera condicion como le puedo hacer para solo conectarme con el nombre de usuario a la bd y que de ahi pueda leer los dos datos y pueda ingresar al menu

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnIngresar.Click Dim cnx As SqlConnection = New SqlConnection("Data Source=YOP\SQLEXPRESS;Initial Catalog=otra;Integrated Security=True") Dim cmd As New SqlCommand("select * from Usuarios where @Usuario=usuario and @password=Password ", cnx)'con estos dos si no cumple uno no entro igual ya sabe pero para que lo identifique cmd.CommandType = CommandType.Text cmd.Parameters.Add(New SqlParameter("@usuario", TxtUsuario.Text)) cmd.Parameters.Add(New SqlParameter("@Password", TxtContrasea.Text)) cnx.Open() Dim leer As SqlDataReader = cmd.ExecuteReader If leer.Read() = True Then ' si una de las anteririores no se cumple no entra If TxtUsuario.Text = leer(0).ToString Then 'este campo si lo lee bien

If TxtContrasea.Text = leer(1).ToString Then 'este es el que me causa problemas FrMenu.Show() Me.Hide() Else

MsgBox("no puedes ingresar contrasea incorrecta") TxtUsuario.Clear() TxtContrasea.Clear() TxtUsuario.Focus() End If Else MsgBox("no puedes ingresar usuario incorrecto") TxtUsuario.Clear() TxtContrasea.Clear() TxtUsuario.Focus() End If End If End Sub

Potrebbero piacerti anche