DataGridView… Quiero saltar de de Columna!!! no de fila

Muchos de nosotros aprovechamos el control DataGridView como visualizador, sin embargo además puede ser una excelente ayuda para añadir nuevas filas a nuestras estructuras de datos.

En un proceso donde la información se estructura mediante columnas y líneas, el objetivo es introducir nuevas filas con la mayor facilidad posible, es entonces cuando nos percatamos de que por defecto el DataGridView actúa de una forma un tanto inconveniente para nuestro cometido. Cada vez que pulsamos ‘enter’ ya sea en modo ‘edición’  el efecto es que nos crea una nueva fila desplazándose acto seguido a la primera celda de la misma (como en Excel), entonces nos obliga a utilizar los cursores para reubicar el ‘foco’ a la celda donde va a continuar nuestra próxima entrada. Realmente es un inconveniente, pues nos hace perder muchísimo tiempo empleándolo en pulsaciones simplemente inútiles.

Dicho esto, para poder introducir datos de izquierda a derecha tal y como estamos acostumbrados en la mayoría de situaciones en la que manejamos información, podemos recurrir a varios recursos, os proponemos ver como anulando las funciones ‘ProcessDialogKey’  ‘OnKeyDown’ y rescribiendo el código para que la pulsación de una tecla ‘enter’ sea substituida por un ‘tab’  utilizando un ‘sendkeys’, pudiendo conseguir una mejora increíble en la funcionalidad. También en una segunda propuesta os introducimos a como manejar el direccionamiento de selección de las ‘celdas’ de un DataGridView capturando las pulsaciones en el ‘PreProcessMessage’, ambas heredando la funcionalidad DataGridView y añadiendo a esta personalidad propia.

Esperamos que os sea de utilidad… solo tenéis que ¡cortar y pegar!

Pep Lluis y Rafael.

'' (c) Pep Lluis & Rafa Vargas

'' Ambos ejemplos vienen derivados de una inquietud compartida en

'' el ultimo Code Camp del Escorial en el 2006 entre Rafa Vargas y

'' Pep Lluis… no cabe duda del lema 'Comparte y Aprenderas'.

''

Public Class form1

    Private WithEvents _MiDGView1 As New DgvPlus     'Mi DGV, que traduce el 'Enter' en 'Tab'

    Private WithEvents _MiDGView2 As New MiDGView    'Mi DGV, que controla la posicion de la celda actual

    '

    ' al lanzar nuestro form (en el momento de carga)

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

        '

        'Construir el primer DGV

        _MiDGView1.Dock = DockStyle.Left                                          'Acoplarlo a la izquierda

        _MiDGView1.ColumnCount = 4                                                'con cuatro columnas

        _MiDGView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill     'Ajustarlo al tamaño

        _MiDGView1.Columns(0).HeaderText = "Caso A"                               'Etiquetar columna

        Me.Controls.Add(_MiDGView1)                                               'Añadirlo al form

        '

        'Construir el segundo DGV

        _MiDGView2.Dock = DockStyle.Right

        _MiDGView2.ColumnCount = 4

        _MiDGView2.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill

        _MiDGView2.Columns(0).HeaderText = "Caso B"

        Me.Controls.Add(_MiDGView2)

        '

        'La ventana (aspecto)

        Me.Width = Me._MiDGView1.Width + Me._MiDGView2.Width + 25           'Ajustar el ancho del form

        Me.Text = "Pep/Rafa DataGridView"                                    'Ponerle titulo

    End Sub

End Class

'

' Nuestra personalizacion para MiDGView —————————————————————

'

Public Class MiDGView

    Inherits DataGridView       'Heredar del DataGridView

    '

    'Prepocesar mensajes

    Public Overrides Function PreProcessMessage(ByRef msg As System.Windows.Forms.Message) As Boolean

        If msg.Msg = 257 And msg.WParam.ToInt32 = 13 Then                    'Si es 'KeyDown' y 'Enter'

            Dim MiCol As Integer = 0

            Dim MiFil As Integer = Me.CurrentCell.RowIndex – 1

            If Me.CurrentCell.ColumnIndex < Me.ColumnCount – 1 Then          'Si noSalimos del limite

                MiCol = Me.CurrentCell.ColumnIndex + 1                       'Siguiente columna

            End If

            If MiFil > -1 Then Me.CurrentCell = Me(MiCol, MiFil) 'Posicionar columna

        End If

        Return MyBase.PreProcessMessage(msg)

    End Function

End Class

'

' Nuestra personalizacion para DGVPlus —————————————————————

'

Public Class DgvPlus

    Inherits DataGridView   'Heredar del DataGridView

    '

    'en el 'processDialogKey'… cuando estamos en edicion

    Protected Overrides Function ProcessDialogKey(ByVal keyData As System.Windows.Forms.Keys) As Boolean

        If keyData = Keys.Enter Then                'Si es 'enter'

            SendKeys.Send(Chr(Keys.Tab))            'Enviar un 'Tab'

            Return True                             'Marcar como procesado

        Else                                        'en caso contrario

            Return MyBase.ProcessDialogKey(keyData) 'devolver KeyData

        End If

    End Function

    '

    ' en 'OnKeyDown'… cuando no estamos en edicion

    Protected Overrides Sub OnKeyDown(ByVal e As System.Windows.Forms.KeyEventArgs)

        If e.KeyData = Keys.Enter Then              'Si es 'enter'

            SendKeys.Send(Chr(Keys.Tab))            'Enviar un 'Tab'

        Else

            MyBase.OnKeyDown(e)                     'Devolver el KeyEventArgs

        End If

    End Sub

End Class

Copiar filas entre dos DataGridView

Siguiendo la discusión en los foros MSDN de VB en Español, os adjunto una propuesta de como copiar una fila entre DataGridView's. Existen muchisimas formas de hacerlo y os animo a discutirlas aqui. Os dejo un ejemplo simple, para animaros a proponer ejemplos mas sutiles.

Como siempre prodeis descargar DataGridView2 en 'attachments'

Un Abrazo,
Pep Lluis,

Visualizar una hoja de Excel en un DataGridView

Aqui teneis un ejemplo para visualizar una hoja de Excel en un DataGridView.
Como Siempre podeis descargaros el Codigo haciendo click en 'attachments'

System.Data.OleDb

Public Class Form1
 
Private MiConexion As New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Extended Properties = 'Excel 8.0'; Data Source=|DataDirectory|\hoja1.xls;")
 
Private MiAdaptador As New OleDbDataAdapter("SELECT * FROM [Hoja1$]", MiConexion)
 
Private MiDataSet As New DataSet()
 
Private MiEnlazador As New BindingSource
 
 
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
   
Dim commandbuilder As New OleDb.OleDbCommandBuilder(Me.MiAdaptador)
   
MiConexion.Open()
    MiAdaptador.Fill(MiDataSet)
    MiEnlazador.DataSource = MiDataSet.Tables(0)
   
Me.DataGridView1.DataSource = MiEnlazador
 
End Sub

End Class
 
Pep Lluis,

Introducir datos desde un textbox a una base access en vb.net

La idea basica es utilizar un 'bindingsource' y un commandbuilder para tu adataptador de datos, a partir de este concepto es tan simple como añadir un 'datarow' o registro a tu tabla de datos 'datatable' cada vez que pulsamos 'enter' y la longitud de los datos introducidos es mayor de cero. Posteriormente para actualizar o añadir los registros del 'datatable' a la BD de access utilizaremos el mandato 'update' (al pulsar un boton en nuestro caso), o asociado al momento que consideres oportuno.

Puedes descargarte este ejemplo haciendo click en 'attachments'

Imports System.Data.OleDb
Imports System.Data.DataRow

Public Class Form1
 
Private MiConexion As New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|\bd1.mdb")
 
Private MiAdaptador As New OleDbDataAdapter("SELECT * FROM Nombres", MiConexion)
 
Private MiDataSet As New DataSet()
 
Private MiEnlazador As New BindingSource

  Private Sub Form1_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles Me.KeyPress
   
If (e.KeyChar = Chr(Keys.Enter)) And (Me.TextBox1.Text.Length > 0) Then
     
Dim nombre As DataRow
      nombre = MiDataSet.Tables(0).NewRow()
      nombre(
"Nombre") = TextBox1.Text
      MiDataSet.Tables(0).Rows.Add(nombre)
     
Me.TextBox1.Text = ""
     
Me.ComboBox1.SelectedIndex = Me.ComboBox1.Items.Count – 1
   
End If
 
End Sub

  Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
   
Dim commandbuilder As New OleDb.OleDbCommandBuilder(Me.MiAdaptador)
    MiConexion.Open()
    MiAdaptador.Fill(MiDataSet)
    MiEnlazador.DataSource = MiDataSet.Tables(0)
   
Me.ComboBox1.DataSource = MiEnlazador
   
Me.ComboBox1.DisplayMember = "Nombre"
   
Me.ComboBox1.ValueMember = "Id"
   
Me.TextBox1.Select()
 
End Sub

  Private Sub Guardar(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
   
Me.MiAdaptador.Update(CType(Me.MiEnlazador.DataSource, DataTable))
 
End Sub

Espero que sea de tu utilidad.
Pep Lluis,

Actualizar una BD Access, utilizando un DataGridView

A peticion de Ester, en el foro Español de Visual Basic, me complace adjuntaros un pequeño proyecto para actualizar los datos de una BD de access desde un DataGridView. Debo destacar y debemos situar este ejemplo dentro de un contexto de manipulacion de bases de datos relativamente pequeñas, desconozco su rendimiento si es usado en tablas de dimensiones considerables, por lo que este ejemplo es solo para dar una idea de como lo hariamos desde este control y en ningun caso como solucion profesional a la consulta/actualizacion de una BD.

Saludos,
Pep LLuis,