none
Error con el evento CellLeave al seleccionar otra celda RRS feed

  • Pregunta

  • Buenas tardes a todos, necesito de su ayuda... Tengo un Formulario llamado Factura, dentro un DatagridView llamado DGV_Factura, donde al ingresar datos como Cantidad, Descuento y Monto, éste me arroja un error. Éste es el código a utilizar:

    private void DGV_Factura_CellLeave(object sender, DataGridViewCellEventArgs e)
            {
                int rows = DGV_Factura.Rows.Count - 1, cantidad;
                double precio, descuento, monto, iva, suma_monto = 0, total;

                if (RBSi.Checked == true)
                {
                    for (int x = 0; x < rows; x++)
                    {
                        precio = (double)DGV_Factura.Rows[x].Cells[3].Value;
                        cantidad = (DGV_Factura.Rows[x].Cells[4].Value != null) ? int.Parse(DGV_Factura.Rows[x].Cells[4].Value.ToString()) : 0;
                        descuento = (DGV_Factura.Rows[x].Cells[5].Value != null) ? double.Parse(DGV_Factura.Rows[x].Cells[5].Value.ToString()) : 0;
                        monto = precio * cantidad - descuento;
                        DGV_Factura.Rows[x].Cells[6].Value = monto;
                        suma_monto += monto;
                    }
                    iva = suma_monto * 0.15;
                    total = suma_monto + iva;

                    TXT_Iva.Text = iva.ToString();
                    TXT_Total.Text = total.ToString();
                    txtFacturado.Text = total.ToString();
                }
                else if (RBNo.Checked == true)
                {
                    for (int x = 0; x < rows; x++)
                    {
                        precio = (double)DGV_Factura.Rows[x].Cells[3].Value;
                        cantidad = (DGV_Factura.Rows[x].Cells[4].Value != null) ? int.Parse(DGV_Factura.Rows[x].Cells[4].Value.ToString()) : 0;
                        descuento = (DGV_Factura.Rows[x].Cells[5].Value != null) ? double.Parse(DGV_Factura.Rows[x].Cells[5].Value.ToString()) : 0;
                        monto = precio * cantidad - descuento;
                        DGV_Factura.Rows[x].Cells[6].Value = monto;
                        suma_monto += monto;
                    }
                    iva = 0;
                    total = suma_monto + iva;

                    TXT_Iva.Text = iva.ToString();
                    TXT_Total.Text = total.ToString();
                    txtFacturado.Text = total.ToString();
                }
            }

    Dónde me equivoco?????

    OJO: En el DGV_Factura ya tengo cargado Producto y Precio proveniente de otro DataGridView llamado dgv_Producto.

    Mil gracias

    viernes, 27 de diciembre de 2019 23:47

Respuestas

  • Hola Ramiro

    Estoy tratando de entender el código de a poco ... te cuento, los índices comienzan en 0, porque me parece que pensaste que la columna Precio era el 3

    La cantidad de filas es dgv.Rows.Count sin restarle 1

    Por qué todo ese código en el método del evento CellLeave? Me parece que tendrías que hacer todo eso con un botón "Terminar" o algo así, y que te permita llenar las celdas libremente, y al finalizar compruebe si hay errores y haga las sumas

    La causa por la que te salta NullReferenceException es porque intentas leer un double de la columna Cantidad (índice 3) y allí no hay nada


    sábado, 28 de diciembre de 2019 2:06
  • hola

    Debes asegurarte que la celda tiene un valor

    double precio = (row.Cells[3].Value != null) ? double.Parse(row.Cells[3].Value.ToString()) : 0;

    al acceder a las otras celdas los validas, no veo porque en esta no lo realizas

    Igualmente un detalle, no definas las variables de forma global si el calculo va a ser local en el for

    foreach (var row in DGV_Factura.Rows)
    {
    	
    	double precio = (row.Cells[3].Value != null) ? double.Parse(row.Cells[3].Value.ToString()) : 0;
    	double cantidad = (row.Cells[4].Value != null) ? int.Parse(row.Cells[4].Value.ToString()) : 0;
    	double descuento = (row.Cells[5].Value != null) ? double.Parse(row.Cells[5].Value.ToString()) : 0;
    	double monto = precio * cantidad - descuento;
    	
    	row.Cells[6].Value = monto;
    	
    	suma_monto += monto;
    }

    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    lunes, 30 de diciembre de 2019 14:15
  • Me parece perfecto tu respuesta, lo hice como tú dices. Con el evento CellLeave todo bien, pero vero deficiencia al estar cambiado el foco de posicionamiento y si lo hago desde el evento CellEndEdit que sería el adecuado a mi parecer, éste no me hace las operaciones que necesito, porque los datos del datagridview son devueltos por medio de otro datagridview2 y no son insertados de forma manual. Entonces que evento me aconsejas que use? Muchas gracias hemano.... Feliz año nuevo!!! 
    martes, 31 de diciembre de 2019 22:43

Todas las respuestas

  • Hola Ramiro

    Estoy tratando de entender el código de a poco ... te cuento, los índices comienzan en 0, porque me parece que pensaste que la columna Precio era el 3

    La cantidad de filas es dgv.Rows.Count sin restarle 1

    Por qué todo ese código en el método del evento CellLeave? Me parece que tendrías que hacer todo eso con un botón "Terminar" o algo así, y que te permita llenar las celdas libremente, y al finalizar compruebe si hay errores y haga las sumas

    La causa por la que te salta NullReferenceException es porque intentas leer un double de la columna Cantidad (índice 3) y allí no hay nada


    sábado, 28 de diciembre de 2019 2:06
  • hola

    Debes asegurarte que la celda tiene un valor

    double precio = (row.Cells[3].Value != null) ? double.Parse(row.Cells[3].Value.ToString()) : 0;

    al acceder a las otras celdas los validas, no veo porque en esta no lo realizas

    Igualmente un detalle, no definas las variables de forma global si el calculo va a ser local en el for

    foreach (var row in DGV_Factura.Rows)
    {
    	
    	double precio = (row.Cells[3].Value != null) ? double.Parse(row.Cells[3].Value.ToString()) : 0;
    	double cantidad = (row.Cells[4].Value != null) ? int.Parse(row.Cells[4].Value.ToString()) : 0;
    	double descuento = (row.Cells[5].Value != null) ? double.Parse(row.Cells[5].Value.ToString()) : 0;
    	double monto = precio * cantidad - descuento;
    	
    	row.Cells[6].Value = monto;
    	
    	suma_monto += monto;
    }

    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    lunes, 30 de diciembre de 2019 14:15
  • Me parece perfecto tu respuesta, lo hice como tú dices. Con el evento CellLeave todo bien, pero vero deficiencia al estar cambiado el foco de posicionamiento y si lo hago desde el evento CellEndEdit que sería el adecuado a mi parecer, éste no me hace las operaciones que necesito, porque los datos del datagridview son devueltos por medio de otro datagridview2 y no son insertados de forma manual. Entonces que evento me aconsejas que use? Muchas gracias hemano.... Feliz año nuevo!!! 
    martes, 31 de diciembre de 2019 22:43
  • Hola

    El Evento CellLeave se da cuando cambias de celda, o "dejas la celda" (leave the cell). Si hay ya escritos datos que provienen de otro DataGridView, y además vos tenes que llenar otras celdas, lo que a mi me parece es que tendrías que realizar todas las sumas y eso, cuando terminas de llenar la última celda, y que un Button "Terminar" sería lo más apropidado. Porque el evento CellLeave se aplica a cuando "dejas" cualquier celda, y si faltan llenar celdas y haces los cálculos te van a saltar errores por celdas vacías, además de hacer trabajar al CPU decenas de veces sin necesidad.

    Feliz año nuevo!

    miércoles, 1 de enero de 2020 21:55