Error al guardar datos decimales – El código para C#

Aquí tienes el código para C# de la aplicación de ejemplo del artículo Error al guardar datos decimales: El valor del parámetro ‘xxx’ está fuera del intervalo.

Nota:
Si buscabas el código para Visual Basic está en este otro enlace:
Error al guardar datos decimales – El código para Visual Basic.

Cuando lo tenga publicado, te pondré el enlace para descargar la solución de Visual Studio 2017 tanto para VB como para C#.

El código de C#

//-----------------------------------------------------------------------------
//  Ejemplo para el error de asignar a decimal(4,4)                 (07/Dic/18)
//
// (c) Guillermo (elGuille) Som, 2018
//-----------------------------------------------------------------------------

using System;
using System.Data.SqlClient;
using System.Text;
using System.Windows.Forms;

namespace SQL_Error_decimal_cs
{
    public partial class Form1 : Form
    {


        //--------------------------------------------------------------------------
        // Los campos para acceder a la base de datos
        //--------------------------------------------------------------------------

        /// <summary>
        /// El usuario para acceder a la base de datos de SQL Server.<br />
        /// Si es una cadena vacía se usará la seguridad integrada de Windows.
        /// </summary>
        private string userDb = "UsuarioErrDec";

        /// <summary>
        /// El password del usuario que accede a la base de datos de SQL Server
        /// </summary>
        private string passwordDB = "123456";

        /// <summary>
        /// El servidor donde está la base de datos.<br />
        /// Normalmente será .\SQLEXPRESS o (local)
        /// </summary>
        private string serverName = @".\SQLEXPRESS";
        /// <summary>
        /// El nombre de la base de datos de SQL Server
        /// </summary>
        private string databaseName = "ErrorDecimal";

        /// <summary>
        /// Devuelve la cadena de conexión a la base de datos de SQL Server<br />
        /// Si el usuario es una cadena vacía, se usará la seguridad integrada de Windows
        /// </summary>
        private string ConnectionString {
            get {
                var sb = new SqlConnectionStringBuilder();
                sb.DataSource = serverName;
                sb.InitialCatalog = databaseName;
                if (String.IsNullOrWhiteSpace(userDb))
                {
                    sb.IntegratedSecurity = true;
                } else
                {
                    sb.UserID = userDb;
                    sb.Password = passwordDB;
                }
                return sb.ConnectionString;
            }
        }



        //--------------------------------------------------------------------------
        // Añadir un valor a las tablas
        //--------------------------------------------------------------------------
        private (bool hayError, string msg) AñadirMiTabla1(decimal valor)
        {
            var sel = "INSERT INTO MiTabla1 (Decimal_4_4) " +
                      "VALUES (@Decimal_4_4)";

            var retVal = (hayError: false, msg: "");

            var sCon = ConnectionString;

            using (SqlConnection con = new SqlConnection(sCon))
            {
                var cmd = new SqlCommand(sel, con);
                cmd.Parameters.AddWithValue("@Decimal_4_4", valor);

                con.Open();

                try
                {
                    var ret = Convert.ToInt32(cmd.ExecuteNonQuery());

                    retVal.hayError = (ret < 1);
                    retVal.msg = "Todo OK. cmd.ExecuteNonQuery() = " + ret.ToString();
                }
                catch (Exception ex)
                {
                    retVal.msg = ex.Message;
                    retVal.hayError = true;
                }
                con.Close();
            }
            return retVal;
        }

        private (bool hayError, string msg) AñadirMiTabla2(decimal[] valores)
        {
            var sel = "INSERT INTO MiTabla2 (Decimal_6_4, Decimal_18_6) " +
                      "VALUES (@Decimal_6_4, @Decimal_18_6)";

            var retVal = (hayError:false, msg:"");
            
            var sCon = ConnectionString;

            using (SqlConnection con = new SqlConnection(sCon))
            {
                SqlCommand cmd = new SqlCommand(sel, con);
                cmd.Parameters.AddWithValue("@Decimal_6_4", valores[0]);
                cmd.Parameters.AddWithValue("@Decimal_18_6", valores[1]);

                con.Open();

                try
                {
                    var ret = Convert.ToInt32(cmd.ExecuteNonQuery());

                    retVal.hayError = (ret < 1);
                    retVal.msg = "Todo OK. cmd.ExecuteNonQuery() = " + ret.ToString();
                }
                catch (Exception ex)
                {
                    retVal.msg = ex.Message;
                    retVal.hayError = true;
                }
                con.Close();
            }
            return retVal;
        }



        private string leerMiTabla(string tabla)
        {
            var sel = "SELECT * FROM " + tabla;

            var retVal = "";

            var sCon = ConnectionString;

            using (SqlConnection con = new SqlConnection(sCon))
            {
                var cmd = new SqlCommand(sel, con);

                con.Open();

                try
                {
                    var ret = cmd.ExecuteReader();

                    StringBuilder sb = new StringBuilder();

                    while (ret.Read())
                    {
                        sb.AppendLine(String.Format("{0} = {1}", ret.GetName(0), ret[0]));

                        if (ret.FieldCount > 1)
                            sb.AppendLine(String.Format("{0} = {1}", ret.GetName(1), ret[1]));
                    };
                    retVal = sb.ToString();
                }
                catch (Exception ex)
                {
                    retVal = "ERROR: " + ex.Message;
                }
                con.Close();
            };
            return retVal;
        }

        //--------------------------------------------------------------------------
        // Para aceptar la coma como decimal en las cajas numéricas
        //--------------------------------------------------------------------------
        /// <summary>
        /// El separador de decimales para los campos numéricos
        /// </summary>
        const string SeparadorDecimal = ",";

        /// <summary>
        /// Para indicar qué tecla "decimal" no se debe admitir
        /// </summary>
        const string NoSeparadorDecimal = ".";

        /// <summary>
        /// Comprobar si se aceptan las teclas en una caja de texto.
        /// En la pulsación de los controles numéricos
        /// aceptar solo los caracteres numéricos,
        /// el valor negativo, el separador de decimales
        /// y las teclas Intro, Delete, Back (borrar hacia atrás)
        ///
        /// Es raro, si teclasAceptadas es: ",-1234567890" también acepta el punto
        /// </summary>
        private char AceptarTeclas(KeyPressEventArgs e, string teclasAceptadas)
        {
            char c = e.KeyChar;

            if (c == Convert.ToChar(Keys.Return))
            {
                // con esto hacemos que se ignore la pulsación
                e.Handled = true;
                // se manda al siguiente control
                SendKeys.Send("{TAB}");
            }
            else if (c == Convert.ToChar(NoSeparadorDecimal))
            {
                e.KeyChar = Convert.ToChar(SeparadorDecimal);
            }
            else if (teclasAceptadas.Contains(c.ToString()))
            {
                // no hacer nada, se aceptan
            }
            else if (c == Convert.ToChar(Keys.Delete) || c == Convert.ToChar(Keys.Back))
            {
                // no hacer nada, se aceptan
            }
            else
            {
                e.Handled = true;
            }
            return c;
        }



        //--------------------------------------------------------------------------
        // Los métodos de evento del formulario
        //--------------------------------------------------------------------------

        private void btnCerrar_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void btnAsignarTabla1_Click(object sender, EventArgs e)
        {
            var d = 0M;
            Decimal.TryParse(txtTabla1_campo1.Text, out d);
            var ret = AñadirMiTabla1(d);

            txtMensaje1.Text = "";
            if (ret.hayError)
                txtMensaje1.Text = "ERROR\r\n";
            txtMensaje1.Text += ret.msg;
        }

        private void btnAsignarTabla2_Click(object sender, EventArgs e)
        {
            var valores = new decimal[12];
            var d = 0M;

            Decimal.TryParse(txtTabla2_campo1.Text, out d);
            valores[0] = d;

            d = 0M;
            Decimal.TryParse(txtTabla2_campo2.Text, out d);
            valores[1] = d;

            var ret = AñadirMiTabla2(valores);

            txtMensaje2.Text = "";
            if (ret.hayError)
                txtMensaje2.Text = "ERROR\r\n";
            txtMensaje2.Text += ret.msg;
        }

        private void btnMostrar1_Click(object sender, EventArgs e)
        {
            // mostrar los datos de MiTabla1
            txtMensaje1.Text = leerMiTabla("MiTabla1");
        }

        private void btnMostrar2_Click(object sender, EventArgs e)
        {
            // mostrar los datos de MiTabla2
            txtMensaje2.Text = leerMiTabla("MiTabla2");
        }

        private void txt_KeyPress(object sender, KeyPressEventArgs e)
        {
            AceptarTeclas(e, SeparadorDecimal + "-1234567890");
        }

        public Form1()
        {
            InitializeComponent();
        }

<

        private void Form1_KeyDown(object sender, KeyEventArgs e)
        {
            // detecta la pulsación de las teclas en el formulario
            // antes de mandarla a los controles
            // En el diseñador de formularios tienes que
            // asignar un valor True a la propiedad KeyPreview

            if (e.Modifiers == Keys.Control)
            {


                if (e.KeyCode == Keys.C)
                {
                    // copiar el texto
                    if (ActiveControl is TextBox)
                    {
                        //Dim texto = ActiveControl.Text
                        //Clipboard.SetText(texto)
                        var txt = ActiveControl as TextBox;
                        if (txt == null) return;
                        txt.Copy();

                        e.Handled = true;
                    }
                }
                else if (e.KeyCode == Keys.V)
                {
                    // pegar el texto
                    if (ActiveControl is TextBox)
                    {
                        var txt = ActiveControl as TextBox;
                        if (txt == null) return;
                        txt.Paste();

                        e.Handled = true;
                    }
                }
                else if (e.KeyCode == Keys.X)
                {
                    // cortar el texto
                    if (ActiveControl is TextBox)
                    {
                        var txt = ActiveControl as TextBox;
                        if (txt == null) return;
                        txt.Cut();

                        e.Handled = true;
                    }
                }
                else if (e.KeyCode == Keys.Z)
                {
                    //deshacer
                    if (ActiveControl is TextBox)
                    {
                        var txt = ActiveControl as TextBox;
                        if (txt == null) return;
                        if (txt.CanUndo)
                        {
                            txt.Undo();
                        }
                        e.Handled = true;
                    }
                }
            }
        }
    }
}

Espero que te sea de utilidad.

Nos vemos
Guillermo

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.