realizar altas

41

Upload: overpaucar

Post on 24-Jul-2015

87 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Realizar altas
Page 2: Realizar altas
Page 3: Realizar altas
Page 4: Realizar altas
Page 5: Realizar altas
Page 6: Realizar altas

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 diseñar nuestro formulario.

Page 7: Realizar altas

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 código. 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 conexión.

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 versión superior, podemos utilizar unicamente el .

(punto)

Initial Catalog: Debemos colocar el nombre de la base de datos a utilizar.

Page 8: Realizar altas

Botón 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 código en SQL, los siguientes

procedimientos están compuestos de dos partes, la primera donde se declaran los parametros a

utilziar, y en la segunda donde se realiza la transacción 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.

Page 9: Realizar altas

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

Código del Botón 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 = “”

Page 10: Realizar altas

TextBox3.Text = “”

TextBox4.Text = “”

Stored Procedure Eliminar

CREATE PROCEDURE dbo.spEliminaCliente

@prmId int

AS

DELETE FROM CLIENTES WHERE ID=@prmId

RETURN

Código del Butón 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

Page 11: Realizar altas

@prmId int,

@prmNombre nvarchar(40)

AS

UPDATE clientes SET nombre=@prmNombre WHERE Id=@prmId

RETURN

Código del Botón 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 botón de consulta mas tarde.

Saludos!!!

el Guille, la Web del Visual Basic, C#, .NET y más...

  Lo+ - WinFX - .NET - ADO.NET - ASP.NET - Cómo... - Colabora - VB6 - API - HTML - Vista - Links - Foros  

Page 12: Realizar altas

ADO.NET

Ejemplo de acceso a datos a una base de SQL ServerPublicado: 19/Abr/2003Actualizado: 21/May/2003

En este ejemplo veremos cómo acceder a una base de datos de SQL Server, usando los

objetos del espacio de nombres System.Data.SqlClient.

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.

 

Nota:

También puedes ver estos mismos conceptos, pero con una base de datos de Access.

Si notas parecido entre esta página y la de Access, no te extrañe, 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 mayoría residen en el espacio de

nombres System.Data.SqlClient, 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

Page 13: Realizar altas

System.Data.SqlClient 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:

'------------------------------------------------------------------------------

' Prueba de acceso a base de tipo SQL Server con ADO.NET (25/May/02)

' Módulo 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 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

Page 14: Realizar altas

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 de SQL Server

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:

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: Deberías cambiar el nombre del equipo, etc. (16/Abr/03)

'

CadenaConexion = "data source=GUILLEACER\NETSDK;" & _

"initial catalog=" & ArchivoDatos & ";" & _

Page 15: Realizar altas

"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 conexión:" & 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 parámetros:

El primero indicará el nombre de la base de datos de SQL Server, 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.

Page 16: Realizar altas

Lo que aquí tenemos que destacar es lo siguiente:

La cadena de conexión deberíamos tenerla asignada antes de llamar a este procedimiento,

de no ser así, se usará la que hemos indicado en el código, aunque deberías cambiarla para

adaptarla a tu configuración.

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.

Page 17: Realizar altas

 

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

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.

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

Page 18: Realizar altas

'

Return nomTablas

End Function

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.

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 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:

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)

Page 19: Realizar altas

nomCol(i) = columna.ColumnName

Next

Return nomCol

End Function

Creo que el código es bastante auto-explicativo y no necesita más aclaración.

 

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.

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)

Page 20: Realizar altas

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 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.

Friend Sub LLenarLista(ByVal unListView As ListView)

Dim i As Integer

Page 21: Realizar altas

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 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.

 

El formulario principal

Este es el aspecto del formulario principal (Form1) en tiempo de diseño:

Page 22: Realizar altas

El formulario principal 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:

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))

Page 23: Realizar altas

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

' s &= lasColumnas(i) & ", "

'Next

'' Quitar la última coma

'i = s.LastIndexOf(", ")

's = s.Substring(0, i)

's = "SELECT " & s & " FROM " & cboTablas.Text

'txtSelect.Text = s

End Sub

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.

Page 24: Realizar altas

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.

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 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:

' Importamos el módulo con las declaraciones de los objetos a usar

Imports ADONET_SQL.ADONETUtil

Page 25: Realizar altas

ADONET_SQL 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.

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 conexión

Try

Page 26: Realizar altas

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 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:

Page 27: Realizar altas

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:

' Importamos el módulo 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

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.

Page 28: Realizar altas

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:

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 información o datos de dicha fila.

Private Sub ListView1_SelectedIndexChanged(ByVal sender As Object, _

Page 29: Realizar altas

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 información 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

Page 30: Realizar altas

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 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:

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 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:

Page 31: Realizar altas

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, 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 Object, _

ByVal e As EventArgs) _

Handles btnNuevo.Click

' Añadir una nueva fila (o registro)

Dim fila As Data.DataRow

Dim i As Integer

Dim lwItem As ListViewItem

Page 32: Realizar altas

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

Page 33: Realizar altas

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:

Page 34: Realizar altas

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()

'

'

Page 35: Realizar altas

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.

 

Como habrás podido comprobar, si lo comparas con el ejemplo de Access, el código es

prácticamente igual, sólo cambia la "procedencia" de algunos objetos, (espacios de

nombres), así como el nombre de los mismos, pero en general el código no tiene apenas

cambios.

En otra ocasión, espero que no se haga tanto de rogar como esta con respecto a la de

Access, veremos un código aún más genérico para acceder tanto a bases de datos de Access

como de SQL Server; si veo que tardo mucho en "depurar" ese código, lo publicaré como

esté y ya habrá tiempo de actualizarlo o mejorarlo.

Nos vemos.

Guillermo

Page 36: Realizar altas

Si quieres bajarte el código 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 condicioncomo 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.ClickDim 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 identifiquecmd.CommandType = CommandType.Textcmd.Parameters.Add(New SqlParameter("@usuario", TxtUsuario.Text))cmd.Parameters.Add(New SqlParameter("@Password", TxtContraseña.Text))cnx.Open()Dim leer As SqlDataReader = cmd.ExecuteReaderIf 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 TxtContraseña.Text = leer(1).ToString Then 'este es el que me causa problemas

FrMenu.Show()Me.Hide()

ElseMsgBox("no puedes ingresar contraseña incorrecta")

TxtUsuario.Clear()TxtContraseña.Clear()TxtUsuario.Focus()End If

ElseMsgBox("no puedes ingresar usuario incorrecto")

TxtUsuario.Clear()TxtContraseña.Clear()

Page 37: Realizar altas

TxtUsuario.Focus()End IfEnd IfEnd Sub