IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

VB.NET Discussion :

Problème de virgule et/ou point


Sujet :

VB.NET

  1. #1
    Membre confirmé Avatar de thierry007
    Homme Profil pro
    Autodidacte
    Inscrit en
    Août 2006
    Messages
    876
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Autodidacte
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2006
    Messages : 876
    Points : 457
    Points
    457
    Par défaut Problème de virgule et/ou point
    Bonjour,

    Je suis régulièrement confronté a des erreurs a l'enregistrement du record en SQL, avec les nombre de type float dans la DB.Quelqu'un me dire la meilleur façon de faire ( conversion, autre type de nombre,...)

    Merci de votre aide
    La Connaissance est comme la joie elle s'accroît en la partageant!

  2. #2
    Membre éprouvé
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    948
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 948
    Points : 1 111
    Points
    1 111
    Par défaut
    "des erreurs" c'est assez vague. Quelles erreurs?

  3. #3
    Membre confirmé Avatar de thierry007
    Homme Profil pro
    Autodidacte
    Inscrit en
    Août 2006
    Messages
    876
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Autodidacte
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2006
    Messages : 876
    Points : 457
    Points
    457
    Par défaut
    et bien si le nombre a enregistrer est 2.222,65 cela donne une erreur
    si le nombre est 2 222,65 aussi l'erreur est présente
    Je pe,se que cela dépand des paramètre régionaux mais alors commen faire pour ne pas en dépendre..
    La Connaissance est comme la joie elle s'accroît en la partageant!

  4. #4
    Membre éprouvé
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    948
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 948
    Points : 1 111
    Points
    1 111
    Par défaut
    Alors il va falloir etre plus précis et donner du code, d'ou il sort ton nombre (rempli par l'utilisateur dans une textbox, lu quelque part, ...?), quelle est ta requete SQL, etc...
    il faut que tu expliques ton problème de manière complète si tu veux une réponse utile.

  5. #5
    Membre confirmé Avatar de thierry007
    Homme Profil pro
    Autodidacte
    Inscrit en
    Août 2006
    Messages
    876
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Autodidacte
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2006
    Messages : 876
    Points : 457
    Points
    457
    Par défaut
    Table SQL
    Designation: type char
    Prix: type float

    Designation = textbox -> saisie
    Prix = textbox -> saisie

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    StrSql = "UPDATE Articles SET " & _
                      "Designation='" & Designation.Text & "'," & _
                      "Prix=" & Prix.Text & _
                      "WHERE IdArticle=" & IdArticle

    Voila je pense qe tu comprendra mieux comme cela

    Merci de ton aide
    La Connaissance est comme la joie elle s'accroît en la partageant!

  6. #6
    Membre éprouvé
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    826
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juin 2006
    Messages : 826
    Points : 1 120
    Points
    1 120
    Par défaut
    Salut,

    ne peux tu pas utiliser de procédures stockées ? ça t'évitera ce genre d'erreurs.

    Dans le cas contraire, il faut que tu vérifies le type avant de l'envoyer vers la requête, ça t'évitera le SQL injection. Une fois ton type vérifié, tu le converti dans le type désiré (float par exemple), puis tu formate ta requête avec string.format. tu n'auras alors plus ce genre de problèmes.

  7. #7
    Membre éprouvé
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    948
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 948
    Points : 1 111
    Points
    1 111
    Par défaut
    D'accrod avec cybermaxs, il ne faut pas que tu envoies directement le texte dans ta requete SQL. Il faut que tu le mettes au bon format avant.
    2 manières de le faire, soit tu mets un contrôle de format directement dans ta textbox pour que l'utilisateur ne puisse pas taper n'importe quoi (voir l'article sur les expressions régulières), soit faire un traitement à la validation de la forme qui va tester si le contenu de ton texte est un nombre, et si c'en est un, le mettre au bon format.

    Ici ce n'est en aucun un problème de paramètres régionaux.

    Pour information tu auras aussi des problemes avec ta désignation si tu rentres des apostrophes dedans. En toute rigueur tout ce qui est envoyé dans une requète doit être formaté auparavant de manière appropriée (suppression des caracteres apostrophe pour les textes, mise au format numérique, etc...). Cela évite d'une part les plantages, et d'autre part les injections SQL comme l'a dit cybermax, qui sont des moyens de pirater ta base de données mais qui ne marchent que s'il y a des oublis de formatage des variables.

  8. #8
    Membre confirmé Avatar de thierry007
    Homme Profil pro
    Autodidacte
    Inscrit en
    Août 2006
    Messages
    876
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Autodidacte
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2006
    Messages : 876
    Points : 457
    Points
    457
    Par défaut
    Voila quelque chose bien interessant.
    Y a t'il de la lecture ou des exemples de codes qui pourraient m'aider
    La Connaissance est comme la joie elle s'accroît en la partageant!

  9. #9
    Membre confirmé Avatar de thierry007
    Homme Profil pro
    Autodidacte
    Inscrit en
    Août 2006
    Messages
    876
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Autodidacte
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2006
    Messages : 876
    Points : 457
    Points
    457
    Par défaut
    Je me pose al question également si l'operateur tape un poit'.' ou une virgule ',' cela aura aussi une insidence non?
    La Connaissance est comme la joie elle s'accroît en la partageant!

  10. #10
    Membre éprouvé
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    948
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 948
    Points : 1 111
    Points
    1 111
    Par défaut
    Oui le point et la virgule, ca a une incidence, a priori ce que tu envoies a la base de données c'est un point.

    Voilà un petit exemple de code pas forcément complet mais qui t'aidera à comprendre le principe :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
     
     
    Dim sDesignationSQL as string
    Dim sPrixSQL as string
    Dim fPrixSQL as float
    Dim bReussi boolean  'indique si le contenu de la textbox est un nombre
     
     
    DesignationSQL = Designation.text.replace("'"," ") 'remplacer une apostrophe par un blanc. Note que je pense que si tu le remplace par une double apostrophe ca marche aussi.
     
    sPrixSQL = Prix.text
    sPrixSQL = sPrixSQL.replace (" ","") 'supprimer les espaces
    sPrixSQL = sPrixSQL.replace(",",".") 'remplacer une virgule par un point
     
    Try
          fPrixSQL = CType(sPrixSQL, float)
          bReussi = true
    Catch e as exception
          bReussi = false
    End try
     
    if bReussi then
     
    'execute ici ta requete :
     
    StrSql = "UPDATE Articles SET " & _
                      "Designation='" & sDesignationSQL & "'," & _
                      "Prix=" & fPrixSQL.tostring & _
                      "WHERE IdArticle=" & IdArticle
    Else
    'genere ici un message d'erreur a l'utilisateur pour lui dire qqu'il n'a pas rentré un nombre dans la textbox
    End if

  11. #11
    Membre confirmé Avatar de thierry007
    Homme Profil pro
    Autodidacte
    Inscrit en
    Août 2006
    Messages
    876
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Autodidacte
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2006
    Messages : 876
    Points : 457
    Points
    457
    Par défaut
    Voici un peut traduit a mon appli

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
     
      Private Function ClearStringDecimal(ByRef Chaine As String) As Decimal
                Dim Nombre As Decimal
                Dim Conversion As Boolean = False
     
                Chaine = Chaine.Replace(",", ".")
                Chaine = Chaine.Replace(" ", "")
     
                Try
     
                      MsgBox(Chaine)
                      Nombre = CType(Chaine, Decimal)
                      Conversion = True
                      MsgBox(Nombre)
     
                Catch ex As Exception
     
                      Conversion = False
     
                End Try
     
                If Conversion = True Then Return Nombre Else MsgBox("Mauvais nombre")
     
          End Function
    j'ai mis les 2 MsgBox pour le résultat. Assez bizarement
    le premier MsgBox affiche bien le nombre (ex: 5555.22)
    le 2ème affiche (555522)
    il a supprimer le point '.' aussi
    Est-ce du a la conversion?
    ou alors je rate quelques chose ( possible aussi )
    La Connaissance est comme la joie elle s'accroît en la partageant!

  12. #12
    Membre confirmé Avatar de thierry007
    Homme Profil pro
    Autodidacte
    Inscrit en
    Août 2006
    Messages
    876
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Autodidacte
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2006
    Messages : 876
    Points : 457
    Points
    457
    Par défaut
    Petit test effectuer je ne retourne pas le bon type de donnée
    en fait je dois retourner du string
    En tout cas pour l'instant cela fonctionne

    Encore un GGGrand merci du coup de main

    Tres agréable de rencontrer des personne comme toi

    La Connaissance est comme la joie elle s'accroît en la partageant!

  13. #13
    Membre averti Avatar de The_Big_Lebowski
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mars 2009
    Messages
    225
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2009
    Messages : 225
    Points : 304
    Points
    304
    Par défaut
    Nous sommes là confrontés a un probleme culturel qui peut être géré par windows.
    Je suppose que le message d'erreur est du type : Plus de values que de colonnes dans la requete insert (ou quelque chose comme ca)
    Et je comprends bien le moteur de ton SGBD
    le séparateur de données en sql est la virgule

    2 possibilités pour résoudre ton problème
    1: Changer le séparateur de décimale dans les options régionales de Windows
    2: traiter la culture FR dans ton programme ce qui a mon sens reste plus fastidieux mais tu peux trouver beaucoup d'exemples sur ce forum et/ou sur ton moteur de recherche préféré.

    teste bien evidemment ta valeur avant de construire ta requête SQL, valide la saisie si celle-ci est conforme.

  14. #14
    Membre confirmé Avatar de thierry007
    Homme Profil pro
    Autodidacte
    Inscrit en
    Août 2006
    Messages
    876
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Autodidacte
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2006
    Messages : 876
    Points : 457
    Points
    457
    Par défaut
    Oui, effectivement en regardans sur le net les discutions tournent bien sur cet axe de culture.
    Je regarde a ne pas dépendre de celle-ci justement

    Merci du conseil
    La Connaissance est comme la joie elle s'accroît en la partageant!

  15. #15
    Membre averti
    Profil pro
    Inscrit en
    Février 2010
    Messages
    291
    Détails du profil
    Informations personnelles :
    Âge : 55
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 291
    Points : 390
    Points
    390
    Par défaut
    Bonjour,

    Une façon de faire est d'imposer le point comme séparateur décimal pour le Thread en cours en utilisant les APIs :
    GetThreadLocale et SetLocaleInfo
    Je ne vous donne pas les déclarations car je ne les ai pas encore adaptées à .NET

    En VB
    cela donnait ça

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Private Declare Function GetThreadLocale& Lib "kernel32" ()
    Private Declare Function SetLocaleInfo& Lib "kernel32" Alias "SetLocaleInfoA" (ByVal locale As Long, ByVal LCType As Long, ByVal lpLCData As String)
    [...]
    locale& = GetThreadLocale
    dummy& = SetLocaleInfo(locale, &HE, ".")
    A+

  16. #16
    Membre confirmé Avatar de thierry007
    Homme Profil pro
    Autodidacte
    Inscrit en
    Août 2006
    Messages
    876
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Autodidacte
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2006
    Messages : 876
    Points : 457
    Points
    457
    Par défaut
    Un changement simple de culture dans le programme, ne faciliterait pas
    passage en culture US

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Thread.CurrentThread.CurrentCulture = New Globalization.CultureInfo("enus")'
    Peut être des concéquences plus loin!!!
    La Connaissance est comme la joie elle s'accroît en la partageant!

  17. #17
    Candidat au Club
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 3
    Points : 4
    Points
    4
    Par défaut
    Bonjour ,

    J'ai a peu près le même genre de problème point/virgule.

    J'ai une application qui se sert du datagridview pour saisir entre autres des floats.
    Mes clients utilisent le point du clavier numérique comme séparateur décimal au lieu de la virgule.

    Avant le endedit , donc dans l'évènement cellValidating, j'essaye de modifier par programmation, mais l'évènement dataerror s'affiche toujours avant donc je tourne en rond.
    Si quelqu'un à une idée pour changer un point par une virgule par
    programmation dans une cellule d'un datagridview qui n'est pas encore validée je l'en remercie.

    Alex

  18. #18
    Membre du Club
    Inscrit en
    Septembre 2010
    Messages
    168
    Détails du profil
    Informations personnelles :
    Âge : 37

    Informations forums :
    Inscription : Septembre 2010
    Messages : 168
    Points : 55
    Points
    55
    Par défaut
    bonjour thierry007 j'ai déjà eu le même problème bon je te donne la solution efficace
    tu laisse ton code comme ça

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    StrSql = "UPDATE Articles SET " & _
                      "Designation='" & Designation.Text & "'," & _
                      "Prix=" & val(Prix.Text) & " _
                      "WHERE IdArticle=" & IdArticle
    après tu vas sur panneau de configuration
    -options régional et linguistique
    -tu choisi la langue français
    -personnaliser
    -tu joue sur les paramètre comme tu veux
    si il ya un autre problème je suis à votre service

    Salutations

  19. #19
    Membre confirmé Avatar de thierry007
    Homme Profil pro
    Autodidacte
    Inscrit en
    Août 2006
    Messages
    876
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Autodidacte
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2006
    Messages : 876
    Points : 457
    Points
    457
    Par défaut
    StrSql = "UPDATE Articles SET " & _
    "Designation='" & Designation.Text & "'," & _
    "Prix=" & val(Prix.Text) & " _
    "WHERE IdArticle=" & IdArticle
    la le val(prix.text) va te retourner un nombre arrondi : 1,2 devient 1

    Mais pour le problème c'est un problème qui est assez général
    le principe des paramètres régionaux est le plus utilisé

    C'est le malheur de la langue francaise en anglaise il n'y a pas encore une uniformisation : dommage mais bon

    A+
    La Connaissance est comme la joie elle s'accroît en la partageant!

  20. #20
    Membre éprouvé
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    665
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 665
    Points : 1 161
    Points
    1 161
    Par défaut
    Bonsoir,
    dans le sens des suggestions proposées ci dessus, je procéderais en usant des cultures pour l'utilisation du pavé numérique, pour l'affichage dans les contrôles et la valeur formatée pour la base de données.

    1) ci dessous, déclaration et instanciation des cultures et d'un clone de celle de l'ordi. pour lui apporter quelque personnalisation :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    Imports System.Globalization
    Imports System.Threading
     
    Public Class Form1
        '*** Clonage des "Options régionales" du panneau de configuration.
        '    (CultureInfo représentant la culture régionale de l'ordinateur). 
        Dim maCI As CultureInfo = CultureInfo.CurrentCulture
        Dim maCIclone As CultureInfo = CType(maCI.Clone(), Globalization.CultureInfo)
        '*** Culture pour envoyer des données à la base (A voir)?
        Dim CIInv As CultureInfo = CultureInfo.InvariantCulture
        Dim CIus As New CultureInfo("en-US", False)
     
        Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
            '*** Utilisation du clone pour modifier certains paramètres de la culture de base
            '    qui s'appliqueront à la culture du thread en cours.
            '    On impose le "." comme séparateur décimal, pour les machines qui ont
            '    dans leur configuration la virgule (Fr). (Dans cette config., la conversion
            '    de String en Décimal n'accepte pas le ".", comme d'ailleurs toutes les 
            '    autres fonctions de conversion (CType,...), la fonction Parse, 
            '    les mise en forme ToString.)
            '    On pourra ainsi employer le "." du pavé numérique pour entrer un nombre 
            '    à décimales.
            '    Pour la présentation des données, on utile les paramètres de l'ordi. pour les contrôles.
            '    Pour l'envoi des données, voir ce que la base exige?.
            '*** En résumé, on utilise la culture clonée pour le traitement.
            '    La culture de base de l'ordinateur pour la présentation dans les contrôles.
            '    La culture (à définir) pour la base de données.
     
            maCIclone.NumberFormat.NumberDecimalSeparator = "."
            Thread.CurrentThread.CurrentCulture = maCIclone
    A ce stade les entrées numériques avec comme séparateur décimal soit le point soit la virgule sont acceptées;

    2) Contrôle strict des entrées utilisateur par une expression rationnelle.
    et formatage du résultat pour présentation visuelle et pour envoi à la base de donnée :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
        Dim valEnvoiBD As Double
     
        Private Sub TextBox1_Validated(ByVal sender As Object, ByVal e As System.EventArgs) Handles TextBox1.Validated
     
            Dim entreeTbx As String = TextBox1.Text
            '*** Nettoie tous espaces blancs intempestifs
            entreeTbx = System.Text.RegularExpressions.Regex.Replace(entreeTbx, "[\s]*", "")
            '*** N'accepte que les integers ou les décimaux avec au maximum 2 chiffres derrière la virgule.
            Dim pattern As String
            pattern = "^(([0-9]+)|(([0-9]+)((\.|,))([0-9]{0,2}))?)$"
            If entreeTbx = System.Text.RegularExpressions.Regex.Match(entreeTbx, pattern).ToString AndAlso entreeTbx <> "" Then
                Dim d As Double = CDbl(entreeTbx)
                TextBox1.Text = d.ToString("N", maCI)
     
                valEnvoiBD = CDbl(entreeTbx)
                MessageBox.Show(CStr(valEnvoiBD.ToString("N", CIInv)))
            Else
                entreeTbx = ""
                TextBox1.Text = ""
                TextBox1.Focus()
            End If
     
        End Sub
    J'ai utilisé la culture invariante pour la base de donnée, mais n'ayant aucune expérience en SQL, il faudra tester et adapter au besoin.
    Concernant le thread sur la culture, je n'ai pas rencontré de problème.

Discussions similaires

  1. Problème de virgule et de point
    Par androz dans le forum C++Builder
    Réponses: 10
    Dernier message: 24/03/2009, 18h29
  2. Problème de virgule
    Par Drax dans le forum Débuter
    Réponses: 12
    Dernier message: 04/12/2005, 14h40
  3. [D7] Problème de virgule flottante
    Par Magnus dans le forum Langage
    Réponses: 17
    Dernier message: 22/09/2005, 14h56
  4. Problème de Regex ... avec un point
    Par bugalood dans le forum Langage
    Réponses: 2
    Dernier message: 29/05/2005, 10h26
  5. [Kylix] Problème de virgule/DBExpress
    Par jeanphy dans le forum EDI
    Réponses: 5
    Dernier message: 12/02/2003, 16h29

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo