none
Problemas con campos decimales entre visual studio y sql RRS feed

  • Pregunta

  • Hola a todos. Trabajo en Visual Studio 2010 y SQL SERVER 2014.

    Mi problema es el siguiente: Dentro de un formulario de mi proyecto tengo un datagridview, el cual relleno con una tabla a través de una sentencia sql. Los campos que recogo de la tabla son de tipo decimal (18,2).  Cuando se muestran los datos en el datagridview aparece la separación de decimal con una "," . Aquí os pongo una imagen con lo dicho.

    Cuando modifico uno de los campos he introduzco el valor "25.50" por ejemplo, en algunos de los campos, se convierte en el valor 2550 quitándose el valor decimal y no es el valor que quiero guardar en el campo.

    Si introduzco el valor "25,50" me sale error a la hora de grabar diciéndome "Hay menos columnas en la instrucción INSERT que valores en la claúsula VALUES. El número de valores de VALUES debe coincidir con el de columnas de INSERT" ya que la separación entre los valores es una "," y por ello tendría más valores a introducir ya que reconoce la coma como separación de valores.

    ¿Cómo podría solucionar esto? . No se si me he explicado bien o no.

    Gracias de antemano.


    Saluditos, Charo

    miércoles, 3 de agosto de 2016 10:21

Respuestas

  • "charoeci1" preguntó:

    > ¿Qué evento puedo utilizar para poder cambiar cuando pulso la tecla "."  por la tecla ","
    > a la hora de escribir en algunos de los campos que quiero modificar y que son decimales?
    > Así si escribo el valor "5.4" que se convierta en "5,4" y creo que ya no tendría ningún
    > problema a la hora de guardar los datos.

    Hola, Charo:

    Tienes que detectar el evento KeyPress del control DataGridViewTextBoxEditingControl subyacente existente en la celda del control DataGridView que contiene los valores decimales donde deseas cambiar el punto decimal (.) por la coma decimal (,).

    Pero para que tu aplicación se adapte a la configuración regional que actualmente tenga establecida el usuario en su sistema operativo, tienes que detectar qué carácter tiene como separador de decimales (normalmente una coma en una configuración regional de español de España) y como separador de miles (normalmente el punto decimal en la misma configuración regional anterior).

    Inserta el siguiente código en el formulario que contiene el control DataGridView:

    Imports System.Globalization
    Imports System.Threading.Thread
    
    Public Class Form1
    
        Private m_decimalSeparator As Char
        Private m_groupSeparator As Char
    
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    
            ' Formato de números correspondiente a la configuración regional actual.
            Dim numberFormatInfo As NumberFormatInfo = CurrentThread.CurrentUICulture.NumberFormat
    
            ' Carácter separador decimal 
            m_decimalSeparator = numberFormatInfo.NumberDecimalSeparator.Chars(0)
    
            ' Carácter separador de grupos de digitos 
            m_groupSeparator = numberFormatInfo.NumberGroupSeparator.Chars(0)
    
        End Sub
    
        Private Sub DataGridView1_EditingControlShowing(sender As Object, e As DataGridViewEditingControlShowingEventArgs) Handles DataGridView1.EditingControlShowing
    
            ' Este evento se producirá cuando la celda pasa a modo de edición.
            '
            Static cellTextBox As DataGridViewTextBoxEditingControl
            Dim valorValido As Boolean = (Not cellTextBox Is Nothing)
    
            ' Referenciamos la celda actual.
            Dim currentCell As DataGridViewCell = DataGridView1.CurrentCell
    
            If (currentCell.ColumnIndex <> 2) Then
    
                ' El índice de la columna de la celda actual no se corresponde con el
                ' índice de la tercera columna del control DataGridView, que es la que
                ' contiene las celdas donde deseamos obtener el carácter separador
                ' decimal tecleado por el usuario.
                '
                If (valorValido) Then
                    ' Primero eliminar el controlador para el evento KeyPress siempre
                    ' y cuando el valor de la variable estática 'cellTextBox' no sea
                    ' Nothing.
                    RemoveHandler cellTextBox.KeyPress, AddressOf CellTextBoxOnKeyPress
                End If
    
                ' Después, establecer el valor Nothing a la variable estática del tipo
                ' DataGridViewTextBoxEditingControl solamente si la celda actual no se
                ' corresponde con el índice de la tercera columna, porque de no hacerlo,
                ' se desencadenaría también el evento KeyPress para aquellas otras celdas
                ' del tipo DataGridViewTextBoxColumn diferentes a aquellas donde deseamos
                ' obtener el carácter separador decimal tecleado.
                '
                cellTextBox = Nothing
    
            ElseIf (Not valorValido) Then
                ' Referenciamos el control DataGridViewTextBoxEditingControl subyacente
                ' siempre y cuando su valor sea Nothing. Si la celda actual no es del tipo
                ' DataGridViewTextBoxEditingControl, el valor de la variable 'cellTextBox'
                ' será Nothing.
                '
                cellTextBox = TryCast(e.Control, DataGridViewTextBoxEditingControl)
                AddHandler cellTextBox.KeyPress, AddressOf CellTextBoxOnKeyPress
    
            End If
    
        End Sub
    
        Private Sub CellTextBoxOnKeyPress(sender As Object, e As KeyPressEventArgs)
    
            If (e.KeyChar = m_groupSeparator) Then
                ' Se ha pulsado el carácter correspondiente al
                ' separador de grupos de dígitos, que será la
                ' "coma decimal" para una configuración regional
                ' de español de España, o el punto decimal para
                ' otra configuración regional distinta.
                '
                ' Especificamos que se ha tecleado el separador decimal
                ' correspondiente con la configuración regional actual.
                e.KeyChar = m_decimalSeparator
            End If
    
        End Sub
    
    End Class


    Observa que el ejemplo asume que la tercera columna del control DataGridView (la que tiene el índice 2) es la que contiene los valores decimales. Si es otra u otras columnas, tendrás que modificar el evento EditingControlShowing del control DataGridView para establecer a Nothing el valor del campo cellTextBox que NO SE CORRESPONDA con las celdas de la columna o columnas donde deseas modificar el punto decimal por la coma decimal.

    Si por casualidad TODAS LAS CELDAS del control DataGridView son del tipo DataGridViewTextBoxColumn y en ellas se van a escribir VALORES NUMÉRICOS Y DECIMALES, entonces podrías controlar el evento KeyPress para todas ellas modificando el evento EditingControlShowing por éste otro:

        Private Sub DataGridView1_EditingControlShowing(sender As Object, e As DataGridViewEditingControlShowingEventArgs) Handles DataGridView1.EditingControlShowing
    
            ' Este evento se producirá cuando la celda pasa a modo de edición.
            '
            Static cellTextBox As DataGridViewTextBoxEditingControl
    
            If (cellTextBox Is Nothing) Then
                ' Referenciamos el control DataGridViewTextBoxEditingControl subyacente
                ' siempre y cuando su valor sea Nothing. Si la celda actual no es del tipo
                ' DataGridViewTextBoxEditingControl, el valor de la variable 'cellTextBox'
                ' será Nothing.
                '
                cellTextBox = TryCast(e.Control, DataGridViewTextBoxEditingControl)
                AddHandler cellTextBox.KeyPress, AddressOf CellTextBoxOnKeyPress
            End If
    
        End Sub

    Para más información sobre detectar los eventos de teclado del control DataGridView, te remito a la lectura del siguiente artículo:

    Cómo detectar la tecla pulsada en una celda del control DataGridView

    Si también quieres FORMATEAR a tres decimales el valor de esa columna de valores decimales, entonces sí tienes que hacer lo que te ha comentado el usuario Yhorby Matias H S. Una vez que hayas enlazado el control DataGridView con un objeto DataTable, ejecutarías:

        Me.DataGridView1.Columns(2).DefaultCellStyle.Format = "N3"

    Pero eso solamente sirve para FORMATEAR el valor decimal, pero no para modificar el punto decimal (5.4) que haya tecleado el usuario por el carácter separador decimal existente actualmente en la configuración regional del usuario que está ejecutando tu aplicación (5,4).

    Un saludo


    Enrique Martínez Montejo
    [MS MVP - Visual Studio y Tecnologías de Desarrollo]

    Nota informativa: La información contenida en este mensaje, así como el código fuente incluido en el mismo, se proporciona «COMO ESTÁ», sin garantías de ninguna clase, y no otorga derecho alguno. Usted asume cualquier riesgo al poner en práctica, utilizar o ejecutar lo recomendado o sugerido en el presente mensaje.

    Si esta respuesta le ha resultado útil, recuerde marcarla como satisfactoria.

    Si usas Visual Basic .NET y deseas ser productivo y feliz, se inteligente y activa la instrucción
    Option Strict.


    lunes, 8 de agosto de 2016 18:45
    Moderador
  • charoeci1,

    Siendo que -por configuración- estableces la coma como separador decimal entre la parte entera y decimal de un valor numérico es posible que la resolución de la consulta sql esté entendiendo dicha coma "," como separador de columnas y esa "confusión" se genera porque al parecer concatenas valores de parámetros a la consulta sql, deberías -en caso no lo hayas hecho- agregar valores de parámetros a la colección Parameters, tal como la siguiente estructura:

    Using cn As New SqlConnection("<Colocar cadena de conexión>")
    		Dim ConsultaSQL As String = "INSERT INTO T (Col1, Col2) VALUES (@Value1, @Value2)"	
    		Dim cmd As New SqlCommand(ConsultaSQL, cn)
    		
    		cmd.Parameters.AddWithValue("@Value1", TextBox1.Text)
    		cmd.Parameters.AddWithValue("@Value2", TextBox2.Text)
    		
    		cn.Open()
    		
    		cmd.ExecuteNonQuery()	
    	End Using


    Espero que la información proporcionada te haya sido de utilidad, quedo atento a tus comentarios.
    miércoles, 3 de agosto de 2016 13:40

Todas las respuestas

  • Saludos intenta formatear la celda del grid seria algo como esto 

    Me.DataGridView1.Columns(2).DefaultCellStyle.Format = "n3"

    Saludos nos dejas saber


    YhorbyMatias


    miércoles, 3 de agosto de 2016 10:28
  • Hola:
    >Hay menos columnas en la instrucción INSERT que valores en la claúsula VALUES. El número de valores de VALUES debe coincidir con el de columnas de INSERT<

    Ahora nos falta saber el codigo de como haces el Insert Into ........

    Un saludo desde Bilbo
    Carlos
    miércoles, 3 de agosto de 2016 11:39
  • charoeci1,

    Siendo que -por configuración- estableces la coma como separador decimal entre la parte entera y decimal de un valor numérico es posible que la resolución de la consulta sql esté entendiendo dicha coma "," como separador de columnas y esa "confusión" se genera porque al parecer concatenas valores de parámetros a la consulta sql, deberías -en caso no lo hayas hecho- agregar valores de parámetros a la colección Parameters, tal como la siguiente estructura:

    Using cn As New SqlConnection("<Colocar cadena de conexión>")
    		Dim ConsultaSQL As String = "INSERT INTO T (Col1, Col2) VALUES (@Value1, @Value2)"	
    		Dim cmd As New SqlCommand(ConsultaSQL, cn)
    		
    		cmd.Parameters.AddWithValue("@Value1", TextBox1.Text)
    		cmd.Parameters.AddWithValue("@Value2", TextBox2.Text)
    		
    		cn.Open()
    		
    		cmd.ExecuteNonQuery()	
    	End Using


    Espero que la información proporcionada te haya sido de utilidad, quedo atento a tus comentarios.
    miércoles, 3 de agosto de 2016 13:40
  • Hola Willams, te comento. He puesto lo que tu me dices pero cuando inserto en un campo el valor "5.4" me coge 54D y eso es lo que me guarda en el campo de la tabla "54" no "5.4". Si pongo "5,4" me hace la modificación de la "," por el "." internarmente visual studio pero no lo hace si le pongo directamente el ".".

    ¿Qué evento puedo utilizar para poder cambiar cuando pulso la tecla "."  por la tecla "," a la hora de escribir en algunos de los campos que quiero modificar y que son decimales?. Así si escribo el valor "5.4" que se convierta en "5,4" y creo que ya no tendría ningún problema a la hora de guardar los datos.

    Gracias de antemano.


    Saluditos, Charo

    miércoles, 3 de agosto de 2016 17:47
  • Saludos solo debes formatear el esa columna del dtagrid a que sea decimal con punto puedes hacer eso manualmente

    YhorbyMatias

    viernes, 5 de agosto de 2016 11:27
  • "charoeci1" preguntó:

    > ¿Qué evento puedo utilizar para poder cambiar cuando pulso la tecla "."  por la tecla ","
    > a la hora de escribir en algunos de los campos que quiero modificar y que son decimales?
    > Así si escribo el valor "5.4" que se convierta en "5,4" y creo que ya no tendría ningún
    > problema a la hora de guardar los datos.

    Hola, Charo:

    Tienes que detectar el evento KeyPress del control DataGridViewTextBoxEditingControl subyacente existente en la celda del control DataGridView que contiene los valores decimales donde deseas cambiar el punto decimal (.) por la coma decimal (,).

    Pero para que tu aplicación se adapte a la configuración regional que actualmente tenga establecida el usuario en su sistema operativo, tienes que detectar qué carácter tiene como separador de decimales (normalmente una coma en una configuración regional de español de España) y como separador de miles (normalmente el punto decimal en la misma configuración regional anterior).

    Inserta el siguiente código en el formulario que contiene el control DataGridView:

    Imports System.Globalization
    Imports System.Threading.Thread
    
    Public Class Form1
    
        Private m_decimalSeparator As Char
        Private m_groupSeparator As Char
    
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    
            ' Formato de números correspondiente a la configuración regional actual.
            Dim numberFormatInfo As NumberFormatInfo = CurrentThread.CurrentUICulture.NumberFormat
    
            ' Carácter separador decimal 
            m_decimalSeparator = numberFormatInfo.NumberDecimalSeparator.Chars(0)
    
            ' Carácter separador de grupos de digitos 
            m_groupSeparator = numberFormatInfo.NumberGroupSeparator.Chars(0)
    
        End Sub
    
        Private Sub DataGridView1_EditingControlShowing(sender As Object, e As DataGridViewEditingControlShowingEventArgs) Handles DataGridView1.EditingControlShowing
    
            ' Este evento se producirá cuando la celda pasa a modo de edición.
            '
            Static cellTextBox As DataGridViewTextBoxEditingControl
            Dim valorValido As Boolean = (Not cellTextBox Is Nothing)
    
            ' Referenciamos la celda actual.
            Dim currentCell As DataGridViewCell = DataGridView1.CurrentCell
    
            If (currentCell.ColumnIndex <> 2) Then
    
                ' El índice de la columna de la celda actual no se corresponde con el
                ' índice de la tercera columna del control DataGridView, que es la que
                ' contiene las celdas donde deseamos obtener el carácter separador
                ' decimal tecleado por el usuario.
                '
                If (valorValido) Then
                    ' Primero eliminar el controlador para el evento KeyPress siempre
                    ' y cuando el valor de la variable estática 'cellTextBox' no sea
                    ' Nothing.
                    RemoveHandler cellTextBox.KeyPress, AddressOf CellTextBoxOnKeyPress
                End If
    
                ' Después, establecer el valor Nothing a la variable estática del tipo
                ' DataGridViewTextBoxEditingControl solamente si la celda actual no se
                ' corresponde con el índice de la tercera columna, porque de no hacerlo,
                ' se desencadenaría también el evento KeyPress para aquellas otras celdas
                ' del tipo DataGridViewTextBoxColumn diferentes a aquellas donde deseamos
                ' obtener el carácter separador decimal tecleado.
                '
                cellTextBox = Nothing
    
            ElseIf (Not valorValido) Then
                ' Referenciamos el control DataGridViewTextBoxEditingControl subyacente
                ' siempre y cuando su valor sea Nothing. Si la celda actual no es del tipo
                ' DataGridViewTextBoxEditingControl, el valor de la variable 'cellTextBox'
                ' será Nothing.
                '
                cellTextBox = TryCast(e.Control, DataGridViewTextBoxEditingControl)
                AddHandler cellTextBox.KeyPress, AddressOf CellTextBoxOnKeyPress
    
            End If
    
        End Sub
    
        Private Sub CellTextBoxOnKeyPress(sender As Object, e As KeyPressEventArgs)
    
            If (e.KeyChar = m_groupSeparator) Then
                ' Se ha pulsado el carácter correspondiente al
                ' separador de grupos de dígitos, que será la
                ' "coma decimal" para una configuración regional
                ' de español de España, o el punto decimal para
                ' otra configuración regional distinta.
                '
                ' Especificamos que se ha tecleado el separador decimal
                ' correspondiente con la configuración regional actual.
                e.KeyChar = m_decimalSeparator
            End If
    
        End Sub
    
    End Class


    Observa que el ejemplo asume que la tercera columna del control DataGridView (la que tiene el índice 2) es la que contiene los valores decimales. Si es otra u otras columnas, tendrás que modificar el evento EditingControlShowing del control DataGridView para establecer a Nothing el valor del campo cellTextBox que NO SE CORRESPONDA con las celdas de la columna o columnas donde deseas modificar el punto decimal por la coma decimal.

    Si por casualidad TODAS LAS CELDAS del control DataGridView son del tipo DataGridViewTextBoxColumn y en ellas se van a escribir VALORES NUMÉRICOS Y DECIMALES, entonces podrías controlar el evento KeyPress para todas ellas modificando el evento EditingControlShowing por éste otro:

        Private Sub DataGridView1_EditingControlShowing(sender As Object, e As DataGridViewEditingControlShowingEventArgs) Handles DataGridView1.EditingControlShowing
    
            ' Este evento se producirá cuando la celda pasa a modo de edición.
            '
            Static cellTextBox As DataGridViewTextBoxEditingControl
    
            If (cellTextBox Is Nothing) Then
                ' Referenciamos el control DataGridViewTextBoxEditingControl subyacente
                ' siempre y cuando su valor sea Nothing. Si la celda actual no es del tipo
                ' DataGridViewTextBoxEditingControl, el valor de la variable 'cellTextBox'
                ' será Nothing.
                '
                cellTextBox = TryCast(e.Control, DataGridViewTextBoxEditingControl)
                AddHandler cellTextBox.KeyPress, AddressOf CellTextBoxOnKeyPress
            End If
    
        End Sub

    Para más información sobre detectar los eventos de teclado del control DataGridView, te remito a la lectura del siguiente artículo:

    Cómo detectar la tecla pulsada en una celda del control DataGridView

    Si también quieres FORMATEAR a tres decimales el valor de esa columna de valores decimales, entonces sí tienes que hacer lo que te ha comentado el usuario Yhorby Matias H S. Una vez que hayas enlazado el control DataGridView con un objeto DataTable, ejecutarías:

        Me.DataGridView1.Columns(2).DefaultCellStyle.Format = "N3"

    Pero eso solamente sirve para FORMATEAR el valor decimal, pero no para modificar el punto decimal (5.4) que haya tecleado el usuario por el carácter separador decimal existente actualmente en la configuración regional del usuario que está ejecutando tu aplicación (5,4).

    Un saludo


    Enrique Martínez Montejo
    [MS MVP - Visual Studio y Tecnologías de Desarrollo]

    Nota informativa: La información contenida en este mensaje, así como el código fuente incluido en el mismo, se proporciona «COMO ESTÁ», sin garantías de ninguna clase, y no otorga derecho alguno. Usted asume cualquier riesgo al poner en práctica, utilizar o ejecutar lo recomendado o sugerido en el presente mensaje.

    Si esta respuesta le ha resultado útil, recuerde marcarla como satisfactoria.

    Si usas Visual Basic .NET y deseas ser productivo y feliz, se inteligente y activa la instrucción
    Option Strict.


    lunes, 8 de agosto de 2016 18:45
    Moderador
  • Buenas, amigo trata cambiando tu configuración regional desde panel de control.

    Alexander Jimenez

    martes, 9 de agosto de 2016 1:06
  • "AJ Designs" aconsejó:

    > amigo trata cambiando tu configuración regional desde panel de control.

    ¡Claro! Y si la aplicación se ejecuta en 50.000 PCs, le modifico a cada uno de ellos la configuración regional que tenga establecida el usuario en el Panel de Control, para fastidiarle al usuario otras aplicaciones diferentes que tenga instaladas en su equipo.

    ¿Quieres un consejo gratuito? Olvídate de cambiar la configuración regional que tenga establecida el usuario en su sistema operativo y haz que tu aplicación se adapte a ella, en vez que la configuración regional se adapte a los requerimientos de tu aplicación. ;-)

    Un saludo


    Enrique Martínez Montejo
    [MS MVP - Visual Studio y Tecnologías de Desarrollo]

    Nota informativa: La información contenida en este mensaje, así como el código fuente incluido en el mismo, se proporciona «COMO ESTÁ», sin garantías de ninguna clase, y no otorga derecho alguno. Usted asume cualquier riesgo al poner en práctica, utilizar o ejecutar lo recomendado o sugerido en el presente mensaje.

    Si esta respuesta le ha resultado útil, recuerde marcarla como satisfactoria.

    Si usas Visual Basic .NET y deseas ser productivo y feliz, se inteligente y activa la instrucción
    Option Strict.


    martes, 9 de agosto de 2016 10:52
    Moderador