none
LINQ Datagridview unir filas en una sola RRS feed

  • Pregunta

  • Hola que tal, podrian ayudarme, porfavor?

    Tengo una consulta LINQ a la cual le concateno los valores de una tabla en un solo campo para mostrar en el datagridview

    Dim Consulta = (From ConsultaConceptos In ds.Tables("Concepto")
                         Select New With { _
                                   .Concepto = "Cantidad: " & ConsultaConceptos.Field(Of String)("cantidad") & " ValorUnitario: " & ConsultaConceptos.Field(Of String)("valorUnitario") & " importe:  " & ConsultaConceptos.Field(Of String)("importe") & " Descripción: " & ConsultaConceptos.Field(Of String)("descripcion")
                               })
                               
                DataGridView1.DataSource = Consulta.ToList


    El caso es que en la tabla Concepto
    puede a ver más de una fila a diferencia de las de más tablas que siempre tendran solo 1

    Ejemplo:

    ____________Concepto_______________
    dato             dato             dato      dato   fila1
    __________________________________
    dato             dato             dato      dato  fila2
    __________________________________
    dato             dato             dato      dato  fila3

    Lo que quiero hacer es lo siguiente:

    Mostrar las filas  1,2 y 3 en una sola


    ____________Concepto_______________
    dato dato dato dato dato dato dato dato dato dato dato dato  fila 1

    De antemano se que esto si es posible porque ya esta hecho en un sistema existente

    Saludos!


    • Cambiado José De Alva martes, 29 de marzo de 2016 23:42
    • Cambiado Enrique M. Montejo miércoles, 30 de marzo de 2016 10:43 Pregunta relacionada con LINQ.
    lunes, 28 de marzo de 2016 21:42

Respuestas

  • Ok.  Existen los operadores en VB.net?  Podría agregarle un operador implícito de conversión a String a la clase Dato.  Creo que eso eliminaría el uso de () =>, que se llama expresión lambda.

    Pero mejor no lo compliquemos.  Hagamos la ruta larga.

    public class Dato
    {
        //Declaramos una propiedad tipo string para contener el valor.
        public string Valor { get; set; }
        public override string ToString() { return Valor; }
    }
    
    
    //Luego hacemos lo que hacíamos pero coleccionamos objetos tipo Dato, no tipo String como antes.
    var filas = from cc in ds.Tables["Concepto"].Rows
                select new Dato() { Valor = String.Format("Cantidad:  {0} ValorUnitario:  {1} Importe:  {2} Descripción:  {3}",
                cc["cantidad"], cc["valorUnitario"], cc["importe"], cc["descripcion"]) };
    
    var listaFilas = filas.ToList();
    if (listaFilas.Count > 0)
    {
        string r = String.Empty;
        foreach Dato d in listaFilas
    	{
    	    r += " " + d.Valor;
    	}
    	r = r.Trim();
    	listaFilas.Clear();
        Dato d = new Dato()
        {
            Valor = r
        };
        listaFilas.Add(d);
    }
    DataGridView1.DataSource = listaFilas;
    ¿Mejor?


    Jose R. MCP
    Code Samples

    • Marcado como respuesta Diego Cantú jueves, 31 de marzo de 2016 18:53
    jueves, 31 de marzo de 2016 17:19

Todas las respuestas

  • Le muestro C# pues no programo en VB.

    //Creo que le falta el .Rows.  No uso datasets/tables.  Verifique.
    var filas = from cc in ds.Tables["Concepto"].Rows
    			select String.Format("Cantidad:  {0} ValorUnitario:  {1} Importe:  {2} Descripción:  {3}",
    			cc["cantidad"], cc["valorUnitario"], cc["importe"], cc["descripcion"]);
    
    var listaFilas = filas.ToList();
    if (listaFilas.Count > 0)
    {
        string r = String.Join(" ", listaFilas);
    	listaFilas.Clear();
    	listaFilas.Add(r);
    }
    DataGridView1.DataSource = listaFilas;


    Jose R. MCP
    Code Samples

    martes, 29 de marzo de 2016 19:57
  • Hola que tal , gracias por responder , lo transforme a VB

    Dim Consulta = (From ConsultaConceptos In ds.Tables("Concepto").Rows
                         Select String.Format("Cantidad:  {0} ValorUnitario:  {1} Importe:  {2} Descripción:  {3}", _
                                          ConsultaConceptos("cantidad"), ConsultaConceptos("valorUnitario"), ConsultaConceptos("importe"), ConsultaConceptos("descripcion")))
            Dim listaFilas = Consulta.ToList()
                If listaFilas.Count > 0 Then
                    Dim r As String = String.Join(" ", listaFilas)
                    listaFilas.Clear()
                    listaFilas.Add(r)
                End If
                DataGridView1.DataSource = listaFilas                                                                                                                                                       
    Y en el datagridview solo me muestra una columna length y el resultado de la fila es solo 111
    supongo que tu respuesta es correcta pero por alguna razón no funciona en VB

    Saludos!
    miércoles, 30 de marzo de 2016 17:31
  • Ok, perdón.  Es que nunca nunca uso un List<String> para alimentar un DGV.  Lo que está pasando es que el DGV está enumerando las propiedades de un String y pues solamente hay una:  Length.

    No sé si VB tiene el tipo de datos dynamic pero una opción es usar List<dynamic>.  La otra opción es crear una pequeña clase con una propiedad tipo string que contendría el valor de texto que busca.

    public class Dato
    {
        //Declaramos una propiedad tipo string para contener el valor.
        public string Valor { get; set; }
        public override string ToString() { return Valor; }
    }
    
    
    //Luego hacemos lo que hacíamos pero coleccionamos objetos tipo Dato, no tipo String como antes.
    var filas = from cc in ds.Tables["Concepto"].Rows
    			select new Dato() { Valor = String.Format("Cantidad:  {0} ValorUnitario:  {1} Importe:  {2} Descripción:  {3}",
    			cc["cantidad"], cc["valorUnitario"], cc["importe"], cc["descripcion"]) };
    
    var listaFilas = filas.ToList();
    if (listaFilas.Count > 0)
    {
        string r = String.Join(" ", () =>
        {
            foreach (Dato d in listaFilas)
            {
                yield return d.Valor;
            }
        });
    	listaFilas.Clear();
            Dato d = new Dato()
            {
                Valor = r
            };
    	listaFilas.Add(d);
    }
    DataGridView1.DataSource = listaFilas;

    Algo así.  Ahora el DGV tendrá una única columna llamada Valor.


    Jose R. MCP
    Code Samples

    miércoles, 30 de marzo de 2016 18:14
  • Hola Jose

    muchas gracias por tú tiempo,

    eh estado tratando de convertir el codigo.. 

    pero no me es posible esta parte (" ", () => VB no la reconoce

    yield no existe en VB

    me imagino que valor quedaria a si en la clase Dato

     Public Property Valor As String
            Get
                Return Me.Valor
            End Get
            Set(ByVal value As String)
                Me.Valor= Conversions.ToString(value)
            End Set
        End Property


    de antemano muchas gracias, seguire intentando 


    Saludos!
    jueves, 31 de marzo de 2016 17:13
  • Ok.  Existen los operadores en VB.net?  Podría agregarle un operador implícito de conversión a String a la clase Dato.  Creo que eso eliminaría el uso de () =>, que se llama expresión lambda.

    Pero mejor no lo compliquemos.  Hagamos la ruta larga.

    public class Dato
    {
        //Declaramos una propiedad tipo string para contener el valor.
        public string Valor { get; set; }
        public override string ToString() { return Valor; }
    }
    
    
    //Luego hacemos lo que hacíamos pero coleccionamos objetos tipo Dato, no tipo String como antes.
    var filas = from cc in ds.Tables["Concepto"].Rows
                select new Dato() { Valor = String.Format("Cantidad:  {0} ValorUnitario:  {1} Importe:  {2} Descripción:  {3}",
                cc["cantidad"], cc["valorUnitario"], cc["importe"], cc["descripcion"]) };
    
    var listaFilas = filas.ToList();
    if (listaFilas.Count > 0)
    {
        string r = String.Empty;
        foreach Dato d in listaFilas
    	{
    	    r += " " + d.Valor;
    	}
    	r = r.Trim();
    	listaFilas.Clear();
        Dato d = new Dato()
        {
            Valor = r
        };
        listaFilas.Add(d);
    }
    DataGridView1.DataSource = listaFilas;
    ¿Mejor?


    Jose R. MCP
    Code Samples

    • Marcado como respuesta Diego Cantú jueves, 31 de marzo de 2016 18:53
    jueves, 31 de marzo de 2016 17:19
  • Trate de hacer esto:

    Dim Consulta = From ConsultaConceptos In Conceptos
      Select New With {.Concepto = "Cantidad: " & ConsultaConceptos.Field(Of String)("cantidad") & " ValorUnitario: " & ConsultaConceptos.Field(Of String)("valorUnitario") & " importe:  " & ConsultaConceptos.Field(Of String)("importe") & " Descripción: " & ConsultaConceptos.Field(Of String)("descripcion")}


                Dim Fila As New DataTable("Fila")
                Fila.Columns.Add("Fila")

                Dim row As DataRow = Fila.NewRow()
                row("Fila") = Consulta.ToList
                Fila.Rows.Add(row)
                DataGridView1.DataSource = Fila

    Y si me manda solo una fila de mi consulta y no 2 .. pero con este mensaje

    System.Collections.Generic.List`1[VB$AnonymousType_4`1[System.String]] 

    Si le quito el ToList a Consulta manda:

    System.Data.EnumerableRowCollection`1[VB$AnonymousType_4`1[System.String]]

    y si pongo Consulta.AsEnumerable

    System.Data.EnumerableRowCollection`1[VB$AnonymousType_4`1[System.String]]

    Alguna manera de hacer un cast?

    Saludos

    jueves, 31 de marzo de 2016 17:40
  • Ya funciono!!

    Al final queda a si:

    Dim listaFilas = Filas.ToList

                If (listaFilas.Count > 0) Then
                    Dim r As String = String.Empty
                    Dim d As Dato = New Dato
                    For Each d In listaFilas
                        r += " " + d.Valor
                    Next
                    r = r.Trim
                    listaFilas.Clear()
                    d.Valor = r
                    listaFilas.Add(d)
                End If
                DataGridView1.DataSource = listaFilas
            Next


    Muchas gracias! te la rifaste

    Saludos!
    jueves, 31 de marzo de 2016 18:53
  • Podrias apoyarme con esta otra , es de lo mismo pero más elaborada , primero queria hacerlo con un solo XML

    https://social.msdn.microsoft.com/Forums/sqlserver/es-ES/65daae91-d7e4-4e8a-9756-15bcedf4bcb0/linq-datagridview-unir-filas-en-una-sola-con-ms-de-1-origen-de-dato?forum=linqes

    te lo agradeceria

    jueves, 31 de marzo de 2016 19:47