none
Formato en datagridview RRS feed

  • Pregunta

  • Buenos dias

    Es mi primera pregunta en el foro, he estudiado y aprendido mucho de esta comunidad pero tengo una duda que no se como solventar

    El problema que me surge es que necesito que me cambie el formato de una fila de un datagridview comparando dos columnas, si hay suficiente material, quiero que le cambie el formato de la fila

    tengo este codigo pero no lo hace bien, hay veces que lo marca y otras no, se puede ver un msgbox (comentado) que me indica los valores y a pesar de ser verdadero, no me cambia todas las filas, solo algunas

    Tambien lo he intentado con un foreach (que esta comentado) pero el resultado es el mismo

     Dim unidades, stock As String
    
            'For Each r As DataGridViewRow In dgwLineas.Rows
    
            For r = 0 To dgwLineas.Rows.Count - 1
                With dgwLineas
                    stock = .Item("STOCK", r).Value.ToString
                    If stock = "" Then
                        stock = 0
                    Else
                        stock = CType(.Item("STOCK", r).Value.ToString, Double)
                    End If
    
    
                    unidades = CType(.Item("PEDIDAS", r).Value.ToString, Double)
                    'MsgBox(unidades & " - " & stock)
    
                    If unidades < stock Then
    
                        .Rows(r).DefaultCellStyle.Font = New Font("Microsoft Sans Serif", 12, FontStyle.Bold)
    
                    End If
                End With
    
            Next

    Espero puedan ayudarme, desde ya, muchas gracias!

    martes, 5 de noviembre de 2019 11:23

Respuestas

  • Hola Israle, bueno en un principio si como comentas has "Ajustado el código..()" y eso supone que has convertido y comparado en String los valores, por los posibles valores nullos, creo que allí radica el error, no se compara un valor en string el valor no es lo mismo, siguiento tu lógica con tu código efectúa lo siguiente

     Private Sub ejec()
            Dim unidades, stock As Integer
            For r = 0 To DGV1.Rows.Count - 2
                With DGV1
                    If IsDBNull(.Item("B", r).Value) Then
                        .Item("B", r).Value = 0
                        unidades = 0
                    Else
                        unidades = Convert.ToInt32(.Item("B", r).Value)
                    End If

                    If IsDBNull(.Item("C", r).Value) Then
                        .Item("C", r).Value = 0
                        stock = 0
                    Else
                        stock = Convert.ToInt32(.Item("C", r).Value)
                    End If

                    If stock < unidades Then

                        .Rows(r).DefaultCellStyle.Font = New System.Drawing.Font("Microsoft Sans Serif", 12, FontStyle.Bold)
                        .Rows(r).DefaultCellStyle.BackColor = Color.LightSalmon
                    Else
                        .Rows(r).DefaultCellStyle.BackColor = Color.LightGreen
                    End If
                End With
            Next
        End Sub

    Este códgio compara valores  en Integer y si el valor de stock es menor al pedido lo marca color con el font si es igual o mayor le da color verde

    Fijate que si utilizas de esta manera (integer) los códigos expuestos anteriormente funcionarán adecuadamente .

    Saludos y a disposición


    ARA San Juan 44 HEROES     ‗‗‗‗­|||||‗‗‗‗‗


    • Editado Marcelo PF viernes, 8 de noviembre de 2019 12:47
    • Marcado como respuesta Israel Gómez viernes, 8 de noviembre de 2019 15:22
    viernes, 8 de noviembre de 2019 12:29

Todas las respuestas

  • Buenos dias de nuevo

    Haciendolo con for each es algo asi

            Dim unidades, stock As String
    
            For Each r As DataGridViewRow In dgwLineas.Rows
    
                'For r = 0 To dgwLineas.Rows.Count - 1
                'With dgwLineas
                stock = r.Cells("STOCK").Value.ToString
                If stock = "" Then
                        stock = 0
                    Else
                    stock = CType(r.Cells("STOCK").Value.ToString, Double)
                End If
    
    
                unidades = CType(r.Cells("PEDIDAS").Value.ToString, Double)
                'MsgBox(unidades & " - " & stock)
    
                If unidades < stock Then
    
                    r.DefaultCellStyle.Font = New Font("Microsoft Sans Serif", 12, FontStyle.Bold)
    
                End If
    
    
            Next

    el resultado es el mismo, no marca todo bien

    Gracias de nuevo


    martes, 5 de noviembre de 2019 11:41
  • Recorre la Grilla con For Each
    For Each fila As DataGridViewRow In dgvLineas.Rows
                If fila.Cells("Total").Value = 0 Then
                    fila.DefaultCellStyle.Font = New Font("Microsoft Sans Serif", 12 Fontstyle.Bold)
                
                End If
            Next
    • Propuesto como respuesta Pablo Rubio miércoles, 6 de noviembre de 2019 22:17
    martes, 5 de noviembre de 2019 18:41
  • Lo que quiero es que compare dos columnas de grid PEDIDAS y STOCK y y le cambie el formato en caso de que el STOCK sea mayor Saludos
    martes, 5 de noviembre de 2019 21:27
  • Hola Israel, prueba de esta manera, según cargues el DGV (en el ejemplo compara columna 2 y 3 (3, 4) y conpuesto con 8 columnas de (0 a 7))

    si cargas desde base de datos en el evento CellFormatting

       Private Sub DGV1_CellFormatting(sender As Object, e As DataGridViewCellFormattingEventArgs) Handles DGV1.CellFormatting
            Dim C As Integer = e.ColumnIndex
            Dim R As Integer = e.RowIndex
            If C = 7 And Not R = DGV1.Rows.Count - 1 Then
                If DGV1(3, R).Value = DGV1(2, R).Value Then
                    DGV1.Rows(R).DefaultCellStyle.Font = New Font("Microsoft Sans Serif", 12, FontStyle.Bold)
                    DGV1.Rows(R).DefaultCellStyle.BackColor = Color.Aqua
                End If
            End If
    
        End Sub

    En caso que la carga fuese en Manual en el evento CellEndEdit

      Private Sub DGV1_CellEndEdit(sender As Object, e As DataGridViewCellEventArgs) Handles DGV1.CellEndEdit
            Dim C As Integer = e.ColumnIndex
            Dim R As Integer = e.RowIndex
            If C = 3 And Not R = DGV1.Rows.Count - 1 Then
                If DGV1(3, R).Value = DGV1(2, R).Value Then
                    DGV1.Rows(R).DefaultCellStyle.Font = New Font("Microsoft Sans Serif", 12, FontStyle.Bold)
                    DGV1.Rows(R).DefaultCellStyle.BackColor = Color.Aqua
                End If
            End If
    
        End Sub

    Y en caso de que sea mediante un buton (For Each)

        Private Sub Button6_Click(sender As Object, e As EventArgs) Handles Button6.Click
    
            For Each Dr As DataGridViewRow In DGV1.Rows
                If Dr.Cells(2).Value = Dr.Cells(3).Value And Not Dr.IsNewRow Then
                    Dr.DefaultCellStyle.Font = New Font("Microsoft Sans Serif", 12, FontStyle.Bold)
                    Dr.DefaultCellStyle.BackColor = Color.Aqua
                End If
            Next
    
    
        End Sub
    Espero te sirva saludos


    ARA San Juan 44 HEROES     ‗‗‗‗­|||||‗‗‗‗‗


    • Editado Marcelo PF miércoles, 6 de noviembre de 2019 15:38
    • Propuesto como respuesta Pablo Rubio miércoles, 6 de noviembre de 2019 22:17
    • Marcado como respuesta Israel Gómez jueves, 7 de noviembre de 2019 8:03
    • Desmarcado como respuesta Israel Gómez jueves, 7 de noviembre de 2019 8:16
    miércoles, 6 de noviembre de 2019 14:44
  • Gracias por la respuesta, ahora no lo puedo probar pero mañana lo pruebo y te digo que tal, tiene buena pinta Gracias por la ayuda!!
    • Propuesto como respuesta Pablo Rubio miércoles, 6 de noviembre de 2019 22:18
    miércoles, 6 de noviembre de 2019 18:47
  • Buenos dias Marcelo

    He porbado los códigos que indicas pero el resultado no ha sido del todo correcto, quiza es porque la explicacion que he dado no es la correcta del todo

    Los datos del grid se cargan cunando se realiza el evento rowenter de otro datagridview, es decir, la cabecera de en este caso un pedido (con los datos del pedido) y al hacer el evento rellena las lineas del grid con el contenido.

    Tras rellenar las filas, quisiera que marcase las lineas que tienen disponibilidad (el codigo indicado esta dentro del evento rowenter.

    Dim unidades, stock As String
    
            For r = 0 To dgwLineas.Rows.Count - 1
                With dgwLineas
                    stock = .Item("STOCK", r).Value.ToString
                    If stock = "" Then
                        stock = 0
                    Else
                        stock = CType(.Item("STOCK", r).Value.ToString, Double)
                    End If
    
    
                    unidades = CType(.Item("PEDIDAS", r).Value.ToString, Double)
                  
    
                    If unidades < stock Then
    
                        .Rows(r).DefaultCellStyle.Font = New Font("Microsoft Sans Serif", 12, FontStyle.Bold)
    
                    End If
                End With
    
            Next
    

    Este codigo lo hace pero no siempre, a veces no lo hace

     Private Sub DGV1_CellEndEdit(sender As Object, e As DataGridViewCellEventArgs) Handles DGV1.CellEndEdit
            Dim C As Integer = e.ColumnIndex
            Dim R As Integer = e.RowIndex
            If C = 3 And Not R = DGV1.Rows.Count - 1 Then
                If DGV1(3, R).Value = DGV1(2, R).Value Then
                    DGV1.Rows(R).DefaultCellStyle.Font = New Font("Microsoft Sans Serif", 12, FontStyle.Bold)
                    DGV1.Rows(R).DefaultCellStyle.BackColor = Color.Aqua
                End If
            End If
    
        End Sub

    Ajustando este codigo para el formato, tambien lo hace pero falla en algunas lineas no las marca todas

    en la imagen se aprecia lo que marca mi codigo y lo que marca el propuesto (pintado de azul) y no coinciden.

    No se como hacerlo :(

    jueves, 7 de noviembre de 2019 8:39
  • Bueno tal cual indicas nos falta más información, puede ser la causa que ejecutes el código con el evento Enter, este de por sí trae algunos problemas ya que salta al siguiente rown de donde lo ejecutes. Pero tendríamos que tener todo el código y más explicación como para ver que sucede ya que, si terminas de llenar el DGV2 y aplicas el código en un button o en una función debería actuar igual. En definitiva si puede agrega más información y se resolverá

    Saludos


    ARA San Juan 44 HEROES     ‗‗‗‗­|||||‗‗‗‗‗

    jueves, 7 de noviembre de 2019 15:12
  • Hola Marcelo

    Ok, te explico un poco mas, creía que seria suficiente.

    Tengo dos grids, les llamaremos cabecera y lineas, la cabecera se carga mediante un boton, despues por el evento rowenter de la cabecera, aplica un metodo que se encarga  de cargar las lineas correspondientes, despues de cargarlas debe indicar que lineas tienen suficiente stock. El codigo del evento es el siguiente

        Private Sub dgwCabecera_RowEnter(sender As Object, e As DataGridViewCellEventArgs) Handles dgwCabecera.RowEnter
         
    
            Try
                idpedv = dgwCabecera.Item(6, e.RowIndex).Value.ToString
    
            Catch ex As Exception
    
            End Try
            LineasPV(idpedv, dgwLineas)
    
            Dim unidades, stock As String
    
            For r = 0 To dgwLineas.Rows.Count-1
                With dgwLineas
                    stock = .Item("STOCK", r).Value.ToString
                    If stock = "" Then
                        stock = 0
                    Else
                        stock = CType(.Item("STOCK", r).Value.ToString, Double)
                    End If
    
                    unidades = CType(.Item("PEDIDAS", r).Value.ToString, Double)
    
                    If unidades <= stock Then
    
                        .Rows(r).DefaultCellStyle.Font = New Font("Microsoft Sans Serif", 12, FontStyle.Bold)
    
                    End If
                End With
    
            Next
    
    
        End Sub
    Saludos

    viernes, 8 de noviembre de 2019 8:14
  • Hola Israle, bueno en un principio si como comentas has "Ajustado el código..()" y eso supone que has convertido y comparado en String los valores, por los posibles valores nullos, creo que allí radica el error, no se compara un valor en string el valor no es lo mismo, siguiento tu lógica con tu código efectúa lo siguiente

     Private Sub ejec()
            Dim unidades, stock As Integer
            For r = 0 To DGV1.Rows.Count - 2
                With DGV1
                    If IsDBNull(.Item("B", r).Value) Then
                        .Item("B", r).Value = 0
                        unidades = 0
                    Else
                        unidades = Convert.ToInt32(.Item("B", r).Value)
                    End If

                    If IsDBNull(.Item("C", r).Value) Then
                        .Item("C", r).Value = 0
                        stock = 0
                    Else
                        stock = Convert.ToInt32(.Item("C", r).Value)
                    End If

                    If stock < unidades Then

                        .Rows(r).DefaultCellStyle.Font = New System.Drawing.Font("Microsoft Sans Serif", 12, FontStyle.Bold)
                        .Rows(r).DefaultCellStyle.BackColor = Color.LightSalmon
                    Else
                        .Rows(r).DefaultCellStyle.BackColor = Color.LightGreen
                    End If
                End With
            Next
        End Sub

    Este códgio compara valores  en Integer y si el valor de stock es menor al pedido lo marca color con el font si es igual o mayor le da color verde

    Fijate que si utilizas de esta manera (integer) los códigos expuestos anteriormente funcionarán adecuadamente .

    Saludos y a disposición


    ARA San Juan 44 HEROES     ‗‗‗‗­|||||‗‗‗‗‗


    • Editado Marcelo PF viernes, 8 de noviembre de 2019 12:47
    • Marcado como respuesta Israel Gómez viernes, 8 de noviembre de 2019 15:22
    viernes, 8 de noviembre de 2019 12:29
  • Buenas tardes Correcto, mi código no está bien, pero hay una razón. Las variables son tipo String porque en alguna ocasión puede recibir decimales provocando error.. Mi fallo está en que convierto a doble el mismo String por lo que no hago lo que hay que hacer y no trata valores numéricos y entonces marca algunas dependiendo del número pero como String. Mil gracias. Lo pruebo en breve y te digo!!!👏👏👏👏
    viernes, 8 de noviembre de 2019 13:33
  • Ves?, ves? Siemrpe falta información je. Bueno en caso de que traiga decimales puedes cambiar las variables a Double tanto Unidades como Stock y también así el valor de las celdas (Convert.ToDouble("Stock",r).Value) Las comparaciones deberían ser entre tipos iguales.


    ARA San Juan 44 HEROES     ‗‗‗‗­|||||‗‗‗‗‗

    viernes, 8 de noviembre de 2019 15:21
  • Bingo!!!!! mil gracias

    Perfecto, asi es he ajustado los codigos para que funcionen en mi programa y funcionan de las dos maneras. te paso los resultados finales que estan de categoria.

    Por insistencia en mi forma de programar

     Dim stock As String
            Dim uni, st As Double
            For r = 0 To dgwLineas.Rows.Count-1
                With dgwLineas
                    stock = .Item("STOCK", r).Value.ToString
                    If stock = "" Then
                        st = 0
                    Else
                        st = CType(.Item("STOCK", r).Value.ToString, Double)
                    End If
    
                    uni = CType(.Item("PEDIDAS", r).Value.ToString, Double)
    
                    If uni <= st Then
    
                        .Rows(r).DefaultCellStyle.Font = New Font("Microsoft Sans Serif", 12, FontStyle.Bold)
    
                    End If
                End With
    
            Next

    Cambia el formato

        Private Sub ejec()
            Dim unidades, stock As Double
            For r = 0 To dgwLineas.Rows.Count - 1
                With dgwLineas
                    If IsDBNull(.Item("PEDIDAS", r).Value) Then
                        .Item("PEDIDAS", r).Value = 0
                        unidades = 0
                    Else
                        unidades = Convert.ToDouble(.Item("PEDIDAS", r).Value)
                    End If
    
                    If IsDBNull(.Item("STOCK", r).Value) Then
                        .Item("STOCK", r).Value = 0
                        stock = 0
                    Else
                        stock = Convert.ToDouble(.Item("STOCK", r).Value)
                    End If
    
                    If stock < unidades Then
    
                        .Rows(r).DefaultCellStyle.Font = New System.Drawing.Font("Microsoft Sans Serif", 12, FontStyle.Bold)
                        .Rows(r).DefaultCellStyle.BackColor = Color.LightSalmon
                    Else
                        .Rows(r).DefaultCellStyle.BackColor = Color.LightGreen
                    End If
                End With
            Next
        End Sub

    Tu codigo retocado para que me funcione a mi :) que me gusta la idea de colorear todas las filas, el efecto visual es mejor

    Muchas gracias, con gente asi da gusto trabajar!

    viernes, 8 de noviembre de 2019 15:26
  • Te comparto una sugerencia, ya que la desarrolle en mi escenario, que tál si colocas un color amarillo en caso de que sean iguales los valores? dado en la practica si el Stock es igual el pedido daría una alarma de que ese Stock esta fuera de "Stock Minimo" para el caso, si lo deseas solo agrega un ElseIf a las condiciones ej:

       
    '---------()
      If stock < unidades Then
    
                        .Rows(r).DefaultCellStyle.Font = New System.Drawing.Font("Microsoft Sans Serif", 12, FontStyle.Bold)
                        .Rows(r).DefaultCellStyle.BackColor = Color.LightSalmon
    
                    ElseIf stock = unidades Then
    
                        .Rows(r).DefaultCellStyle.BackColor = Color.LightYellow
                    Else
    
                        .Rows(r).DefaultCellStyle.BackColor = Color.LightGreen
                    End If
                End With
    
    '-----------()


    ARA San Juan 44 HEROES     ‗‗‗‗­|||||‗‗‗‗‗

    viernes, 8 de noviembre de 2019 15:55
  • OK, Gracias, si ya juego con ello..... voy probando y voy haciendo

    Hasta la proxima!

    Saludos

    viernes, 8 de noviembre de 2019 16:34