Dos Tablas y sus relaciones en un DataGridView a traves de un ‘ComboBoxColumn’

Ejemplo de cómo añadir una columna de selección unida a una tabla de ‘maestros’ y relacionada con su identificador en la tabla ‘detalles’, en casos reales solo teneis que substituir las tablas por los ‘sources’ de las tablas en vuestra BD.
Me gustara recibir vuestros comentarios… ;-)


Combo3
 


Imports System
Imports System.Data

Public Class Form1
    Private dataGridView1 As New DataGridView()


    Private Sub Form1_Load() Handles Me.Load
       
        ‘ Simular tabla con los Detalles
       
        Dim Detalles As New DataTable(“Detalle”)
        Detalles.Columns.Add(“Actividad”)
        Detalles.Columns.Add(“Nombre”)
        Detalles.Columns.Add(“Telefono”)
        Detalles.Rows.Add(“001″, “Pep Lluis”, “231.321.321″)
        Detalles.Rows.Add(“002″, “Luis Franco”, “Internacional”)
        Detalles.Rows.Add(“003″, “Marc Rubiño”, “111.222.333″)
        Detalles.Rows.Add(“004″, “Javier Conesa”, “91.244.32.32″)
       
        ‘ Simular tabla con los Id’s Maestros
       
        Dim Maestros As New DataTable(“Maestro”)
        Maestros.Columns.Add(“Actividad”)
        Maestros.Columns.Add(“Descripcion”)
        Maestros.Rows.Add(“001″, “POgramaor”)
        Maestros.Rows.Add(“002″, “Torero”)
        Maestros.Rows.Add(“003″, “Banderillero”)
        Maestros.Rows.Add(“004″, “ANALista”)

       
        ‘ Construir el DS y establecer relaciones
       
        Dim MiDataSet As New DataSet
        MiDataSet.Tables.Add(Detalles)
        MiDataSet.Tables.Add(Maestros)
        MiDataSet.Relations.Add(“Actividad”, _
              MiDataSet.Tables(“Maestro”).Columns(“Actividad”),_
              MiDataSet.Tables(“Detalle”).Columns(“Actividad”))
        
        ‘ Añadir una columna ‘ComboBox’
        ‘ Conteniendo la tabla ‘Maestro’
       
        Dim MiBoxColumn As New DataGridViewComboBoxColumn
        MiBoxColumn.DisplayMember = “Descripcion”
        MiBoxColumn.ValueMember = “Actividad”
        MiBoxColumn.DataPropertyName = “Actividad”
        MiBoxColumn.DataSource = MiDataSet.Tables(“Maestro”)
        Me.dataGridView1.Columns.Add(MiBoxColumn)
       
        ‘ Visualizar el DGV con la columna combo ‘Maestro’
        ‘ y las columnas y tablas de ‘Detalle’
       
        Me.dataGridView1.Dock = DockStyle.Fill
        Me.Controls.Add(dataGridView1)
        Me.dataGridView1.DataSource = MiDataSet.Tables(“Detalle”)

   End Sub
End Class


Si os interesa en determinadas situaciones podeis “camuflar” el combo para que tenga un aspecto como este :



Combo4


De esta forma no podran modificar ni desplegar las opciones y su aspecto sera como el de cualquier otra columna.
Ajustando las propiedades :

        MiBoxColumn.DisplayStyle = DataGridViewComboBoxDisplayStyle.Nothing
        MiBoxColumn.ReadOnly = True

Saludos,
Pep Lluis,

PD. Agradecemos la participacion de los actores secundarios (Javier, Luis i Marc), aunque tengo mis dudas sobre si son personajes reales o ficticios ;-)

31 thoughts on “Dos Tablas y sus relaciones en un DataGridView a traves de un ‘ComboBoxColumn’”

  1. Hola, he tenido una gran duda, bueno primeramente, lo que hice fue cambiar los dataSet y enlazarlos a SQLServer2005 he hice las relaciones y todo funciona de maravilla, pero mi duda es… ¿De que manera se pueden actualizar los registros de la BD con un DataSet relacionado como este? Me.dataGridView1.DataSource = MiDataSet.Tables(“Detalle”)

    Saludos, espero su respuesta!! muy agradecido por todo!

  2. Puedes utilizar aluno de los ejemplo que encontraras en los ‘TAG’ de MDF’s y DataGridView.
    Si no es suficiente contacta de nuevo y montamos un ejemplo.
    Pep Lluis,

  3. Hola Pep, primero gracias por tu pagina. Son ejemplos muy claros y precisos.
    Tengo que hacer algo muy parecido a lo del ejemplo pero con tablas de SQL. Las cargo luego en un dataset y sigo el codigo tuyo para añadir una columna con un combobox. Pero este me parece vacio y sin valor, aunque si lo desplego tiene la tabla cargada.
    La relacion yo creo que esta bien hecha, pero no lo consigo. Adjunto el codigo. Un saludo.

    Dim Detalles As New DataTable(“Detalle”)
    Dim Selecciona As String = “SELECT * FROM EyP_dependencias”
    Try
    da_Unidades = New SqlClient.SqlDataAdapter(Selecciona, sCnn)
    dt_Unidades = New DataTable
    da_Unidades.Fill(Detalles)

    Catch ex As Exception
    MessageBox.Show(“ERROR al conectar o recuperar los datos:” & vbCrLf & _
    ex.Message, “Conectar con la base”, _
    MessageBoxButtons.OK, MessageBoxIcon.Error)
    End Try

    ‘ Tabla maestra de unidades

    Dim Maestros As New DataTable(“Maestro”)
    Selecciona = “SELECT * FROM TM_Unidadespresupuestos order by Código”
    Try
    da_unidades = New SqlClient.SqlDataAdapter(Selecciona, sCnn)
    dt_unidades = New DataTable
    da_Unidades.Fill(Maestros)

    Catch ex As Exception
    MessageBox.Show(“ERROR al conectar o recuperar los datos:” & vbCrLf & _
    ex.Message, “Conectar con la base”, _
    MessageBoxButtons.OK, MessageBoxIcon.Error)
    End Try

    Dim MiDataSet As New DataSet
    MiDataSet.Tables.Add(Detalles)
    MiDataSet.Tables.Add(Maestros)
    MiDataSet.Relations.Add(“Actividad”, MiDataSet.Tables(“Maestro”).Columns(“Código”), MiDataSet.Tables(“Detalle”).Columns(“CódigoUCcliente”))

    Dim MiBoxColumn As New DataGridViewComboBoxColumn
    MiBoxColumn.DisplayMember = “Código”
    MiBoxColumn.ValueMember = “Código”
    MiBoxColumn.DataPropertyName = “Código”
    MiBoxColumn.DataSource = MiDataSet.Tables(“Maestro”)
    Me.dataGridView1.Columns.Add(MiBoxColumn)

    Me.dataGridView1.Dock = DockStyle.Fill
    Me.Controls.Add(dataGridView1)
    Me.dataGridView1.DataSource = MiDataSet.Tables(“Detalle”)

  4. Hola Francisco,

    Solucionaras este problema utilizando el mismo nombre para los los campos relacionados…

    MiDataSet.Relations.Add(“Actividad”, MiDataSet.Tables(“Maestro”).Columns(“Código”), MiDataSet.Tables(“Detalle”).Columns(“Código”))

    Aunque no conozco tu aplicacion, recuerda que no es necesario crear un dataset.. puedes obtenerlo directamente de la consulta al SQL. En nuestro caso lo componemos pues las tablas no provienen del resultado de una consulta.

    Saludos,
    Pep Lluis,

  5. Gracias Pep,

    Justo lo acababa de ver. Bueno ha sido facil.
    Lo tengo en un datatable porque luego quiero que los cambios en el datagridview se apliquen en la tabla SQL. La unica modificacion que permito en el datagridview es el campo de relacion en la tabla detalle que es la del combobox.

    Gracias y un saludo

    Francisco Macias

  6. la verdad si en ejemplo seria mejor “complicar” un poco seria haci:

    en un formulario saliera el datagriw siguiente:
    direc_dcto gerec distrito
    c:\dc\tabla.pdf general san luis
    c:\dc\tabla1.pdf adminitra san luis
    c:\dc\tabla2.pdf rr.hh san luis

    seria cambiar asi,

    direc_dcto gerec distrito
    seleccionar general san luis
    seleccionar adminitra san luis
    seleccionar rr.hh san luis

    me parece que se puede ver mejor

    como lo puedo hacer?

  7. Hola Emilio,
    Debes disculparme, pero no entiendo tu pregunta, si te parece bien me gustaria me lo detallaras para ver si puedo ayudarte.
    Saludos,
    Pep Lluis,

  8. Hola Matri,
    Mayormente se utilizan estos ejemplo para demostrar algunas posibilidades de los componentes, en este caso sobre todo de como unir dos tablas y visualizar una seleccion en un comboBoxButton. No es que sea rebuscado… es un simple ejercicio, en ningun caso lo consideres una recomendacion de buenas practicas.
    Saludos y gracias por tu comentario.

  9. Buenas.
    A partir de social.msdn he llegado aquí donde he posteado el problema que tengo, que básicamente lo que quiero es lo que habéis hecho aquí con las dos tablas y sus relaciones, la diferencia está en que las claves (primarias y externas) son strings y yo los tengo integer y falla, te dejo el post de social.

    Tengo 2 tablas
    Una tabla articulos con tres campos PK(int), descripcion (str)y FKfamilias(int)
    Otra de familias con 2 campos PKfamilia(int) y descr.(str)
    una muestra puede ser
    para familia
    PKfamilia(int) descr.(str)
    1 familia1
    2 familia2

    para articulos
    Pk descr fkfamilia
    1 art1 1
    2 art2 2
    3 art3 1

    Tengo un datagridview enlazado a la tabla articulos que tiene dentro una columna DataGridViewComboBoxColumn que obtiene los datos de la tabla familias que alimenta la fk de la tabla articulos, el problema es el siguiente
    cuando se añade una nueva fila obtengo una infinidad de errores del datagridview indicando que el valor del DataGridViewComboBoxColumn no es válido y en efecto eso sucede porque por omision al añadir una fila nueva a las celdas con campos integer les añade un 0, que, en este caso, no es fk en la tabla familias,
    mi pregunta es ¿cómo puedo hacer para que el datagridview no me añada ese 0 a la celda por omisión y me provoque dicho error?
    Claro está que si agrego un registro con el 0 y una descripcion cualquiera a la tabla familias se soluciona el problema pero eso no es lo que quiero.
    Uso LINQ to SQL por si sirve. en VB.net 9.0

    Gracias de antemano

  10. Hola Fisli,
    Si aun no has recibido la solucion desde el post en los foros… te ruego contactes conmigo para tratar el problema de forma agil.

    Opcion [Contact] en la parte superior izquierda.
    Saludos,
    Pep Lluis,

  11. Mi pregunta es la siguiente:
    cargo la el datagrid mediante una consulta en sql
    despues le doy limpiar el datagrid
    La cosa es que al parecer cuando le doy limpiar el datagrid no limpia la columna donde cree mi combobox
    ¿Que se puede hacer?

  12. Pep Lluis, primero darte las gracias por tu ejemplo, porque me ha ido genial, claro y conciso.

    Sólo me ha llevado un poco de cráneo (Lo comento por si a alguien le pasa lo mismo) el ValueMember y el DataPropertyName, y es que en mi caso los campos tenían diferente nombre en las dos tablas, y los tenía cambiados, y me daban un error.

  13. Hola Pepluis una preg cuando se carga nuevamente el grid luego de una actualizacion(eliminar, insertar, etc)para que refreesque los datos, tambien hay que asignar nuevamente la relacion?

    Gracias

  14. solo quiero agradecer ya tenia rato buscando algo como esto y la verdad que tu codigo esta muy entendible esperemos y funcione xq el dia de hoy no alcansare a comprobarlo

    MUCHAS GRACIAS Y TE FELICTO POR LO ENTENDIBLE DEL TEMA

  15. oye primo, como le haces por ejemplo, tengo un grid y una columna como un combo box de otro grid, tns conforme actualize el otro grid este campo debe ir visualizando los nuevos valores? pude hacer todo menos hacer ke el campo se actualize solo

  16. Jorge,
    Si quieres utiliza la opcion [Contact], para formularme de nuevo la cuestion, pues no entiendo del todo tu pregunta.

    Saludos… y espero tus noticias,
    Pep Lluis,

  17. Antes que nada, perdón por escribir tanto tiempo despues de publicado el artículo.

    Excelente trabajo, es algo que buscaba y no había logrado hacer, pero tengo una duda.

    Al copiar el texto, tal y como lo presentas, en un nuevo formulario de ejemplo, me encuentro con que cambio los datos del combo y no me actualiza las columnas restantes.

    ¿Hay alguna manera de hacer esto?

    Utilizo VB 2008 Express sobre win7

    Gracias de antemano por la respuesta.

    Andres

  18. Tengo un datagridview el cual no esta enlazado, los datos los cargo de forma manual, el problema es tengo un combobox dentro del datagridview y quiero que cada que se agregue una fila al datagrid, en el combobox del datagrid se me cargue cierta informacion que tengo en una tabla o en una matrix….
    es decir que me aparezcan como items del combo…

    cargar un datagrid con un objeto table, o dataset o datadapter es sencillo…lo que pregunto no es tan sencillo quien me puede ayudar??????????

  19. Saludos de favor su ayuda necesito realizar algo mas facil pero no se como tengo que recuperar los datos de una sola tabla pero quiero que el campo principal por ejemplo idpersona sea un link el cual me dirija a otra pagina y me muestre los datos de esa persona, en epsera de su ayuda gracias

  20. Hola como puedo hacer para que varios registro seleccionados en un datagrid, ademas de gurdarlos en una tabla tambien los pueda modificar de un solo clic ya sea uno, dos cincuenta registros.
    Gracias Espero me ayuden

  21. Hola Buenas Tardes
    Mi pregunta es al Sig. tengo dos Data Grid View con un campo en comun, yo lo que quiero es pasar el resultado de los dos Data Grid View con el campo en comun en un tercer Data Grid View

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>