Archivo de la categoría: DGV & SQL

Auto Data Entry Form’s

Muchos de los lectores de este blog muestran interés por ejemplos entorno a Windows forms y SQL Express, no hay duda y soy consciente de que este articulo no forma parte de esos “avances que están por venir” ni representa a ninguna novedad tecnológica actual; obviamente lejos de herramientas tan actuales como LightSwitch, sin embargo me complace compartirlo con vosotros pues creo que puede ser un buen soporte para ayudar en la comprensión de ciertos usos y técnicas sobre todo para los que empiezan.

Como digo, este es uno de esos artículos intemporales en varios aspectos, pues describe metodologías “retro” utilizando los clásicos SQL y Forms… si embargo no quiero que perdáis de vista que los “usos” y “técnicas” utilizadas pueden traspasar esa barrera atemporal y utilizarse en cualquier escenario actual… incluso en las nuevas aplicaciones “Metro Style” J

Al diseñar algunos ejemplos, disfruto partiendo de una plantilla de “Consola”, pues debido a la naturaleza y el propósito del mismo, esta concesión me permite “Salirme fuera de pistas” de lo que sería una aplicación comercial, pero a su vez me permite disfrutar de la libertad de construir algo desde los cimientos.

Como su nombre indica el objetivo del siguiente laboratorio es interactuar con la conocida base de datos para pruebas “NorthWnd”, utilizaremos la estructura de cualquiera de sus tablas para “Autogenerar” nuestro form de entrada (con todos sus textboxes) que nos permita añadir un nuevo registro a la tabla a través de un “Enlazador”. A modo de flecos para darle un poco mas de interés, he creído divertido incluir una pequeña funcionalidad que nos permita recorrer la tabla buscando todos los registros según la coincidencia del país introducido el textbox de búsqueda (con LINQ), y un par de botones para recorrer el enlazador, avanzando o retrocediendo a partir de la posición actual en el datagridview.

No creo que sea necesario un detalle mas exhaustivo, prefiero pasar al código, aunque antes quedo a vuestra disposición para continuar y desarrollar esta conversación según consideréis de interés.
Que disfrutéis
J

PepLluis,

Imports System.Drawing
Imports System.Windows.Forms
 
Imports System.Data
Imports System.Data.SqlClient
 
'
'
' Establecer un punto de entrada. Esto es una aplicacion VB
'
Module MiAplicacion
    Sub Main()
        Dim Ventana As New frmDinamico
        Ventana.Show()
        Application.Run()
    End Sub
End Module
 
 
Public Class frmDinamico
    Inherits Form
    'Punto de Inicializacion de nuestra ventana
 
    'Definicion de Variables de contexto
    Private MiConexion As New SqlConnection(
     "Data Source=.\SQLEXPRESS;" +
     "AttachDbFilename=D:\Bd_App\NORTHWND.MDF;" +
     "Integrated Security=True;Connect Timeout=30;User Instance=True")
 
    ' Adaptador, Enlazador y juego de datos para la tabla clientes
    Private MiAdaptador As New SqlDataAdapter("Select * from Customers", MiConexion)
    Private MiEnlazador As New BindingSource
    Private MiDataSet As New DataSet
 
    ''' <summary>
    ''' Al lanzar la ejecucion de la app
    ''' </summary>
    ''' <remarks></remarks>
    Sub New()
        Try
            Inicializacion()
        Catch fallo As Exception
            Messagebox.Show(fallo.Message, "Error Grave... no puedo continuar")
            End
        End Try
    End Sub
 
    ''' <summary>
    ''' Inicializar/Construir los objetos de la aplicacions
    ''' </summary>
    ''' <remarks></remarks>
    Sub Inicializacion()
        Me.Text = "Auto Entry Data Form"
        ' Crear y Enlazar datos
        Dim MiCommandBuild As New SqlCommandBuilder(MiAdaptador)
        MiConexion.Open()
        MiAdaptador.Fill(MiDataSet)
        MiENlazador.DataSource = MiDataSet.Tables(0)
        Dim MiDataGridView As New DataGridView
        MiDataGridView.DataSource = MiENlazador
        MiDataGridView.Anchor = AnchorStyles.Left Or AnchorStyles.Right Or AnchorStyles.Top
        MiDataGridView.Dock = DockStyle.Top
        '
        ' Añadir los controles al Form
        Me.Controls.Add(MiDataGridView)
        Me.Controls.AddRange({
            New TextBox With {.Name = "Buscar", .Text = "", .Dock = DockStyle.Bottom},
            New Button With {.Name = "Añadir", .Text = .Name, .Dock = DockStyle.Bottom},
            New Button With {.Name = "Avanza", .Text = .Name, .Dock = DockStyle.Bottom},
            New Button With {.Name = "Retrocede", .Text = .Name, .Dock = DockStyle.Bottom}
            })
' Apuntar los handlers a sus funciones         AddHandler Me.Controls("Añadir").Click, AddressOf Nuevo         AddHandler Me.Controls("Avanza").Click, AddressOf Avanzar         AddHandler Me.Controls("Retrocede").Click, AddressOf Retroceder         AddHandler Me.Controls("Buscar").TextChanged, AddressOf Seleccionar         Me.Controls("Buscar").Focus()     End Sub     ''' <summary>     ''' Al final la ejecucion de la app     ''' </summary>     ''' <remarks></remarks>     Sub Fin() Handles Me.FormClosed         Application.ExitThread()         End     End Sub     ''' <summary>     ''' Query para seleccionar solo los registros coincidentes     ''' con la cadena de texto introducida en el TextBox 'Buscar'     ''' </summary>     ''' <remarks></remarks>     Sub Seleccionar()         MiENlazador.DataSource =                         (                          From S In MiDataSet.Tables(0)                           Where S.Item("Country").Contains(Me.Controls("Buscar").Text)                           Select Nombre = S.Item("CompanyName"),                                  Ciudad = S.Item("City")                         ).ToList     End Sub     ''' <summary>     ''' Enlazador : MoveNext     ''' </summary>     ''' <remarks></remarks>     Sub Avanzar()         MiEnlazador.MoveNext()     End Sub     ''' <summary>     ''' Enlazador : MovePrevious     ''' </summary>     ''' <remarks></remarks>     Sub Retroceder()         MiEnlazador.MovePrevious()     End Sub     ''' <summary>     ''' Crear un nuevo form conteniendo un TextBox y una etiqueta     ''' con su descripcion para cada columna de la tabla     ''' </summary>     ''' <remarks></remarks>     Sub Nuevo()         Dim AutoForm As New Form         AutoForm.Name = "Nuevo"         AutoForm.Text = "Data Entry Form"         Dim Pos_x As Integer = 5         Dim Pos_y As Integer = 10         Dim Etiqueta As Label         Dim Entrada As TextBox         For Each col As DataColumn In MiDataSet.Tables(0).Columns             Etiqueta = New Label             Etiqueta.Location = New Point(Pos_x, Pos_Y)             Etiqueta.Text = Col.ColumnName             Pos_X += Etiqueta.Width             Entrada = New TextBox             Entrada.tag = Etiqueta.Text             Entrada.Location = New Point(Pos_X, Pos_Y)             AutoForm.Controls.AddRange(New Control() {Etiqueta, Entrada})             Pos_x = 5             Pos_Y += Etiqueta.Height + 5         Next         AutoForm.height = Pos_y + 75         AutoForm.Show()     End Sub End Class

UPDATE ME DEVUELVE ERROR : CON LA FECHA DEL DGV

Desbordamiento de SqlDateTime. Debe estar entre 1/1/1753 12:00:00 AM y 12/31/9999 11:59:59 PM.

En determinados escenarios donde intervienen plataformas en múltiples lenguajes, puede ser necesario implementar unas funciones extras para que la interacción entre formatos se realice correctamente. (sin hablar de las excepciones para tener en cuenta si sumamos el tema de zonas horarias).

Una idea seria realizar la adaptación entre la fecha y hora del objeto (en este caso el DGV) y la asignación de los valores que retornaran, cuando los extremos esperan diferentes formatos.

Puedes capturar el “cellFormating” del DGV y controlar la conversión en el “Parse”.

Aquí tienes un Ejemplo :

http://msdn.microsoft.com/es-es/library/system.windows.forms.datagridview(VS.80).aspx

En otras situaciones donde no disponemos de los “Format” y “Parse” podemos optar por creamos nuestra propia estructura…

   

    ‘ Definicion de la estructura para Fecha/Hora

    ‘ segun la definicion del lpSystemTime

    Structure FechaYHora

        Public Año As UInt16

        Public Mes As UInt16

        Public DiaDeLaSemana As UInt16

        Public Dia As UInt16

        Public Hora As UInt16

        Public Minutos As UInt16

        Public Segundos As UInt16

        Public Milis As UInt16

    End Structure

 

    ‘Funciones Fecha/Hora sistema

    Declare Function GetSystemTime Lib «Kernel32.dll» (ByRef lpSystemTime As FechaYHora) As UInt32

    Declare Function SetSystemTime Lib «Kernel32.dll» (ByRef lpSystemTime As FechaYHora) As UInt32

 

    Private MiFechaYHora = New FechaYHora

 

    Sub DelServidor(ByVal FechaHoraOrigen As DateTime)

        MiFechaYHora.Año = Convert.ToUInt16(FechaHoraOrigen.Year)

        MiFechaYHora.Mes = Convert.ToUInt16(FechaHoraOrigen.Month)

        MiFechaYHora.Dia = Convert.ToUInt16(FechaHoraOrigen.Day)

        MiFechaYHora.Hora = Convert.ToUInt16(FechaHoraOrigen.Hour)

        MiFechaYHora.Minutos = Convert.ToUInt16(FechaHoraOrigen.Minute)

        MiFechaYHora.Segundos = Convert.ToUInt16(FechaHoraOrigen.Second)

        ‘ luego debeis asignarlo segun convenga… desde o hacia el control

        ‘ o llamando a la funcion de asignar la nueva entrada

        SetSystemTime(MiFechaYHora)

    End Sub

 

Espero te ayude,
Pep Lluis,

Actualizar dos tablas vinculadas en una vista Maestro-Detalle

Una de las consultas comúnmente solicitadas a través del Blog, tiene que ver con la actualización de datos de dos tablas relacionadas en una BD de SQL, o sea actualizar una vista maestro-detalle vinculadas a sendas tablas.

Aunque por obvio y sencillo, las explicaciones acostumbran a ser de lo más diversas y finalmente te das cuenta que la mayoría de ejemplos se inician con un «desparrame» de jergas incomprensivas para la mayoría. Me decido postearos el ejemplo más básico posible, para que a partir de este punto podáis hacerlo crecer a vuestra necesidad.

Espero que os sea útil y despeje vuestras jaquecas cuando se trata de lidiar con diversas tablas.
PepLluis,

 (Para ejecutar el ejemplo, iniciar Visual Studio y crear un nuevo proyecto ‘Winform’, añadir dos DataGridView y un Button, copiar / pegar codigo y por supuesto F5)

Imports System.Data.SqlClient

Public Class Form1

    Private Maestro As SqlDataAdapter
    Private Detalle As SqlDataAdapter
    Private ConjuntoDeDatos As DataSet

    Private Sub Form1_Load() Handles MyBase.Load

        Dim miConexion As New SqlConnection("Data Source=.\SQLExpress;Initial Catalog=MaestroDetalle;Integrated Security=True")

        Maestro = New SqlDataAdapter("Select * From Maestro", miConexion)
        Dim MaestroCmdBuilder As New SqlCommandBuilder(Maestro)

        Detalle = New SqlDataAdapter("Select * From Detalle", miConexion)
        Dim DetalleCmdBuilder As New SqlCommandBuilder(Detalle)

        ConjuntoDeDatos = New DataSet
        Maestro.Fill(ConjuntoDeDatos, "Maestro")
        Me.DataGridView1.DataSource = ConjuntoDeDatos
        Me.DataGridView1.DataMember = "Maestro"

        Detalle.Fill(ConjuntoDeDatos, "Detalle")
        Me.DataGridView2.DataSource = ConjuntoDeDatos

        ConjuntoDeDatos.Relations.Add("Fk", ConjuntoDeDatos.Tables("Maestro").Columns("IdMaestro"),
                                            ConjuntoDeDatos.Tables("Detalle").Columns("IdDetalle"))

        Me.DataGridView2.DataMember = "Maestro.Fk"
    End Sub

    Private Sub Actualizar() Handles Button1.Click
        If ConjuntoDeDatos.HasChanges Then
            Maestro.Update(ConjuntoDeDatos, "Maestro")
            Detalle.Update(ConjuntoDeDatos, "Detalle")
        End If
    End Sub
End Class

De un DGV a una MDB

Debido a la insistencia de algunos lectores de este blog, me complace retomar un antiguo ejemplo donde rellenamos un DGV con los datos de una hoja XLS y posteriormente creamos una BD con la tabla correspondiente y en formato MDB. Por lo tanto seguro que con las nuevas herramientas podremos realizar tareas similares con mucho menos código, por eso matizo que se trata de un ejemplo reanimado de 2005 al 2010 J

Las versiones tanto de la XLS como la MDB corresponden al 97-2003. Para poder ejecutar este ejemplo necesitas crear un nuevo proyecto ‘Winforms’ en VB y simplemente copiar y pegar el código en el ‘form1’.

Tenéis que tener en cuenta para que funcione necesitas guardar tu hoja en la carpeta del proyecto ‘Bin/Debug’ (o reléase) según estés compilando y con el nombre ‘Libro1.xls’.

No dudéis en contactar conmigo para aclarar cualquier duda, además si necesitas el proyecto el completo estaré encantado de facilitártelo (Lo tengo para Visual Studio 2010).

Espero vuestras valoraciones.
Happy reentrada!
Pep Lluis,

' --------------------------------------------------------------------------------------------
' * AVISO IMPORTANTE * Este programa es propiedad (c)2010 Pep Lluis Bano.
' * AVISO IMPORTANTE * Se autoriza su uso, solo con fines formativos.
' 
' EL USO DE ESTA APLICACION IMPLICA LA ACEPTACION DE LAS CONDICIONES DE USO QUE SE APLICAN
' AL PROGRAMARIO "Open Source", ESTE PROGRAMA SE PROPORCIONA "COMO ESTA", NO OBLIGANDO AL 
' AUTOR A CONTRAER COMPROMISO ALGUNO PARA CON QUIENES LO UTILICEN, ASI COMO DECLINANDO 
' CUALQUIER REPONSABILIDAD DIRECTA O INDIRECTA, CONTRAIDA POR LOS MISMOS EN SU UTILIZACION 
' FUERA DE LOS PROPOSITOS PARA EL QUE FUE ESCRITO Y DISEÑADO.
'
' CUALQUIER MODIFICACIÓN Y DISTRIBUCION DEL MISMO DEBERA CONTENER Y CITAR SU FUENTE Y ORIGEN.
'
' ASI MISMO EL AUTOR AGRADECERA CUALQUIER COMENTARIO o CORRECCION QUE LOS LECTORES CONSIDEREN
' CONTRIBUYENDO ESTOS ULTIMOS A MEJORAR LA APLICACION CON FINES FORMATIVOS.
' CONSIDEREN ENVIAR SUS COMENTARIOS ulizando la opcion [Contact]
' --------------------------------------------------------------------------------------------

Imports
 ADOX
Imports System.Data.OleDb
Imports System.Text.RegularExpressions

Public Class Form1
    'Definir conexion,adaptador y Dataset
    Private MiXlsConexion As OleDbConnection
    Private MiXlsAdaptador As OleDbDataAdapter
    Private MiXlsDataSet As New DataSet()
    Private MiXlsDGV As New DataGridView

    Private MiMdbConexion As New OleDbConnection
    Private MiMdbAdaptador As New OleDbDataAdapter
    Private MiMdbDataSet As New DataSet()

    Private Mienlazador As New BindingSource
    Private MiMdbDGV As New DataGridView

    Private Sub Form1_FormClosing(ByVal sender As ObjectByVal e As System.Windows.Forms.FormClosingEventArgsHandles Me.FormClosing
        MiMdbConexion.Close()
    End Sub

    Private Sub Form1_Load() Handles MyBase.Load
        Dim MiXlsEtiqueta As New Label
        MiXlsEtiqueta.Text = "Contenido de la Hoja Excel"
        MiXlsEtiqueta.TextAlign = ContentAlignment.MiddleCenter
        MiXlsEtiqueta.BorderStyle = BorderStyle.Fixed3D
        MiXlsEtiqueta.BackColor = Color.Green
        MiXlsEtiqueta.ForeColor = Color.White
        MiXlsEtiqueta.Dock = DockStyle.Top

        Dim MiXlsDGBPanel As New Panel
        MiXlsDGBPanel.AutoSize = True
        MiXlsDGV.Dock = DockStyle.Top
        MiXlsDGBPanel.Controls.AddRange(New Control() {MiXlsDGV, MiXlsEtiqueta})


        Dim MiMdbEtiqueta As New Label
        MiMdbEtiqueta.Text = "Contenido de la BD resultante"
        MiMdbEtiqueta.TextAlign = ContentAlignment.MiddleCenter
        MiMdbEtiqueta.BorderStyle = BorderStyle.Fixed3D
        MiMdbEtiqueta.BackColor = Color.Maroon
        MiMdbEtiqueta.ForeColor = Color.White
        MiMdbEtiqueta.Dock = DockStyle.Top

        Dim MiMdbDGBPanel As New Panel
        MiMdbDGBPanel.AutoSize = True
        MiMdbDGV.Dock = DockStyle.Top
        MiMdbDGBPanel.Controls.AddRange(New Control() {MiMdbDGV, MiMdbEtiqueta})

        Dim BotonDeActualizar As New Button
        BotonDeActualizar.Dock = DockStyle.Bottom
        BotonDeActualizar.Text = "Generar Archivo MDB"

        Me.AutoSize = True
        Me.Text = "De XLS a MDB"
        MiXlsDGBPanel.Dock = DockStyle.Top
        MiMdbDGBPanel.Dock = DockStyle.Top
        Me.Controls.AddRange(New Control() {MiMdbDGBPanel, MiXlsDGBPanel, BotonDeActualizar})
        AddHandler BotonDeActualizar.Click, AddressOf GenerarMdb

        LeerXls()
    End Sub

    Private Sub LeerXls()
        'Abrir y llenar el DGV con la hoja de excel
        MiXlsConexion = New OleDbConnection _
        ("Provider=Microsoft.Jet.OLEDB.4.0;" + _
         "Extended Properties = 'Excel 8.0';" + _
         "Data Source=|DataDirectory|\libro1.xls;")
        MiXlsAdaptador = New OleDbDataAdapter("SELECT * FROM [Hoja1$]", MiXlsConexion)
        MiXlsConexion.Open()
        MiXlsAdaptador.Fill(MiXlsDataSet)
        MiXlsDGV.DataSource = MiXlsDataSet.Tables(0)
    End Sub

    Private Sub GenerarMdb()
        'Eliminar la BD1 si existe
        If My.Computer.FileSystem.FileExists("Bd1.mdb"Then
            My.Computer.FileSystem.DeleteFile("Bd1.mdb")
        End If
        '
        Dim Nombrede_MiBd = "Bd1.mdb"
        Dim NombreDe_MiTabla = "Detalles"
        ' Para crear una nueva BD de Access, me viene a la
        ' memoria la funcion Catalog del ADOX.DLL
        Dim Catalogo As New ADOX.Catalog()
        Catalogo.Create("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Nombrede_MiBd)
        '
        ' Una vez creado el nuevo catalogo añadiremos 
        ' la tabla utilizando el suministrador OLEDB
        MiXlsConexion = New OleDb.OleDbConnection("PROVIDER=Microsoft.Jet.OLEDB.4.0;Data Source =" & Nombrede_MiBd)
        '
        ' Obtenendremos el esquema de la nueva BD
        MiXlsConexion.Open()
        Dim MiEsquema As DataTable = MiXlsConexion.GetOleDbSchemaTable(OleDb.OleDbSchemaGuid.Tables, _
                New Object() {NothingNothing, NombreDe_MiTabla, "Detalles"})
        '
        ' El ultimo paso sera crear la estructura en funcion a las columnas de la hoja
        Dim Campos As String = "Create Table [" + NombreDe_MiTabla + "] ("
        For Each col As DataGridViewTextBoxColumn In MiXlsDGV.Columns
            If Campos.EndsWith(")"Or Campos.EndsWith("Key"Then Campos += ", "
            Campos += "[" + Regex.Replace(col.DataPropertyName, " ""_") + "] Text(50)"
        Next
        Campos += ")"
        Dim MiMandato As New OleDbCommand(Campos, MiXlsConexion)
        MiMandato.ExecuteNonQuery()
        MiXlsConexion.Close()
        '
        ' Añadir todos las filas como registros a la BD
        MiMdbConexion = New OleDb.OleDbConnection("PROVIDER=Microsoft.Jet.OLEDB.4.0;Data Source =" & Nombrede_MiBd)
        MiMdbAdaptador = New OleDbDataAdapter("SELECT * FROM Detalles", MiMdbConexion)
        Dim commandbuilder As New OleDb.OleDbCommandBuilder(Me.MiMdbAdaptador)
        MiMdbConexion.Open()
        MiMdbAdaptador.Fill(MiMdbDataSet)

        Dim Registro As DataRow
        For Each row As DataGridViewRow In MiXlsDGV.Rows
            If row.Index < MiXlsDGV.RowCount - 1 Then
                Registro = MiMdbDataSet.Tables(0).NewRow
                For Each col As DataGridViewColumn In MiXlsDGV.Columns
                    'Añadir una entrada por celda
                    Registro(col.Index) = row.Cells(col.Index).Value
                Next
                'Añadir una linea por fila
                MiMdbDataSet.Tables(0).Rows.Add(Registro)
            End If
        Next
        MiMdbAdaptador.Update(MiMdbDataSet)
        MiMdbDGV.DataSource = MiMdbDataSet.Tables(0)
        MiMdbConexion.Close()
    End Sub
End Class

Buscar un texto en una columna y seleccionar los coincidentes en un DGV

<Pregunta>
Que tal .. igual no sé si este comentario sea para es hilo, pero tengo un problema .. tengo un datagridview pero quiero agregar un textbox fuera del datagrid, para cuando empiece a escribir vaya buscando en el datagrid y que se vaya seleccionando, sé que para ese procedimiento se juega un poco con el datatable pero aún estoy perdido … alguién tiene una sugerencia ..

Mil gracias

<Respuesta>
… Se me ocurre algo similar a esto.

    Private Articulo As New DataTable(«Articulos»)

    Private MIDGV As New DataGridView

    Private MITXT As New TextBox

 

    Private Sub Form1_Load() Handles MyBase.Load

       

        ‘ Simular tabla Articulos

       

        Articulo.Columns.Add(«Codigo»)

        Articulo.Columns.Add(«Descripcion»)

        Articulo.Columns.Add(«Precio»)

        Articulo.Rows.Add(«001», «Resistencia 100ohms», «0,15»)

        Articulo.Rows.Add(«002», «Transistor 2n2234», «1,00»)

        Articulo.Rows.Add(«003», «Microprocesador Z80», «5,40»)

        Articulo.Rows.Add(«004», «UART 16C450», «3,45»)

        Articulo.Rows.Add(«005», «Resistencia 200ohms», «0,12»)

        Articulo.Rows.Add(«006», «Transistor 2n2222», «1,22»)

       

        ‘ marco

        Dim marcoDGV = New FlowLayoutPanel

        marcoDGV.BorderStyle = BorderStyle.Fixed3D

        marcoDGV.Width = Me.Width

        marcoDGV.Height = Me.Height

        ‘ Añadir el marco con el DataGridView y textBox

        marcoDGV.Controls.AddRange(New Control() {MIDGV, MITXT})

        Me.Controls.Add(marcoDGV)

        ‘ Seleccionar el textbox

        MITXT.Select()

        ‘ al cambiar el texto

        AddHandler MITXT.TextChanged, AddressOf VerSeleccion

    End Sub

 

    ‘ LINQ (Con VB9 ‘Visual Studio 2008’)

    ‘ Mostrar la seleccion de los registros

    ‘ que contienen la seleccion del texto

    ‘ introducido en el textBox

    Private Sub VerSeleccion()

        MIDGV.DataSource = (From S In Articulo Where S.Item(«Descripcion»).ToString.Contains(MITXT.Text) _

                                 Select Codigo = S.Item(«Codigo»), _

                                        Descripcion = S.Item(«Descripcion») _

                            ).ToList

    End Sub

Saludos,
Pep Lluis,

Autocompletando columnas en un DataGridView

<Pregunta>
Estoy desarrollando una TPV, y he visto muchos ejemplos donde existe un texbox para ingresar el codigo o el producto y despues agregarle al datagrid. Mi pregunta es la siguiente:
Existe la forma de escribir directamente en la grilla y que a medida de ingresar las letras me autocomplete el nombre del producto y luego con enter me trae los otros datos (codigo,precio,etc)?
Saludos

<Respuesta>

Public Class Form1

    Private Articulo As New DataTable(«Articulos»)

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

       

        ‘ Simular tabla Articulos

       

        Articulo.Columns.Add(«Codigo»)

        Articulo.Columns.Add(«Descripcion»)

        Articulo.Columns.Add(«Precio»)

        Articulo.Rows.Add(«001», «Resistencia 100oh», «0,15»)

        Articulo.Rows.Add(«002», «Transistor 2n2234», «1,00»)

        Articulo.Rows.Add(«003», «Microprocesador Z80», «5,40»)

        Articulo.Rows.Add(«004», «UART 16C450», «3,45»)

        Articulo.Rows.Add(«001», «Resistencia 200oh», «0,12»)

        Articulo.Rows.Add(«002», «Transistor 2n2222», «1,22»)

       

        ‘Fijar la clave principal para las busquedas

        Dim Claves(0) As DataColumn

        Claves(0) = Articulo.Columns(«Descripcion»)

        Articulo.PrimaryKey = Claves

       

        ‘Crear la lista de cadenas para el autocompletado

        For Each nombre In Articulo.Rows

            CadenasAutocompletado.Add(nombre(«Descripcion»))

        Next

        ‘Dar formato a la vista de nuestro DGV

        Me.DataGridView1.Columns.Add(«Codigo», «Codigo»)

        Me.DataGridView1.Columns.Add(«Descripcion», «Descripcion»)

        Me.DataGridView1.Columns.Add(«Precio», «Precio»)

    End Sub

   

    ‘Al editar la celda Descripcion

    Private CadenasAutocompletado As New AutoCompleteStringCollection

    Private Sub ControlEdicion(ByVal sender As Object, ByVal e As DataGridViewEditingControlShowingEventArgs) Handles DataGridView1.EditingControlShowing

        If DataGridView1.CurrentCell.ColumnIndex = 1 Then

            DirectCast(e.Control, TextBox).AutoCompleteMode = AutoCompleteMode.SuggestAppend

            DirectCast(e.Control, TextBox).AutoCompleteSource = AutoCompleteSource.CustomSource

            DirectCast(e.Control, TextBox).AutoCompleteCustomSource = CadenasAutocompletado

        End If

    End Sub

   

    ‘ Completar las columnas de Codigo/Precio al finalizar la edicion

    Private Sub FinDeEdicion(ByVal sender As Object, ByVal e As DataGridViewCellEventArgs) Handles DataGridView1.CellEndEdit

        ‘Añadir aqui las validaciones necesarias

        Try

            Dim _Articulo As DataRow = Articulo.Rows.Find(Me.DataGridView1(e.ColumnIndex, e.RowIndex).Value)

            Me.DataGridView1(«Codigo», e.RowIndex).Value = _Articulo(«Codigo»)

            Me.DataGridView1(«Precio», e.RowIndex).Value = _Articulo(«Precio»)

        Catch ex As Exception

            ‘…. Accion en caso de excepcion

        End Try

    End Sub

End Class

Establecer una vista Maestro Detalle, entre dos Tablas

Más respuestas… a la pregunta:

>> Hola el ejemplo Dos Tablas y sus relaciones en un DataGridView a traves de un ‘ComboBoxColumn’ estuvo muy bueno pero quería saber cómo hago si solamente quiero mostrar los 2 DataTables tipo maestro detalle en el DataGridView.

VistaDetalle

‘ Simular tabla con los Id’s Maestros

Dim Maestros As New DataTable(«Maestro»)

Maestros.Columns.Add(«Cliente»)

Maestros.Columns.Add(«Nombre»)

Maestros.Rows.Add(«001», «Jose Javier Garcia»)

Maestros.Rows.Add(«002», «Jhon Smith Carter»)

Maestros.Rows.Add(«003», «Pierre Bertran Janvier»)

Maestros.Rows.Add(«004», «Jose Di Souza»)

‘ Simular tabla con los Detalles

Dim Detalles As New DataTable(«Detalle»)

Detalles.Columns.Add(«Cliente»)

Detalles.Columns.Add(«Pedido»)

Detalles.Columns.Add(«Fecha»)

Detalles.Columns.Add(«Importe»)

Detalles.Rows.Add(«001», «F164533», «22/01/2006», «1,111.11»)

Detalles.Rows.Add(«001», «A163453», «22/02/2007», «2,123.23»)

Detalles.Rows.Add(«003», «ZP12343», «22/03/2008», «3,456.34»)

Detalles.Rows.Add(«004», «PDF2333», «22/05/2009», «4,452.22»)

Detalles.Rows.Add(«001», «CRF5453», «22/06/2009», «1,223.33»)

Detalles.Rows.Add(«002», «MFF6763», «22/07/2009», «1,234.32»)

Detalles.Rows.Add(«002», «VRF4683», «22/08/2009», «2,123.54»)

Detalles.Rows.Add(«004», «ZRF7933», «22/09/2009», «1,203.00»)

‘ Construir el DS y establecer relaciones

Dim MiDataSet As New DataSet

MiDataSet.Tables.Add(Detalles)

MiDataSet.Tables.Add(Maestros)

MiDataSet.Relations.Add(«Fk», _

MiDataSet.Tables(«Maestro»).Columns(«Cliente»), _

MiDataSet.Tables(«Detalle»).Columns(«Cliente»))

‘ Contructores para los Bingdings

Dim MaestroBindingSource As New BindingSource

Dim DetalleBindingSource As New BindingSource

‘ Binding del «Maestro»

MaestroBindingSource.DataMember = «Maestro»

MaestroBindingSource.DataSource = MiDataSet

‘ Enlace del detalle entre la relacion «Fk» y el Maestro

DetalleBindingSource.DataMember = «Fk»

DetalleBindingSource.DataSource = MaestroBindingSource

‘Asignar los binding source Maestro y Detalle a su DGV

Me.DataGridView1.DataSource = MaestroBindingSource

Me.DataGridView2.DataSource = DetalleBindingSource

Para probar este ejemplo solo es necesario crear una nueva solución “Windows Forms”, añadir dos DataGridView al Form1 y en el evento “Form Load” añadir el código adjunto. Puedes hacer lo mismo utilizando un ‘combo’ aunque he preferido dos DataGridView por simplicidad.

Espero os sea útil,
Pep Lluis,

Del Articulo al Albaran

‘ A tren de una consulta de como duplicar filas de un DGV a otro

‘ a petición de Raul os dejo esta idea (muy básica) de como

‘ componer un «albarán» a partir de un DGV con los datos del articulo.

‘ Al realizar un doble clic sobre una fila de artículos

‘ se abrirá un cuadro de dialogo pidiendo la cantidad

‘ una vez introducida, crearemos una nueva línea en un

‘ DataGridView personalizado para contener la entradas

‘ de un albarán… evidentemente ficticio.

‘Ejemplo utilizando VB2008

ArticulosYFacturas

Imports System.Data.OleDb

 

Public Class Form1

   

    ‘Definir objectos de conexion a base de datos

    Private MiConexion As New OleDbConnection(«Provider=Microsoft.Jet.OLEDB.4.0; Data Source=MiBd.mdb;»)

    Private MiAdaptador As New OleDbDataAdapter(«SELECT * FROM Articulos», MiConexion)

    Private MiDataSet As New DataSet()

    Private MiEnlazador As New BindingSource

 

   

    ‘tareas en tiempo de carga de la aplicación

    Private Sub Form1_Load() Handles MyBase.Load

        ‘Abrir conexion y llenar el dataset

        MiConexion.Open()

        MiAdaptador.Fill(MiDataSet)

        Dim commandbuilder As New OleDb.OleDbCommandBuilder(Me.MiAdaptador)

        ‘Asignamos el origen de datos para del DataGridView

        Me.DataGridView1.DataSource = MiDataSet.Tables(0)

        ‘Cerrar la conexión

        MiConexion.Close()

        ‘Clonar o…

        ‘Reproducir la estructura del 1er dataGrid en DataGridView2

        ‘añadiendo una columna para la cantidad y otra para totalizar

        Me.DataGridView2.ColumnCount = Me.DataGridView1.ColumnCount + 1

        Me.DataGridView2.Columns(0).Name = «Cantidad»

        Me.DataGridView2.Columns(0).HeaderText = «Cantidad»

        For x = 1 To Me.DataGridView1.ColumnCount – 1

            Me.DataGridView2.Columns(x).Name = Me.DataGridView1.Columns(x).Name

            Me.DataGridView2.Columns(x).HeaderText = Me.DataGridView1.Columns(x).HeaderText

        Next

        Me.DataGridView2.Columns(DataGridView1.ColumnCount).Name = «Total»

        Me.DataGridView2.Columns(DataGridView1.ColumnCount).HeaderText = «Total»

        Me.DataGridView2.AllowUserToAddRows = False

    End Sub

   

    ‘ Al hacer doble click sobre la fila del articulo esta se duplica en el segundo grid

   

    Private Sub DataGridView1_DoubleClick(….) Handles DataGridView1.DoubleClick

        If DataGridView1.SelectedRows.Count > 0 Then

            ‘Añadir los valores obtenidos de la fila seleccionada

            ‘al segundo datagridview

            Dim Unidades = InputBox(«Numero de unidades para :» _
                + DataGridView1.SelectedRows.Item(0).Cells(1).Value, «Cantidad»)

            If Unidades.Length > 0 Then

                Me.DataGridView2.Rows.Add( _

                   FilaAlbaran( _

                                Unidades, _

                                DataGridView1.SelectedRows.Item(0)) _

                              )

            End If

        End If

    End Sub

   

    ‘ Componer la nueva entrada al DGV del albaran

   

    Function FilaAlbaran(ByVal cantidad As String, ByVal fila As DataGridViewRow) As String()

        ‘Dimensionar el array al tamaño de columnas del DGV + una de total

        Dim Contenido(Me.DataGridView1.ColumnCount) As String

        ‘La primera columna corresponde a la cantidad

        Contenido(0) = cantidad

        ‘Rellenar el contenido con el valor de las celdas de la fila

        For Ndx = 1 To Contenido.Length – 2

            Contenido(Ndx) = fila.Cells(Ndx).Value

        Next

        ‘Calcular y mover a la columna total el resultado de la cantidad por el precio

        Contenido(Contenido.Length – 1) = cantidad * Contenido(Contenido.Length – 2)

        Return Contenido

    End Function

End Class

Copiar o mover filas de un DataGridView a otro.

Atendiendo a la consulta de Javier..

Hola Pep Lluis, he leído varias veces las soluciones que das en los diferentes espacios y foros, y quizá esta pregunta te la hayan hecho ya, pero la verdad ando algo atorado con este problemilla… ahí va :
La idea es tener 2 datagrid’s : el1er Datagrid : Muestra el resultado de una búsqueda, de este datagrid deben seleccionar 1 o varios registros y deberán pasarse al 2do Datagrid : Que debe mostrar los registros seleccionados en el 1er datagrid.Si paso un registro del Datagrid 1 al 2, el registro desaparecerá del 1 y aparecerá en el 2, y viceversa.

____

DgvToDgv

Supongo que existen diversas formas de conseguir lo mismo y sin duda más sofisticadas pero como siempre buscando la simplicidad y en pro de la comprensión os muestro el siguiente ejemplo evitando a exprofeso estructuras complejas difíciles de seguir.

 Para poder tener visión sobre dos maneras distintas de hacerlo, he decido mostrar el primer DGV unido a una estructura de datos y el segundo “clonado” pero sin estar enlazado a ninguna BD, por lo tanto deberéis situar el ejemplo como un punto de partida, en ningún caso como una solución concreta y mucho menos pensando en dos DGV’s enlazados a datos y con relaciones… pues la cosa puede complicarse ligeramente y como os digo no es el propósito ni alcance de este corto.

Tampoco contempla en qué orden y como se ordenan los registros o filas que se copian o mueven de un lado a otro J, también he obviado procesar la excepciones para concentrarnos solo en el código que puede interesarnos… por lo que no está libre de ‘errores’.

Para utilizar este código tienes que crear un nuevo proyecto “Windows Form Application” desde el menú de Visual Basic y arrastrar y soltar dos DGV’s, dos CheckBox y dos Botones de la ventana de herramientas, a continuación solo debes copiar y pegar este código substituyendo el generado por el ‘wizard’. También debes crear una BD de Access en la carpeta ‘debug’ conteniendo la tabla de la BD referenciada en la cadena de conexión, para poder leer tanto código comodamente,.me he tomado la libertad de eliminar las firmas de las funciones, por lo que tendréis de substituir el “(….)” Por el ‘ByVal sender As System.Object, ByVal e As System.EventArgs’ correspondiente en VB2005 o dejarlo simplemente () en VB2008.

Espero que os sea útil,
Saludos!
Pep Lluis,

Imports System.Data.OleDb

Public Class Form1
   
    ‘Definir objectos de conexion a base de datos
    Private MiConexion As New OleDbConnection(«Provider=Microsoft.Jet.OLEDB.4.0; Data Source=TuBd.mdb;»)
    Private MiAdaptador As New OleDbDataAdapter(«SELECT * FROM TuTabla», MiConexion)
    Private MiDataSet As New DataSet()
    Private MiEnlazador As New BindingSource

   
    ‘tareas en tiempo de carga de la aplicación
    Private Sub Form1_Load(….) Handles MyBase.Load
        ‘Abrir conexion y llenar el dataset
        MiConexion.Open()
        MiAdaptador.Fill(MiDataSet)
        Dim commandbuilder As New OleDb.OleDbCommandBuilder(Me.MiAdaptador)
        ‘Asignamos el origen de datos para del DataGridView
        Me.DataGridView1.DataSource = MiDataSet.Tables(0)
        ‘Cerrar la conexión
        MiConexion.Close()
        ‘Clonar o…
        ‘Reproducir la estructura del 1er dataGrid en DataGridView2
        Me.DataGridView2.ColumnCount = Me.DataGridView1.ColumnCount
        For x = 0 As Integer To Me.DataGridView1.ColumnCount – 1
            Me.DataGridView2.Columns(x).Name = Me.DataGridView1.Columns(x).Name
            Me.DataGridView2.Columns(x).HeaderText = Me.DataGridView1.Columns(x).HeaderText
        Next
        Me.CheckBox1.Checked = True     ‘por defecto al iniciar seleccionamos
        Me.CheckBox2.Checked = False    ‘Operaciones origen DGV1, destino DGV2
    End Sub
   
    ‘Boton Copiar
    Private Sub Btn_Copiar_Click(….) Handles Btn_Copiar.Click
        ‘determinar la direccion de copiar entre DGV1 y 2
        If CheckBox1.Checked Then

            ‘Comprobar que existen columnas seleccionadas
            If DataGridView1.SelectedRows.Count > 0 Then
                CopiarSeleccionadosDGV1aDGV2()
            End If
        Else
            If DataGridView2.SelectedRows.Count > 0 Then
                CopiarSeleccionadosDGV2aDGV1()
            End If
        End If
    End Sub
   
    ‘Boton Mover
    Private Sub Btn_Mover_Click(….) Handles Btn_Mover.Click
        ‘determinar la direccion de mover entre DGV1 y 2
        If CheckBox1.Checked Then
            ‘Comprobar que existen columnas seleccionadas
            If DataGridView1.SelectedRows.Count > 0 Then
                MoverSeleccionadosDGV1aDGV2()
            End If
        Else
            If DataGridView2.SelectedRows.Count > 0 Then
                MoverSeleccionadosDGV2aDGV1()
            End If
        End If
    End Sub
   
    ‘Copiar los elementos seleccionados del DGV1 al DGV2
    Sub CopiarSeleccionadosDGV1aDGV2()
        For Each Seleccion As DataGridViewRow In DataGridView1.SelectedRows
            Me.DataGridView2.Rows.Add(ObtenerValoresFila(Seleccion))
        Next
        DataGridView1.ClearSelection()
    End Sub
   
    ‘Copiar los elementos seleccionados del DGV1 al DGV2
    Sub CopiarSeleccionadosDGV2aDGV1()
        For Each Seleccion As DataGridViewRow In DataGridView2.SelectedRows
            Me.MiDataSet.Tables(0).Rows.Add(ObtenerValoresFila(Seleccion))
        Next
        DataGridView2.ClearSelection()
    End Sub
   
    ‘Mover los elementos seleccionados del DGV1 al DGV2
    Sub MoverSeleccionadosDGV1aDGV2()
        ‘Para cada fila seleccionada
        For Each Seleccion As DataGridViewRow In DataGridView1.SelectedRows
            ‘Añadir los valores obtenidos de la fila seleccionada
            ‘al segundo datagridview
            Me.DataGridView2.Rows.Add(ObtenerValoresFila(Seleccion))
            ‘eliminar la fila del DataGridView origen
            DataGridView1.Rows.Remove(Seleccion)
        Next
    End Sub
   
    ‘Mover los elementos seleccionados del DGV1 al DGV2
    Sub MoverSeleccionadosDGV2aDGV1()
        ‘Para cada fila seleccionada
        For Each Seleccion As DataGridViewRow In DataGridView2.SelectedRows
            ‘Añadir los valores obtenidos de la fila seleccionada
            ‘al segundo datagridview
            Me.MiDataSet.Tables(0).Rows.Add(ObtenerValoresFila(Seleccion))
            ‘eliminar la fila del DataGridView origen

            DataGridView2.Rows.Remove(Seleccion)
        Next
    End Sub
   
    ‘Obtener el contenido de la fila en un string()
    ‘con el proposito de copiarlo o moverlo
   
    ‘Recibe el ‘row’ y retorna su contenido en un array tipo string
    Function ObtenerValoresFila(ByVal fila As DataGridViewRow) As String()
        ‘Dimensionar el array al tamaño de columnas del DGV
        Dim Contenido(Me.DataGridView1.ColumnCount – 1) As String
        ‘Rellenar el contenido con el valor de las celdas de la fila
        For Ndx As Integer = 0 To Contenido.Length – 1
            Contenido(Ndx) = fila.Cells(Ndx).Value
        Next
        Return Contenido
    End Function
   
    ‘Seleccionar la direccion en que se efectuara la copia
    Private Sub CheckBox1_CheckedChanged(….) Handles CheckBox1.CheckedChanged
        CheckBox2.Checked = Not CheckBox1.Checked
    End Sub
    Private Sub CheckBox2_CheckedChanged(….) Handles CheckBox2.CheckedChanged
        CheckBox1.Checked = Not CheckBox2.Checked
    End Sub
End
Class

Actualizar una Tabla de una BD SQL utilizando un DataGridView

A menudo en los foros aparece la pregunta de cómo actualizar una BD utilizando un DataGridView. Aquí os dejo una forma de realizarlo. Espero que os sea útil.

Saludos,
Pep Lluis,


‘Definir enlace a datos y objetos del form

Private MiConexion As New SqlConnection( _

   «Datasource=.\SQLEXPRESS;AttachDbFilename=C:\Temp\NORTHWND.MDF» + _
   «;Integrated Security=True;Connect Timeout=30;User Instance=True»)
Private MiAdaptador As New SqlDataAdapter(«SELECT * FROM Shippers», MiConexion)
Private MiDataSet As New DataSet()

Private MiEnlazador As New BindingSource

 

Private MidataGriView As New DataGridView

Private BotonGuardar As New Button

‘En tiempo de carga…
Private Sub Form1_Load(…..) Handles MyBase.Load
    MessageBox.Show(My.Computer.FileSystem.CurrentDirectory)

    ‘Poner titulo a la aplicacion

    Me.Text = «Mantenimiento de Shippers»

    ‘Añadir DataGriView

    MidataGriView.Dock = DockStyle.Top

    Me.Controls.Add(MidataGriView)

    BotonGuardar.Dock = DockStyle.Bottom

    ‘Añadir Boton de Guardar

    BotonGuardar.Text = «Guardar Cambios»

    Me.Controls.Add(BotonGuardar)

    AddHandler BotonGuardar.Click, AddressOf Guardar
    Dim commandbuilder As New SqlCommandBuilder(Me.MiAdaptador)

    MiConexion.Open()

    MiAdaptador.Fill(MiDataSet)

    MiEnlazador.DataSource = MiDataSet.Tables(0)

    MidataGriView.DataSource = MiEnlazador

End Sub

‘Actualizar la tabla enlazada con el DataGridView

Private Sub Guardar(…..)
    Me.MiAdaptador.Update(CType(Me.MiEnlazador.DataSource, DataTable))

End Sub