none
Como contar segun columna dgv1 y pasarlo a otro dgv2 y graficarlo RRS feed

  • Pregunta

  • Si yo tengo una datagridview que una de sus columnas es cliente y este tiene:

    Cliente1

    cliente1

    cliente1

    cliente2

    cliente2

    cliente3

    cliente1

    cliente5

    cliente4

    cliente4

    que en otra dgv 

    Muestre:

    Cliente1 04

    Cliente2 02

    Cliente3 01

    Cliente4 02

    Cliente5 01

    Como lograr eso y por cada cambio que se de en dgv1 automáticamente en la otra dgv2 aparezca

    Saludos y Gracias




    lunes, 26 de marzo de 2018 0:07

Respuestas

  • Puedes escribir una consulta mediante Linq para proyectar el resumen de los datos y presentarlo cada vez que la lista de origen cambia, por ejemplo:

    Private Sub dgv1_DataBindingComplete(sender As Object, e As ...
    
    	dgv2.DataSource = DirectCast(DirectCast(sender, DataGridView).DataSource, DataTable).
    		AsEnumerable().GroupBy(Function(c) c.Field(Of String)("Cliente")).
    		Select(Function(c) New With {.Cliente = c.Key, .Cuenta = c.Count()}).ToList()
    
    End Sub

    • Marcado como respuesta Javier Roque lunes, 26 de marzo de 2018 1:00
    lunes, 26 de marzo de 2018 0:49

Todas las respuestas

  • Jeje, ya vamos viendo cosas como "automáticamente".  Eso es posible, pero es posible usando clases y colecciones para vincular a datos.  Una vez más, el DataTable estorba.

    Si usted usara un BindingList<Clase> para alimentar la primera grilla, donde Clase sería una clase que representa una línea de la grilla (y por lo tanto, de su actual DataTable) que a su vez implementa INotifyPropertyChanged, cambios que realiza el usuario automáticamente cambiarían valores en las propiedades del objeto de la fila que se cambia, que iniciaría el evento PropertyChanged para el o las propiedades que cambian.  Eso habilitaría a un escucha del evento PropertyChanged darse cuenta de que, por ejemplo, se ha cambiado un cliente, lo que podría entonces correr lógica para actualizar una cuenta como la que usted desea mostrar en la segunda grilla.

    Pero bueno, eso sería si usara clases y colecciones.

    Lo que a usted le tocaría es recalcular los totales por cliente cada vez que carga la grilla.  Luego supongo que tendrá que agregar código para recalcular totales de nuevo en los eventos de edición de celda de la grilla.

    Los totales en sí son fáciles de calcular:  Con un Dictionary<string, uint> que represente los totales por cliente, puede usted recorrer el DataTable y simplemente contar.

    public Dictionary<string, uint> CalcularTotalesPorCliente(DataTable data)
    {
        Dictionary<string, uint> totales = new Dictionary<string, uint>();
        foreach (DataRow r in data.Rows)
        {
            string cliente = r[<índice de columna que tiene el nombre del cliente>].ToString();
            if (!totales.ContainsKey(cliente))
            {
                totales.Add(cliente, 0);
            }
            totales[cliente] += 1;
        }
        return totales;
    }

    En C# porque en VB.net no soy nada diestro.


    Jose R. MCP
    Code Samples


    lunes, 26 de marzo de 2018 0:24
    Moderador
  • Puedes escribir una consulta mediante Linq para proyectar el resumen de los datos y presentarlo cada vez que la lista de origen cambia, por ejemplo:

    Private Sub dgv1_DataBindingComplete(sender As Object, e As ...
    
    	dgv2.DataSource = DirectCast(DirectCast(sender, DataGridView).DataSource, DataTable).
    		AsEnumerable().GroupBy(Function(c) c.Field(Of String)("Cliente")).
    		Select(Function(c) New With {.Cliente = c.Key, .Cuenta = c.Count()}).ToList()
    
    End Sub

    • Marcado como respuesta Javier Roque lunes, 26 de marzo de 2018 1:00
    lunes, 26 de marzo de 2018 0:49
  • Bien Willy Perfecto. Ahora viene la siguiente pregunta. en otro Post.

    Gracias

    lunes, 26 de marzo de 2018 1:00
  • De este 

    dgv2.DataSource=...

    Cual es el valor del datatable? necesito graficar ese dgv2 y no me sale me ayudas por favor? el oDatatable no es. Se genera algun otro? como lo tomaria para 

    Chart.datasource=..?



    miércoles, 28 de marzo de 2018 3:53
  • Lo que tienes a la derecha del operador de asignación no es una referencia a un objeto de tipo DataTable, es un tipo anónimo. Si necesitas que el origen de datos sea una referencia a una instancia de la clase DataTable debes copiar los resultados a sus filas, por ejemplo:

    Dim dt As New DataTable
    
    dt.Columns.Add("Cliente", GetType(String))
    dt.Columns.Add("Cuenta", GetType(Int32))
    
    For Each item In DirectCast(DirectCast(sender, DataGridView).DataSource, DataTable).
    		DefaultView().ToTable().AsEnumerable().
    		GroupBy(Function(c) c.Field(Of String)("Cliente")).
    		Select(Function(c) New With {.Cliente = c.Key, .Cuenta = c.Count()}).ToList()
    	dt.Rows.Add(item.Cliente, item.Cuenta)
    Next
    
    dgv2.DataSource = dt

    miércoles, 28 de marzo de 2018 4:29
  • Buenos Dias, para el otro caso estoy correcto?

    Dim dt3 As New DataTable
            Dim Total = Convert.ToInt32(lblTra.Text)
    
            dt3.Columns.Add("ST", GetType(Int32))
            dt3.Columns.Add("GT", GetType(Int32))
            dt3.Columns.Add("GG", GetType(Int32))
            dt3.Columns.Add("LABIQS", GetType(String))
    
            For Each item In DirectCast(GTramiteGG.DataSource, DataTable).
                    DefaultView().ToTable().AsEnumerable().
            Select(Function(c) New With
            {
                .ST = (c.Field(Of Int32)("ST") / Total).ToString("P2"),
                .GT = (c.Field(Of Int32)("GT") / Total).ToString("P2"),
                .GG = (c.Field(Of Int32)("GG") / Total).ToString("P2"),
                .LABIQS = (((c.Field(Of Int32)("ST") / Total) + (c.Field(Of Int32)("GT") / Total) + (c.Field(Of Int32)("GG") / Total)) / 3).ToString("P2")
            }).ToList()
    
                dt3.Rows.Add(item.ST, item.GT, item.GG, item.LABIQS)
            Next
    
            dgvCumple.DataSource = dt3

    Error: La cadena de entrada no tiene el formato correcto.No se puede almacenar <100.00 %> en la columna ST. El tipo esperado es Int32.

    Lo tengo que redondear

    Saludos


    • Editado Javier Roque miércoles, 28 de marzo de 2018 15:03
    miércoles, 28 de marzo de 2018 15:02
  • Si necesitas que el origen, de la grilla dgvCumple, sea una referencia a una instancia de la clase DataTable, pues si.

    - Respecto a la excepción que obtienes

    Cuidado con los tipos que defines para las columnas, si la proyección incluye columnas de tipo string entonces las columnas de la variable dt3 deberían ser también del tipo string y no del tipo int, o determinar un tipo decimal y otorgar el formato de porcentaje sobre las columnas de la grilla y no en el origen, esto creo que es lo más adecuado.

    miércoles, 28 de marzo de 2018 15:08