viernes, 27 de marzo de 2020

De CSV a DataGridView y de DatagridView a BBDD.

Leer un CSV

Se puede leer desde Visual Basic un archivo con formato separado por comas CSV, para que esto sea posible, el formato que debe cumplir un CSV debe cumplir estos requisitos:

Sea un fichero de texto plano cualquiera, eliminamos las cabeceras (suele ser la primera fila), y renombramos el fichero como .csv 

Si ahora lo abrimos (debemos tener en nuestro equipo un programa capaz de leer archivos .csv como LibreOffice por ejemplo).
Al intentar abrirlo nos muestra esta pantalla.

Abrir archivo con formato CSV


viernes, 13 de marzo de 2020

Mantenimiento de datos de una BBDD de Oracle con DataGridView de VB y DataBinding


Vamos a realizar un mantenimiento de una tabla de una base de datos de Oracle, para ello cargaremos la tabla en un DataGridView de Visual Basic y pondremos los botones de Alta, Modificar y Eliminar, También pondremos algunos campos como filtros, de modo que podamos hacer búsquedas en la tabla.
Enlazaremos los datos de la tabla con DataBinding de Visual Basic.

Ojo porque hay veces que la select es correcta pero no carga nada, en ese caso hay que revisar la PK de la tabla, si la creamos y sigue sin funcionar, añadimos una columna nueva de tipo number y la hacemos autonumérica, luego le asignamos la PK y con esto ya debería funcionar.


Más fotos como esta.

Crearemos un formulario con tres txt de campos llamados txtCampo1, 2 y 3, otros tres de filtrado llamados txtFiltroCampo1, 2 y 3 y  un DataGridView llamado dgdDataResult.

El programa sería de este estilo:

Imports System.IO

Imports System.Data.OleDb
Imports System.Windows.Forms
Imports System.Data.SqlClient

Public Class frmMantenimiento
    Dim ds As New DataSet()

    Dim bs As BindingSource = New BindingSource()
    Dim dA As New OleDb.OleDbDataAdapter
    Dim drEdit As DataRowView
    Dim bolRefrescar As Boolean
    Dim bolPrimeraVez As Boolean = True
    Const Tabla = "Mantenimiento"
    Enum Accion
        Alta = 1
        Baja = 2
        Modificacion = 3
    End Enum

    Dim TipoAccion As Accion


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

        Me.grdResult.DataSource = bs

        txtCampo1.MaxLength = 40
        txtCampo2.MaxLength = 40
        txtCampo3.MaxLength = 40

        Mantenimiento()
      
        Dim ObjetosPermitidos As Dictionary(Of String, String)
        ObjetosPermitidos = ComprobarPermisos(Me.Name)
        btnModificar.Visible = IIf(ObjetosPermitidos.ContainsKey("btnModificar"), True, False)
        btnBaja.Visible = IIf(ObjetosPermitidos.ContainsKey("btnBaja"), True, False)
        btnAlta.Visible = IIf(ObjetosPermitidos.ContainsKey("btnAlta"), True, False)

    End Sub

    Sub Mantenimiento()

      
        Dim tb As DataTable
        Dim srSQL As StreamReader
        Dim strConsulta As String
        Dim oPar As OleDbParameter
        Dim iNumReg As Integer
        Dim cmdbuilder As OleDbCommandBuilder

        tb = New DataTable

        strStartupPath = My.Application.Info.DirectoryPath
        srSQL = New System.IO.StreamReader(strStartupPath & "\CargarTabla.sql")
        strConsulta = srSQL.ReadToEnd
        cmdPD = New OleDb.OleDbCommand(strConsulta, cnxPD)
        dA.SelectCommand = cmdPD
        cmdbuilder = New OleDbCommandBuilder(dA)
        dA.Fill(ds, "Mantenimiento")

        If Not bolPrimeraVez Then
            Exit Sub
        End If

        bolPrimeraVez = False

        dA.UpdateCommand = cmdbuilder.GetUpdateCommand()
        dA.DeleteCommand = cmdbuilder.GetDeleteCommand()
        dA.InsertCommand = cmdbuilder.GetInsertCommand()

        bs.DataSource = ds.Tables(Tabla)

        Me.txtCampo1.DataBindings.Add(New Binding("Text", bs, "CAMPO1"))
        Me.txtCampo2.DataBindings.Add(New Binding("Text", bs, "CAMPO2"))
        Me.txtCampo3.DataBindings.Add(New Binding("Text", bs, "CAMPO3"))

        grdResult.Columns(0).MinimumWidth = 180
        grdResult.Columns(1).MinimumWidth = 100
        grdResult.Columns(2).MinimumWidth = 30
        grdResult.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill

        grdResult.Columns(0).HeaderText = "Campo 1"
        grdResult.Columns(1).HeaderText = "Campo 2"
        grdResult.Columns(2).HeaderText = "Campo 3"
       
        grdResult.Refresh()

    End Sub


    Function BuscarCodigoRelacion() As Integer
        Stop
    End Function


    Private Sub btnFiltro_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnFiltro.Click
        Dim strFiltro As String = ""
        Dim vwMantenimiento As DataView


        If txtFiltroCampo1.Text <> "" Then
            If Not strFiltro = "" Then
                strFiltro = strFiltro & " AND "
            End If
            strFiltro = strFiltro & "CAMPO1 LIKE '%" & txtFiltroCampo1.Text & "%'"  
       End If

        If txtFiltroCampo2.Text <> "" Then
            If Not strFiltro = "" Then
                strFiltro = strFiltro & " AND "
            End If
            strFiltro = strFiltro & "CAMPO2 LIKE '%" & txtFiltroCampo2.Text & "%'"        
 End If

        If txtFiltroCampo3.Text <> "" Then
            If Not strFiltro = "" Then
                strFiltro = strFiltro & " AND "
            End If
            strFiltro = strFiltro & "CAMPO3 LIKE '%" & txtFiltroCampo3.Text & "%'"        
 End If

        If Not ds.Tables("Mantenimiento") Is Nothing Then
            vwMantenimiento = ds.Tables("Mantenimiento").DefaultView
            vwMantenimiento.RowFilter = strFiltro
        End If
    End Sub


    Private Sub btnAlta_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAlta.Click
        Dim strConsulta As String
        TipoAccion = Accion.Alta

        grbDetalle.Enabled = True
        grbBuscar.Enabled = False
        drEdit = bs.AddNew()
        bs.MoveLast()

        grdResult.Refresh()
    End Sub

    Private Sub btnBaja_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnBaja.Click
        Dim drv As DataRowView
        TipoAccion = Accion.Baja


        Try
            If MsgBox("¿Esta usted seguro que desea borrar este registro?", MsgBoxStyle.YesNo + MsgBoxStyle.Question, "Confirmación de Baja") = MsgBoxResult.Yes Then
                drv = bs.Current
                drv.Delete()
            End If
            dA.Update(ds, Tabla)
            grbDetalle.Enabled = False
            grdResult.Refresh()
        Catch ex As Exception
            If Mid(ex.Message, 1, 9) = "ORA-00001" Then
                MsgBox("El código de la tabla debe ser único revise los datos e intentelo de nuevo", MsgBoxStyle.Critical, "Error al actualizar los datos")
            End If
            If Mid(ex.Message, 1, 9) = "ORA-02292" Then
                MsgBox("No está permitido el borrado en cascada, asegúrese que el campo no tiene SubCampos asociados antes de borrarlos", MsgBoxStyle.Critical, "Error al actualizar los datos")
            End If
            Recargar()
        End Try
    End Sub

    Private Sub btnModificar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnModificar.Click
        TipoAccion = Accion.Modificacion
        grbDetalle.Enabled = True
        grbBuscar.Enabled = False
    End Sub

    Private Sub btnAceptar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAceptar.Click
        Dim drv As DataRowView
        Try

            drv = bs.Current

            bs.EndEdit()
            dA.Update(ds, Tabla)
            grbBuscar.Enabled = True
            grbDetalle.Enabled = False

            grdResult.Refresh()
            bolRefrescar = False
        Catch ex As Exception
            If Mid(ex.Message, 1, 9) = "ORA-00001" Then
                MsgBox("El código debe ser único revise los datos e inténtelo de nuevo", MsgBoxStyle.Critical, "Error al actualizar los datos")
            End If
            bolRefrescar = True
        End Try

    End Sub

    Private Sub btnCancelar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCancelar.Click
        bs.CancelEdit()
        If bolRefrescar Then
            Recargar()
        End If
        grbDetalle.Enabled = False
        grbBuscar.Enabled = True
    End Sub

    Sub Recargar()
        bolRefrescar = False
        ds.Tables(1).Clear()
        ds.Tables(0).Clear()
        FormatoLogico()
        grdResult.Refresh()
    End Sub

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

    End Sub

Sub AplicarFiltro()
        Dim strFiltro As String = ""
        Dim vwMantenimiento As DataView



        If txtFiltroCampo1.Text <> "" Then
            If Not strFiltro = "" Then
                strFiltro = strFiltro & " AND "
            End If
            strFiltro = strFiltro & "Campo1 LIKE '%" & txtFiltroCampo1.Text & "%'"         
End If

        If txtFiltroCampo2.Text <> "" Then
            If Not strFiltro = "" Then
                strFiltro = strFiltro & " AND "
            End If
            strFiltro = strFiltro & "CAMPO2 LIKE '%" & txtFiltroCampo2.Text & "%'"         
End If

        If txtFiltroCampo3.Text <> "" Then
            If Not strFiltro = "" Then
                strFiltro = strFiltro & " AND "
            End If
            strFiltro = strFiltro & "CAMPO3 LIKE '%" & txtFiltroCampo3.Text & "%'"         
End If

  

        If Not ds.Tables("Mantenimiento") Is Nothing Then
            vwMantenimiento = ds.Tables("Mantenimiento").DefaultView
            vwMantenimiento.RowFilter = strFiltro
        End If
    End Sub

    Private Sub txtFiltroCampo1_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles txtFiltroCampo1.TextChanged
        AplicarFiltro()
    End Sub

    Private Sub txtFiltroCampo2_Validated(ByVal sender As Object, ByVal e As System.EventArgs) Handles txtFiltroCampo2.Validated
        AplicarFiltro()
    End Sub

    Private Sub txtFiltroCampo3_Validated(ByVal sender As Object, ByVal e As System.EventArgs) Handles txtFiltroCampo3.Validated
        AplicarFiltro()
    End Sub

    Private Sub txtFiltroCampo1_TextChanged(sender As Object, e As EventArgs) Handles txtFiltroCampo1.TextChanged
        AplicarFiltro()
    End Sub

    Private Sub txtFiltroCampo2_TextChanged(sender As Object, e As EventArgs) Handles txtFiltroCampo2.TextChanged
        AplicarFiltro()
    End Sub


    Private Sub txtFiltroCampo3_TextChanged(sender As Object, e As EventArgs) Handles txtFiltroCampo3.TextChanged
        AplicarFiltro()
    End Sub


Esta es la SQL que llama a la Base de datos (será un módulo .sql asociado al proyecto de Visual Basic)

CargarTabla. sql

SELECT CAMPO1, CAMPO2, CAMPO3 FROM PROPIETARIO.TABLA

Si queremos poner un INSERT o un DELETE con parámetros, en vez de un SELECT hacemos:


Sub InsertaTabla(ByVal cod_idAsStringByValdes_idAsString)

Dim srSQL As IO.StreamReader
Dim strConsulta AsString
Try
strStartupPath = My.Application.Info.DirectoryPath
srSQL = New System.IO.StreamReader(strStartupPath & "\InsertaTabla.sql")
strConsulta = srSQL.ReadToEnd
cmdPD = New OleDb.OleDbCommand(strConsulta, cnxPD)
cmdPD.CommandType = CommandType.Text
cmdPD.Parameters.AddWithValue("?", cod_id)
cmdPD.Parameters.AddWithValue("?"des_id)
cmdPD.ExecuteNonQuery()

Catch
MsgBox("Se ha producido un error insertando en TABLA: " & Err.Description)
EndTry

EndSub

Sub BorraTabla()

Dim srSQL AsStreamReader
Dim strConsulta AsString

Try

strStartupPath = My.Application.Info.DirectoryPath
srSQL = New System.IO.StreamReader(strStartupPath & "\BorraTabla.sql")
strConsulta = srSQL.ReadToEnd
cmdPD = New OleDb.OleDbCommand(strConsulta, cnxPD)
cmdPD.CommandType = CommandType.Text
cmdPD.ExecuteNonQuery()

Catch
MsgBox("Se ha producido un error borrando en TABLA: " & Err.Description)
EndTry


EndSub

InsertaTabla.sql (las ? son los parámetros)


INSERT PROPIETARIO.TABLA VALUES(?,?,'Valor por defecto1','Valor por defecto2')


BorrarTabla.sql (las ? son los parámetros)



DELETE PROPIETARIO.TABLA WHERE CAMPO1= ?