25 de julio de 2012

Clase ACME en VB-SQL sin SP

Se creara una clase en VB para Actualizar, Modificar, Consultar y Eliminar datos (ACME) sin utilizar procedimientos almacenados, la sencillez de este caso puede parecer hasta casi un insulto para aquellos que piensan que toda aplicación existente en el mundo laboral debe ir satisfactoriamente apegada a una base de datos(me incluyo), por lo que pienso que esta entrada del blog servirá mas para alumnos del cole o aprendices primerizos que para aquellos que ya estén laburreando, igual si les sirve de algo aquí se los dejo.

Para este ejemplo y en mi caso particular me conectare a una base de datos llamada sistema, que contiene una tabla llamada empleado, con tres campos a utilizar: dui(PK), nombres(varchar(50)) y cargo(varchar(50)).

Ustedes pueden utilizar la base que quieran o que deban para probar el ejemplo, lo único a tener en cuenta es que se utilizara un app.config para guardar los datos de la cadena de conexión así que en caso no sepan como hacerlo sera útil que vean esta entrada sobre el app.config:   http://pabletoreto.blogspot.com/search/label/App.Config

Logrando lo anterior, mi app.config queda de la siguiente manera, con el nombre: conexión, servidor local y  base de datos: sistema 

    <connectionStrings>
        <add name="conexion" connectionString="Data Source=.\LINGONET;Initial Catalog=sistema;Integrated Security=True"
            providerName="System.Data.SqlClient"
    <connectionStrings>

ahora se debe agregar una clase a nuestro proyecto de VB, en mi caso llame a la clase ACME, se importaran los siguientes espacios de nombre

Imports System.Data
Imports System.Data.SqlClient
Imports System.Configuration


y se declaran las variables necesarias estableciendo la cadena de conexión:

Dim sql As New SqlConnection(ConfigurationManager.ConnectionStrings("conexion").ConnectionString)
    Dim cmd As SqlCommand
    Dim da As SqlDataAdapter
    Dim dt As DataTable
    Dim bs As BindingSource

Ahora viene la parte del ACME, recuerden que el dui es PK y que se trabaja en una tabla llamada empleado sobre los campos dui, nombres y cargo, ademas que no se utilizan procedimientos almacenados sino mas bien se "carga" la sentencia sql en cada función dependiendo de los datos que reciba

En todas las funciones se utiliza un Try-Catch para manejar la cadena de conexión con lo que se me facilita el obtener los errores, ademas se utiliza el command en la variable cmd (cmd = new SqlCommand) que recibe los datos por parámetros y el cual al final de la instrucción es destruido 

Public Sub AgregarDatos(ByVal dui, ByVal nombres, ByVal cargo)
        Try
            sql.Open()
            cmd = New SqlCommand
            cmd.Connection = sql
            cmd.CommandText = "insert into empleado(DUI, nombres, cargo) values (@dui, @nombres, @cargo)"
            cmd.Parameters.AddWithValue("@dui", dui)
            cmd.Parameters.AddWithValue("@nombres", nombres)
            cmd.Parameters.AddWithValue("@cargo", cargo)
            cmd.ExecuteNonQuery()
            MessageBox.Show("datos ingresados eficientemente")
        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try
        cmd.Dispose()
        sql.Close()
    End Sub

    Public Sub ModificarDatos(ByVal dui, ByVal nombres, ByVal cargo)

        Try
            sql.Open()
            cmd = New SqlCommand
            cmd.Connection = sql
            cmd.CommandText = "update empleado SET nombres = @nombres, cargo=@cargo where dui = @dui"
            cmd.Parameters.AddWithValue("@dui", dui)
            cmd.Parameters.AddWithValue("@nombres", nombres)
            cmd.Parameters.AddWithValue("@cargo", cargo)
            cmd.ExecuteNonQuery()
            MessageBox.Show("Dato modificado satisfactoriamente")
        Catch ex As Exception
            MessageBox.Show(ex.Message)
        Finally
            sql.Close()
            cmd.Dispose()
        End Try
    End Sub

    Public Sub EliminarDatos(ByVal dui)
        Try
            sql.Open()
            cmd = New SqlCommand
            cmd.Connection = sql
            cmd.CommandText = "delete from empleado where dui=@id"
            cmd.Parameters.AddWithValue("@id", dui)
            cmd.ExecuteNonQuery()
            MessageBox.Show("dato eliminado correctamente")
        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try
        sql.Close()
        cmd.Dispose()
    End Sub

    Public Function ConsultarDatos() As BindingSource
        Try
            sql.Open()
            da = New SqlDataAdapter("select * from empleado", sql)
            dt = New DataTable
            bs = New BindingSource
            da.Fill(dt)
            bs.DataSource = dt
        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try
        sql.Close()
        da.Dispose()
        Return bs
    End Function


ahora viene la parte del formulario, en mi caso le llame ACME_VB.vb y esta es la apariencia, tiene un DataGridView, un BindingNavigator, 4 botones con las funciones ACME y tres textbox para los campos de la tabla que se van a utilizar...ojo se van a cargar los datos en el DataGridView y se enlazaran con los textbox y con el BindingNavigator al cargar el formulario :)


La referencia a la clase ACME desde el código del formulario y el BindingSource a ocupar se declaran así:

Dim clase As New ACME
Dim bs As BindingSource


ahora, al cargar el formulario invoco a un metodo llamado refrescar(), lo que hace es mostrar los datos en el dataGridView, en los textbox y en el BindingNavigator al cargar el formulario así:

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        refrescar()
    End Sub


Private Sub refrescar()
        bs = New BindingSource
        bs = clase.ConsultarDatos
        DataGridView1.DataSource = bs
        BindingNavigator1.BindingSource = bs
        DUIText.DataBindings.Clear()
        DUIText.DataBindings.Add(New Binding("text", bs, "dui"))
        NombreText.DataBindings.Clear()
        NombreText.DataBindings.Add(New Binding("text", bs, "nombres"))
        CargoText.DataBindings.Clear()
        CargoText.DataBindings.Add(New Binding("text", bs, "cargo"))
    End Sub


bueno y el codigo completo del form es este

Public Class ACME_VB
    Dim clase As New ACME
    Dim bs As BindingSource

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        refrescar()
    End Sub

    Private Sub AgregarDatos_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles AgregarDatos.Click
        clase.AgregarDatos(DUIText.Text, NombreText.Text, CargoText.Text)
        DataGridView1.DataSource = clase.ConsultarDatos
    End Sub

    Private Sub Consultar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Consultar.Click
        refrescar()
    End Sub

    Private Sub Modificar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Modificar.Click
        clase.ModificarDatos(DUIText.Text, NombreText.Text, CargoText.Text)
        DataGridView1.DataSource = clase.ConsultarDatos
    End Sub

    Private Sub Eliminar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Eliminar.Click
        clase.EliminarDatos(DUIText.Text)
        DataGridView1.DataSource = clase.ConsultarDatos
    End Sub

    Private Sub refrescar()
        bs = New BindingSource
        bs = clase.ConsultarDatos
        DataGridView1.DataSource = bs
        BindingNavigator1.BindingSource = bs
        DUIText.DataBindings.Clear()
        DUIText.DataBindings.Add(New Binding("text", bs, "dui"))
        NombreText.DataBindings.Clear()
        NombreText.DataBindings.Add(New Binding("text", bs, "nombres"))
        CargoText.DataBindings.Clear()
        CargoText.DataBindings.Add(New Binding("text", bs, "cargo"))
    End Sub

End Class