none
Como sumar una columna segun condicion de otra columna? RRS feed

  • Pregunta

  • Por ejemplo:

    Id | Codigo | Tipo | Precio

    1    G001    Ingreso    90.00

    2    G002    Ingreso     55.50

    3    G003    Egreso       23.65

    Lo que deseo es obtener en un label el total de Ingreso y el Total de Egresos

    Por el momento solo tengo un total general pero suma todo.

    Espero de su ayuda



    • Editado Javier Roque miércoles, 22 de febrero de 2017 17:07
    miércoles, 22 de febrero de 2017 17:00

Respuestas

  • Javier Rocco,

    Asigna el resultado de las variables a las etiquetas

    Dim TotalIngresos, TotalEgresos As Decimal
    For Each Fila As DataGridViewRow In DataGridView1.Rows.
    		Cast(Of DataGridViewRow).Where(Function(x) Not x.IsNewRow)
    	Dim Tipo = Convert.ToString(Fila.Cells("Tipo").Value)
    
    	TotalIngresos += IIf(Tipo(0) = "I", Convert.ToDecimal(Fila.Cells("Precio").Value), 0)
    	TotalEgresos += IIf(Tipo(0) = "E", Convert.ToDecimal(Fila.Cells("Precio").Value), 0)
    Next
    
    lblTotalIngresos.Text = TotalIngresos.ToString("N2")
    lblTotalEgresos.Text = TotalEgresos.ToString("N2")


    Espero que la información proporcionada te haya sido de utilidad, quedo atento a tus comentarios.
    • Marcado como respuesta Javier Roque viernes, 24 de febrero de 2017 20:15
    viernes, 24 de febrero de 2017 19:41

Todas las respuestas

  • Javier Rocco,

    La tabla que muestras -donde se encuentran los datos- ¿es de base de datos? o ¿de una grilla de datos como por ejemplo un objeto de tipo DataGridView?


    Espero que la información proporcionada te haya sido de utilidad, quedo atento a tus comentarios.
    miércoles, 22 de febrero de 2017 17:04
  • Correcto es una tabla de ebase de Datos; y es de un DataGridView
    miércoles, 22 de febrero de 2017 17:08
  • Javier Rocco,

    - Si deseas obtener la sumatoria desde una tabla de base de datos:

    SELECT
        SUM(CASE WHEN Tipo = 'Egreso' THEN Precio * -1 ELSE Precio END)
    FROM
        NombreTabla;
    GO

    Label1.Text = cmd.ExecuteScalar().ToString()

    - Si los datos se encuentran en un objeto de tipo DataGridView (si están vinculados puedes obtener la sumatoria desde el origen)

    Label1.Text = DataGridView1.Rows.Cast(Of DataGridViewRow).
                        Sum(Function(x) Convert.ToDecimal(x.Cells("Precio").Value) *
                        IIf(x.Cells("Tipo").Value.ToString() = "Egreso", -1, 1)).ToString()


    Espero que la información proporcionada te haya sido de utilidad, quedo atento a tus comentarios.
    miércoles, 22 de febrero de 2017 17:18
  • Hola Javier Rocco,

    [-] ... Lo que deseo es obtener en un label el total de Ingreso y el Total de Egresos

    Otra forma a la propuesta anteriormente, es agrupando las filas y obtener las sumas.

    Dim data = DataGridView1.Rows.OfType(Of DataGridViewRow).
                        GroupBy(Function(x) x.Cells("Tipo").Value).
                        Select(Function(x) New With {
                            Key .Tipo = x.Key,
                            Key .Suma = x.Sum(Function(y) CDbl(y.Cells("Precio").Value))
                        }).ToList()
    
    
    lblTotalIngresos.Text = CStr(data.Single(Function(x) x.Tipo.Equals("Ingreso")).Suma)
    lblTotalEgresos.Text = CStr(data.Single(Function(x) x.Tipo.Equals("Egreso")).Suma)

    - Mediante GroupBy agrupas por el Tipo y luego sumas los valores del Precio.

    Según tus datos, te retornaría los siguientes valores :

    Saludos.


    JC NaupaCrispín
    Lima - Perú

    La magia no existe, la programación SI

    • Marcado como respuesta Javier Roque miércoles, 22 de febrero de 2017 18:29
    • Desmarcado como respuesta Javier Roque viernes, 24 de febrero de 2017 19:11
    miércoles, 22 de febrero de 2017 17:38
  • Gracias a ambos por su respuesta. 

    Sr. Joel y si en el datagridV o Tabla de este aun no contiene los ingresos o egreso sea null que de momento no se hayan registrado como validar eso?

    Salio Error cuando borre un egreso que puse de ejemplo: en la parte del label egreso

    lblTotalIngresos.Text = CStr(data.Single(Function(x) x.Tipo.Equals("Ingreso")).Suma)
    lblTotalEgresos.Text = CStr(data.Single(Function(x) x.Tipo.Equals("Egreso")).Suma)

    Disculpe espero lo vea.

    • Editado Javier Roque miércoles, 22 de febrero de 2017 21:50
    miércoles, 22 de febrero de 2017 18:29
  • William;

    Gracias por tu respuesta pero eso me da la diferencia del ingreso con el egreso igual puede servirme mucho. Para otro uso.

    miércoles, 22 de febrero de 2017 21:23
  • William;

    Gracias por tu respuesta pero eso me da la diferencia del ingreso con el egreso igual puede servirme mucho. Para otro uso.

    Lo siento, ya veo que no llegué a entender del todo tu requerimiento.

    Si deseas sumar valores de celda debes recorrer las filas y bifurcar la asignación según una condición, por ejemplo algo simple:

    Dim TotalIngresos, TotalEgresos As Decimal
    For Each Fila As DataGridViewRow In DataGridView1.Rows.
    		Cast(Of DataGridViewRow).Where(Function(x) Not x.IsNewRow)
    	Dim Tipo = Convert.ToString(Fila.Cells("Tipo").Value)
    
    	TotalIngresos += IIf(Tipo(0) = "I", Convert.ToDecimal(Fila.Cells("Precio").Value), 0)
    	TotalEgresos += IIf(Tipo(0) = "E", Convert.ToDecimal(Fila.Cells("Precio").Value), 0)
    Next


    Espero que la información proporcionada te haya sido de utilidad, quedo atento a tus comentarios.
    miércoles, 22 de febrero de 2017 22:09
  • Gracias a ambos por su respuesta. 

    Sr. Joel y si en el datagridV o Tabla de este aun no contiene los ingresos o egreso sea null que de momento no se hayan registrado como validar eso?

    Salio Error cuando borre un egreso que puse de ejemplo: en la parte del label egreso

    lblTotalIngresos.Text = CStr(data.Single(Function(x) x.Tipo.Equals("Ingreso")).Suma)
    lblTotalEgresos.Text = CStr(data.Single(Function(x) x.Tipo.Equals("Egreso")).Suma)

    Disculpe espero lo vea.

    Hola Javier Rocco,

    ¿Te refieres a que en la tabla no exista valores ?

    Podrías cambiar por :

            lblTotalIngresos.Text = If(data.Count > 0, CStr(data.Single(Function(x) x.Tipo.Equals("Ingreso")).Suma), "No result")
            lblTotalEgresos.Text = If(data.Count > 1, CStr(data.Single(Function(x) x.Tipo.Equals("Egreso")).Suma), "No result")

    - Si no existe filas con el Tipo 'Ingreso' o 'Egreso' asignará 'No result' al label.

    Saludos.


    JC NaupaCrispín
    Lima - Perú

    La magia no existe, la programación SI

    jueves, 23 de febrero de 2017 20:53
  • Referencia a objeto no establecida como instancia de un objeto.

    Function(x) x.Tipo.Equals("Ingreso")

    Antes salia ahora ya no sale que pasara? He probado ambos codigos que proponen y ambos salen errores del mismo tipo




    viernes, 24 de febrero de 2017 15:03
  • Bueno Williams he colocado tu codigo no sale error pero no pasa nada donde es que ese resultado se va ver? en otro datagrid? lo que deseo es obtener los valores en un label
    viernes, 24 de febrero de 2017 19:31
  • Javier Rocco,

    Asigna el resultado de las variables a las etiquetas

    Dim TotalIngresos, TotalEgresos As Decimal
    For Each Fila As DataGridViewRow In DataGridView1.Rows.
    		Cast(Of DataGridViewRow).Where(Function(x) Not x.IsNewRow)
    	Dim Tipo = Convert.ToString(Fila.Cells("Tipo").Value)
    
    	TotalIngresos += IIf(Tipo(0) = "I", Convert.ToDecimal(Fila.Cells("Precio").Value), 0)
    	TotalEgresos += IIf(Tipo(0) = "E", Convert.ToDecimal(Fila.Cells("Precio").Value), 0)
    Next
    
    lblTotalIngresos.Text = TotalIngresos.ToString("N2")
    lblTotalEgresos.Text = TotalEgresos.ToString("N2")


    Espero que la información proporcionada te haya sido de utilidad, quedo atento a tus comentarios.
    • Marcado como respuesta Javier Roque viernes, 24 de febrero de 2017 20:15
    viernes, 24 de febrero de 2017 19:41
  • Hola Javier Rocco,

    Ha habido alguna modificación en los datos y/o estructura de tu tabla ? Tienes la propiedad AllowUserToAddRows de tu DataGridView en true ? En caso sea correcto es necesario agregar un Where para omitir la selección de ello.

    Dim data = DataGridView1.Rows.OfType(Of DataGridViewRow).
                Where(Function(x) Not x.IsNewRow).
                GroupBy(Function(x) x.Cells("Tipo").Value).

    En caso no sea inspecciona la parte de 'Ver detalle' para saber un poco más de que está produciendo el error, ya que está retornando un valor nulo, por el cual no puede acceder a la propiedad.

    Saludos.


    JC NaupaCrispín
    Lima - Perú

    La magia no existe, la programación SI

    viernes, 24 de febrero de 2017 19:49
  • Esta en false. La estructura  no creo que haya echo algo diferente mi equipo anterior la plca s eme malogro el disco se puso raw se borro todo asi que lo estoy haciendo de nuevo. 
    viernes, 24 de febrero de 2017 20:06
  • Williams:

    Yo tambien los habia asignado solo me falto el tostring pero bueno se ve bien ahora. Muchas gracias.

    viernes, 24 de febrero de 2017 20:14