begin process at 2012 02 13 01:02:42
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

Base de registre

 > FORCER LE "." POINT COMME PARAMÈTRE DÉCIMAL DANS LES PARAMÈTRES RÉGIONNAUX ( MA SOLUTION)

FORCER LE "." POINT COMME PARAMÈTRE DÉCIMAL DANS LES PARAMÈTRES RÉGIONNAUX ( MA SOLUTION)




 Description

Cliquez pour voir la capture en taille normale
Il existait sur le site une source traitant de ce sujet qui avait même déclanshée pas mal de polémique. Elle  avait l'avantage d'apporter pas mal de débat, solution avis sur la question. Malheureusement je viens de voir qu'elle a été désactivé par un ADMIN ! Pourqouoi ? pas d'infos c'est peut être un manque dans le site au lieu de mettre juste désactivé la raisson serait intéressante. La source s'appelait (TESTER SIMPLEMENT LA "," OU LE "." EN PARAMÈTRE REGIONAL http://www.vbfrance.com/code.aspx?id=32227 )

Enfin bref pour répondre à un problème récurent je poste ma solution à ce problème. C'est une solution un peu barbare qui consiste àa forcer le paramètre directement dans le registre. C'est pas propre mais efficace.

Le problème est le suivant dans les paramètres régionnaux sous windows tu peux fixer le format du symbol déciaml. En France c'est la virgule au US ou autre c'est le point. Le problème vient ensuite quand tu veux écrire ou relire un nonbre dans un fichier texte ou dans un controle. la conversion selon que tu as 0,2 ou 0.2 ne donnera pas la même chose. si tu es avec une virgule une fonction du type Val te retournera 0 de même l'écriture de 0.2 dans un fichier texte via une fonction comme format(MaValeurDouble,"0.000")  ( pour écrire un nombre avec trois chiffres après la virgule te donnera 0,2 au lieu des 0.2 désirée.

Comme pour ma part toute mes applications utilise des format de type . avec séparateur décimal j'ai opté pour la solution radicale : Je force.

A l'ouverture du programme  je test en regardant dans le registre le charactère (Y a plus simple voir autres sources sur le site ) si c'est pas le bon jécris le point et j'ouvre automatiquement le panneau des réglages régionnaux pour indiquer à l'utilisateur la modif. On est pas des bètes tout de même :)


Source

  • Private Sub Form_Load()
  • ' test le charactere décimal
  • If test_decimal Then
  • ' force le charactere à un point
  • ' NE marche pas ...
  • Call EcritureRegistre(HKEY_CURRENT_USER, "Control Panel\International", "sDecimal", REG_SZ, ".")
  • Shell "rundll32 shell32,Control_RunDLL intl.cpl" ' Regional setting
  • End If
  • End Sub
  • ' test dans le registre le charactere de la décmal
  • Function test_decimal() As Boolean
  • Dim rc As Long
  • Dim SysDecimal As String
  • rc = GetKeyValue(HKEY_CURRENT_USER, "Control Panel\International", "sDecimal", SysDecimal)
  • If SysDecimal <> "," Then
  • test_decimal = True
  • MsgBox "Attention le caracthere décimal n'est pas un point"
  • Else
  • test_decimal = False
  • End If
  • End Function
Private Sub Form_Load()
' test le charactere décimal
If test_decimal Then
    ' force le charactere à un point
    ' NE marche pas ...
    Call EcritureRegistre(HKEY_CURRENT_USER, "Control Panel\International", "sDecimal", REG_SZ, ".")
    Shell "rundll32 shell32,Control_RunDLL intl.cpl"    ' Regional setting
End If

End Sub

' test dans le registre le charactere de la décmal
Function test_decimal() As Boolean
Dim rc As Long
Dim SysDecimal As String
    

rc = GetKeyValue(HKEY_CURRENT_USER, "Control Panel\International", "sDecimal", SysDecimal)
If SysDecimal <> "," Then
    test_decimal = True
    MsgBox "Attention le caracthere décimal n'est pas un point"
Else
    test_decimal = False
End If

End Function

 Conclusion

Voilà vous pouvez Y aller de vos commentaires . Cette source est faites pour ca ...

 Fichier Zip

Les Membres Club peuvent télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip


 Sources du même auteur

Source avec Zip Source avec une capture PILOTER GOOGLEEARTH AVEC SES API
Source avec Zip Source avec une capture VISUALISATEUR / EDITEUR OPENGL
Source avec Zip Source avec une capture JEUX DE COMBAT OPENGL
Source avec Zip Source avec une capture ROTATION 3D
Source avec Zip Source avec une capture MENU DÉROULANT FAÇON XP SANS OCX

 Sources de la même categorie

Source avec Zip Source avec une capture Source .NET (Dotnet) SHELLVIEW EN VB.NET par Le Pivert
Source avec Zip Source avec une capture Source .NET (Dotnet) AJOUTER OU SUPPRIMER MENU CONTEXTUEL D'APPLICATION PAR CLIC ... par Le Pivert
Source avec Zip Source avec une capture Source .NET (Dotnet) MODIFIER IMAGE COULEUR EN NOIR ET BLANC PAR CLIC DROIT par Le Pivert
Source avec Zip Source avec une capture Source .NET (Dotnet) RENOMMER TOUS LES FICHIERS D'UN DOSSIER PAR CLIC DROIT par Le Pivert
Source avec Zip Source avec une capture Source .NET (Dotnet) REDIMENSIONNER ET IMPRIMER FORMAT PHOTO (10X15) par Le Pivert

 Sources en rapport avec celle ci

Source avec Zip Source avec une capture CONVERTIR UN NOMBRE DÉCIMAL EN FRACTION par Guillaume170194
RETROUVER UN POINT À PARTIR D'UN AUTRE POINT ET D'UNE DISTAN... par michael59330
UN CDBL QUI GERE LES OPTIONS REGIONAL CONCERANT LE SEPARATEU... par Nic0s
Source avec Zip Source avec une capture Source .NET (Dotnet) SÉPARATEUR DÉCIMAL DES NOMBRES. par christoni
CONNAÎTRE LE SÉPARATEUR DÉCIMAL DE VOTRE ORDINATEUR par Neo.balastik

Commentaires et avis

Commentaire de BruNews le 08/09/2005 09:52:48 administrateur CS

Si ton prog a besoin du point décimal:
- Ecrire "." dans BDR
- PostMessage(HWND_BROADCAST, WM_SETTINGCHANGE, 0, 0)
- Faire tes traitements
- Remettre ancien séparateur décimal
- PostMessage(HWND_BROADCAST, WM_SETTINGCHANGE, 0, 0)

Evitera intervention utilisateur puisque devait se faire obligatoirement.

Commentaire de franckydeluka le 08/09/2005 10:25:45

Salut,

comme le dit Brunews si ton prog a besoin du point decimal tu le parametre dans ton form_load puis tu l'enleve dans le form_unload

regarde sur cette source tu telecharge le module :

http://www.vbfrance.fr/code.aspx?id=3258

elle est très bien faite.

sinon bien vu quand même mais tu peux améliorer.
ah oui pour les commentaires essaie de mettre tout en français parce qu'on parle pas tous forcément anglais

A+

Francky Deluca.

Commentaire de bouv le 08/09/2005 16:50:53

Slt, je ne regarde pas le code mais je trouve ta manière de procédé plutôt mauvaise.
Imagine que moi je décide de faire tout mes progs en utilisant la virgule comme séparateur décimal, et que comme toi je force l'inscription dans le registre. Imagine ensuite qu'une même personne utilise nos 2 applis. Que va-t-il se passer ?
Ta solution :
   1 - Est égoïste
   2 - N'en est pas une (puisque je viens de te montrer une faille)
   3 - N'est pas pro (s'est au développeur de s'adapter et nom à l'OS).

A mon sens il faut stocker le séparateur décimal du PC dans une variable au lancement de l'appli et utiliser ensuite. Ainsi tu ne touche pas au parametres du PC et ton appli reste compatible avec tout les PC.

Commentaire de cuq le 08/09/2005 17:39:47

Voila une bonne remarque. Et voila pourquoi ce sujet est sensible.
Je pense que tu n'as jamais éte confronté au problème avant d'écrire ton commentaire.

Oui c'est égoiste et oui c'est à l'appli d'être indépendante mais dans ce cas je n'ai pas trouvé de solution. de solution simple :)

dans mon type d'appli j'utilise souvent les fonctions VAL, FORMAT et autres de ce type ces fonctions étant directement dépendantes des paramètres régionaux pour s'affranchir du problème il faudrait ré-écrire  toutes ces fonctions pour les rendre indépendantes de ce paramètre. Si comme moi tu es amené à relire beaucoup de ligne avec beaucoup de traitement ré-écrire ces fonctions c'est au détriment de la rapidité de ton logiciel.

De plus le problème c'est vraiment la virgule tu trouveras souvent la question de changer la virgule en point mais pas l'inverse. C'est un problème on va dire Francais ou europeen pas  Anglo Saxon Voila pourquoi les §$%% de chez Microsoft n'on pas gérer ce problème.  Maintenant la plus part des formats texte que tu doit relire utilise le point . Format d'echange standard comme IGES, DXF, WRML , GPS .... Format d'origine US . Donc si tu travail sur ce type de fichier tu as le problème.

Et dernier point tu remarqueras que si tu changes la virgule en point cela passe n'est pas très pénalisant .

Enfin je ne dit pas que c'est LA solution c'est MA solution que j'utilise depuis plusieurs années sans rencontrer de problème ni de retour des utilisateurs. Donc le constat est le suivant nous n'avons pas les mêmes utilisateurs.

Maintenant le truc Idéal serait de changer le paramètre pas au niveau de l'utilisateur mais au niveau de l'appli . J'ai longtemps cherché je cherche encore .... Si vous avez un avis une idée je suis preneur.

Mais comme indiqué dans le texte de départ ce sujet est polémique .Il est polémique pour une raison comme tu le dit c'est égoiste et pas pro donc ce genre de sentiment déclenche la polémique et les sarcasmes seulement voilà On le sait , je le sais et si j'ai pris cette solution c'est que justement c'était la meilleru à mon avis.

En attendant la suite ... Cuq

Commentaire de BruNews le 08/09/2005 18:19:45 administrateur CS

Alors pour changer, pas besoin d'aller dans le registre, API fera mieux et plus vite:
SetLocaleInfo(1024, 0x0E, ".");
Votre code ici.
SetLocaleInfo(1024, 0x0E, ",");
et voila remis en ordre.

Commentaire de cuq le 08/09/2005 18:41:19

Ok ca c'est une bonne info. Mais je n'ai jamais vu SetLocalInfo il y a un GetLocalInfo oui pas l'écriture tu as pris cette info ou ? sur l'API guide de allapi.net Y a pas de référence ?

T'as un exemple ? Mais bon ca reste le même truc ce qu'il faudrait c'est un SetLocalApliInfo :)

Cuq

Commentaire de cuq le 08/09/2005 18:48:05

Autant pour moi :

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/intl/nls_8d0z.asp

En regradant un peu j'ai vu GetNumberFormat a voir c'est peut être la solution

Commentaire de BruNews le 08/09/2005 19:00:22 administrateur CS

Pour ne pas changer tout le système vu que ça pose problème (et c'est juste), vous pouvez employer:
SetThreadLocale

Commentaire de cuq le 08/09/2005 19:06:26

Private Type NUMBERFMT
        NombreDecimal As Long               '  nombre de décimal
        ZeroTete As Long                    '  Afficher les zéro en en tête (Marche pas  ?)
        Groupe As Long                      '  Groupement des digit ( 3 pour les milliers)
        SeparateurDecimal As String         '  Separateur des Decimals
        SeparateurMillier As String         '  Separateur des miliers ( Voir Groupe )
        PositionSigneNegatif As Long          '  Position du signe négatif
End Type
Private Declare Function GetNumberFormat Lib "kernel32" Alias "GetNumberFormatA" (ByVal Locale As Long, ByVal dwFlags As Long, ByVal lpValue As String, lpFormat As NUMBERFMT, ByVal lpNumberStr As String, ByVal cchNumber As Long) As Long
Private Sub Form_Load()
    Dim Buffer As String, NF As NUMBERFMT
    
    Buffer = String(255, 0)
    With NF
        .NombreDecimal = 3
        .ZeroTete = 1
        .Groupe = 3
        .SeparateurDecimal = "."
        .SeparateurMillier = " "
        .PositionSigneNegatif = 1
    End With
    
    GetNumberFormat ByVal 0&, 0, "-0015545.242315654", NF, Buffer, Len(Buffer)
    MsgBox Buffer
End Sub

Enfin ca reste lourd à mon avis si tu doit l'employer toute les 2 lignes de code et j'ai pas testé au niveau performance

Tu as un exemple pour SetThreadLocale
Cuq

Commentaire de cuq le 08/09/2005 19:37:08

Bon ben pour setlocalThread j'ai pas tout compris mais ce serait pas plus pour basculer en mode  system locale. ou Default user locale. et ca semble n'avoir d'influence que sur des fonctions du type findRessource  Bref A rien compris
:


pour GetLocalInfo ( oui c'est pour récupérer la valeur de la décimal sans passer par le registre un petit exemple pour les autres :

Const LOCALE_SDECIMAL = &HE

Private Declare Function GetLocaleInfo Lib "kernel32" Alias "GetLocaleInfoA" (ByVal Locale As Long, ByVal LCType As Long, ByVal lpLCData As String, ByVal cchData As Long) As Long
Private Declare Function SetThreadLocale Lib "kernel32" (ByVal LCID As Long) As Boolean
Private Sub Form_Load()
  
    MsgBox "la décimal est le ou la  : " & GetInfo(LOCALE_SDECIMAL)
End Sub

Public Function GetInfo(ByVal lInfo As Long) As String
    Dim Buffer As String, Ret As String
    Buffer = String$(256, 0)
    Ret = GetLocaleInfo(LOCALE_USER_DEFAULT, lInfo, Buffer, Len(Buffer))
    If Ret > 0 Then
        GetInfo = Left$(Buffer, Ret - 1)
    Else
        GetInfo = ""
    End If
End Function

Commentaire de BruNews le 08/09/2005 19:37:29 administrateur CS

J'ai testé SetThreadLocale dans Excel mais pas moyen d'arriver à sortir un "." en séparateur.
Le plus simple reste SetLocaleInfo() comme dit plus haut.

Commentaire de Renfield le 09/09/2005 08:00:59 administrateur CS

OK pour l'utilisation de l'API...

Je ne suios pas plus d'accord que sur l'autre source, sur ce procede...

VB s'adapte pas trop mal aux regional settings...
Reste a faciliter la saisie :
- le . du pave numerique, et la touche , insereront un separateur
- les dates (ne pas les oublier !) transformeront - / . en separateur de date

prendre les donnees d'un SGBD ne posera pas de soucis, si les champs sont bien types...
pour un fichier texte, il faudra se discipliner : adopter une convention

prendre la "norme US", par exemple...

Commentaire de cuq le 09/09/2005 08:22:23

Salut,
Je comprend pas vraiment ce que tu veux dire par "norme US".
Et au contraire de toi je pense que dans mon cas VB s'adapte très mal aux régional settings . Non plus exactement c'est ce Séparateur décimal qui est la cause de tout.

Pour les fichiers texte tu n'as pas à te discipliner .
SI tu prends des formats Texte existant des standard du marché comme par exemple:
DXF pour les données CAO géométriques 2D
IGES pour les données CAO géométriques 3D
GPS , WRML, STEP , STL qui sont des formats standards et beaucoup d'autres.
Dans ces fichiers le séparateur est le point. Pour nous (Français et européen en général le séparateur est la virgule) .
Donc en VB si tu veux lire, convertir ces données texte en valeur type double par exemple la conversion par val retournera une mauvaise valeur. Sauf si tu utilise Replace ) mais dans ce cas tu complique et ralenti ton code ) de plus très souvent le séparateur de champ dans ces fichiers est ... la virgule. Donc tu ne peut pas faire un seul replace sur une ligne relue mais X relpace après avoir isolé chaque valeur . Ou alors deux replace un pour le séparateur de champ un pour la décimal. Enfin je m'égare mais voila le type de problème. Même chose à l'écriture.

Enfin faut être confronté au problème pour bien comprendre. 5 ou alors c'est moi qui me fait chier depuis pas mal de temps mais à ce point là je doute )

Commentaire de marcA le 09/09/2005 08:25:27

Bonjour,

Personellement, je suis pour rechercher le symbole décimal, (Par exemple valeur 1.1).
On fait un csng ("1.1") et csng ("1,1").
On compage la longueur des deux et le plus long donne le signe décimal.
Par exemple, si csng("1.1") donne 11 (longueur 2) et csng ("1,1") donne 1,1 (longueur 3).
Ainsi, on sait que c'est la "," le séparateur décimal.
Après, pour toute entrée utilisateur, on fait un Replace (entree, ".", ",") et on a plus de problème.

On peut aussi faire une fois avec le replace (entree, ".", ",") et l'autre fois (entree, ",", ".") et le plus long est le bon. Ainsi, si l'utilisateur change son symbole décimal pendant que le programme fonctionne, le programme fonctionne toujours.

Marc Allard

Commentaire de Patrice99 le 09/09/2005 08:39:15

La plupart du temps, il suffit de lire les nombres réels en tant que string, de remplacer le séparateur décimal par le bon, puis d'utiliser les fonctions classiques de VB6 ou VBA, même dans une requête Access cela fonctionne. Cependant, il existe quand même des cas où l'on est obligé de changer à la volée le séparateur décimal dans le registre : par exemple j'utilise OWC 9 et je charge des enregistrements en une seule instruction dans le tableur OWC : hé bien je suis obligé d'utiliser le . comme séparateur décimal.

Commentaire de cuq le 09/09/2005 08:54:14

Merci Patrice99
Enfin un qui me comprend ou qui a simplement les mêmes  problèmes.

:)

Commentaire de pit1 le 09/09/2005 20:16:15

Je suis du même avis que MarcA. Il suffit d'écrire une fonction qui fait la conversion (éventuellement avec un variable statique pour la "," et une pour le ".", cela évite de tester à chaque fois la base de régistre ou avec csng quel est le séparateur des décimales).

Pas question de tripoter dans les settings locale. Que ce passe t'il avec les autres application en mémoire, que ce passe t'il si l'appli plante avant de restaurer les settings ???

Commentaire de bouv le 10/09/2005 09:10:22

Je campe toujours sur ma position et ma méthode est très proche de celle de marcA. De plus la dernière remarque de PIT1 est également à prendre en compte.

Essai donc ça :

    Dim dTest As Double
    Dim sDecimal As String
    dTest = 1 / 2
    sDecimal = Mid$(CStr(dTest), 2, 1)

A chaque fois que l'on rencontre une valeur on fait un appel de la fonction suivante :

Public Function Valider_Nombre(Valeur_A_Valider)
    Valider_Nombre = Replace(Valeur_A_Valider, ".", sDecimal)
    Valider_Nombre = Replace(Valider_Nombre, ",", sDecimal)
End Function

Essai par exemple avec :
     Msgbox Valider_Nombre(1.25)
     Msgbox Valider_Nombre(3,42)

Bonne prog
++

Commentaire de bouv le 10/09/2005 09:13:18

On peut même faire plus propre avec :

Public Function Valider_Nombre(Valeur_A_Valider)
    Select Case sDecimal
        Case "."
            Valider_Nombre = Replace(Valeur_A_Valider, ",", sDecimal)
        Case ","
            Valider_Nombre = Replace(Valeur_A_Valider, ".", sDecimal)
    End Select
End Function

Commentaire de Manolitoos le 10/09/2005 12:11:10

Bonjour à tous,

Tout d'abord je voulais te dire, Cuq, que je te comprend bien puisque j'ai eu un problème à les Paramètres Régionaux sous windows : au lieu d'avoir € comme symbole monnétaire j'avais $.

Pour le séparateur décimal je pense que la solution est celle que BruNews à écrite :
- au démarrage de ton application, tu places le séparateur en "."
- à la fermeture tu restore en ","

Le paramètre est stocké dans le base de registre, clé suivante :
HKCU/Control Panel/International
puis sous cette clé voir la valeur chaîne sDecimal.

Je pense qu'en lisant la valeur de cette clé, en la plaçant dans une variable temporaire, en paramétrant ensuite la valeur sur le "." au démarrage de ton application, serait une bonne solution.

Il te reste ensuite, à la fermeture de ton application, à restorer la clé à l'aide de cette variable temporaire.


Bon courage...

Commentaire de marcA le 12/09/2005 08:32:35

Bonjour,

Le problème en imposant le symbole décimal, c'est quand l'application plante.
Un collègue a eu un problème avec une application il y a deux semaines car l'application qui modifie les paramètres régionaux avait planté et n'avait donc pas restauré les paramètres. A moins qu'il n'y ait un système pour voir quand une application plante, c'est une technique à éviter à tout prix pour moi.

Marc Allard

Commentaire de mynyroger le 12/09/2005 08:55:32

Slt :
Confronté à ce problème, voici ma solution indépendante :

xx = votre donnée
For x = 1 to len(xx)
   if mid(x,1,1) = "." then mid(x,1,1) = ","
next

Ou inversement si vous désirez des "."

Commentaire de Renfield le 12/09/2005 09:07:56 administrateur CS

Utilise en ce cas la fonction Replace ^^

Commentaire de mynyroger le 12/09/2005 09:44:43

BJ Renfield

Bien sûr que j'emploie Replace, mais j'ai noté la fonction la plus lisible pour les débutants.

Ce site est bien pour cela non?

J'ai surtout voulu dire que le logiciel doit être indépendant, car il est possible d'utiliser simultanément plusieurs logiciels.

Le faît de modifier le registre ? salut les dégats.

Commentaire de cuq le 12/09/2005 09:58:50

Bonjour A Tous,

On l'avait dit c'est un sujet brulant. Et je pense que vous n'avez pas bien mes différents commentaires . Le problème de replace ou autres méthodes consitant à changer la "," en "." c'est dans le cas de grand traitement "milliers" de lignes à lire vous augmentez le  temps de traitement ( j'ai pas vraiment de % de temps en plus à fournir mais le test serait intéressant pour variament être plus explicit). et ces Replaces ou autres à la lecture seront aussi nécessaires à l'écriture pour "Corriger" la sortie de FORMAT. Donc encore une fois au risque de me répéter je ne présente ici que MA solution qui n'st pas LA solution mais qui dans ce cas de figure me semble la plus appropriée. LA solution avec un L et un A majuscule serait de pouvoir spécifié les paramètres juste au niveau de l'appli. J'ai testé SetLocalInfo mais sans grand succès (manque de connaisssnace) Si quequ'un peut en dire plus sur cette fonction . C'est une piste

Commentaire de BruNews le 12/09/2005 10:22:02 administrateur CS

SetLocalInfo modifie le registre, simplement elle évite de manipuler la BDR par code.

Il est très clair qu'un prog ne devrait jamais toucher aux params utilisateur mas au contraire s'adapter, il ne peut y avoir aucun doute là dessus. S'il ne le peut pas et que les temps de traitement sont cruciaux, on fait convertirr les données avant et/ou après par une dll en C et le prob est réglé à la base. Traiter des milliers de lignes en vb me semble une ineptie, ça n'a jamais été conçu pour cela.

Commentaire de cuq le 12/09/2005 11:12:22

Pardon BrNews je voulai parlé de SetThreadLocal et pas de SetLocalInfo ( la ca va je maitrise)Duex petits lien en Anglais de Microsoft  sur le problème ) Ca c'est pour celui qui ne connaitrait pas vraiment le problème . Ca donne un peu plus d'infos mais pas la solution :

Considération a prendre en compte lors de l'écriture d'un programme qui se veut international

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vbcon98/html/vbconspecialcondsiderationswhenwritinginternationalcode.asp

et

Idem mais pour la lecture et l'écriture dans les fichiers.

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vbcon98/dt_vbconSpecialCondsiderationsWhenWritingInternationalCodeC.asp

Commentaire de pit1 le 12/09/2005 16:56:25

Attention au séparateur des milliers, il peut aussi être . ou , ou espace! Un replace tout bête pourrait rendre la chaine de charactères illisibles, vu qu'il pourra contenir DEUX séparateurs de décimales ...

Commentaire de jipef le 13/09/2005 08:55:09

en debut de ton code :
  If InStr(1, CStr(CDbl(TimeValue("09:01:01"))), ",") > 0 Then
        SeparateurDecimal = "Virgule"
    Else
        SeparateurDecimal = "POINT"
    End If
ensuite dans ton code tu utilise cdouble("123,45")
'===================================
Public Function Cdouble(Chaine As String) As Double
'===================================
    Dim Pos%
If Chaine = "" Then
    Cdouble = 0
    Exit Function
End If

    If UCase(SeparateurDecimal) = UCase("virgule") Or UCase(SeparateurDecimal) = "," Then
        Pos = InStr(1, Chaine, ",")
        If Pos <> 0 Then
            ' rien faire c'est virgule pour virgule !!!
            Cdouble = CDbl(Chaine)
            Exit Function
        Else
            Pos = InStr(1, Chaine, ".")
            If Pos <> 0 Then
                Mid(Chaine, Pos, 1) = ","
            End If
        End If
    Else    ' point décimal
        Pos = InStr(1, Chaine, ",")
        If Pos <> 0 Then    ' VIRGULE 0 CHANGER PAR POINT
            Mid(Chaine, Pos, 1) = "."
        Else
        ' ne rien faire POINT pour POINT
            Cdouble = CDbl(Chaine)
            Exit Function
        End If
    End If
    ' maintenant on peut convertir !! si > 0
    If Val(Chaine) > 0 Then
        On Error GoTo SORTIE
        Cdouble = CDbl(Chaine)
    Else
        Cdouble = 0
    End If
    Exit Function
SORTIE:
    Cdouble = 0
End Function

Pour la saisie tu testes et tu remplace la touche "." par ","

CQFD
signe Jipef

Commentaire de wisjo le 15/09/2005 17:46:27

C'est bien joli les "replace" mais ça ne marche pas pour les fonctions du genre "importXML" qui s'appuie sur les variables d'environnement.

ex: valeur dans le fichier xml: 0.30 -> insertion dans une table sur un PC avec virgule comme séparateur décimal: 30

Commentaire de tawass le 20/04/2006 18:48:46

Ma solution reste simple et doit pouvoir passer partout: je
scan ma chaine de caractères (caractère par caractère) et je remplace chaque virgule par un point à la reconstruction de la nouvelle chaine.

For i = 1 To Len(chaine_de_caracteres)
    test = Mid(chaine_de_caracteres, i, 1)

    If test = "," Then
        test = "."
    End If

    chaine_de_caracteres = chaine_de_caracteres + test
Next

Commentaire de Renfield le 20/04/2006 19:41:29 administrateur CS

tu peux utiliser la fonction Replace...

ta boucle est fausse, elle concatène a chaine_de_caracteres, une version ou les virgules sont remplacées par un point...

ex:
12,4512.45

Commentaire de tawass le 25/04/2006 09:53:53

En effet Renfield, c'est plutôt:
"chaine_de_caracteres2 = chaine_de_caracteres2 + test"

A ce moment là on est bon!

Commentaire de mynyroger le 25/04/2006 10:12:16

On revient à ce que j'ai écrit le 25/09/2005 !

Commentaire de azerty58220 le 12/02/2007 10:57:16

Application.International(xlDecimalSeparator)

est aussi bien efficace...

Commentaire de Patrice99 le 17/02/2007 09:25:04

Pour info, Application.International(xlDecimalSeparator) c'est du VBA Excel.

Commentaire de peug le 16/07/2009 10:22:38

Salut,
Tenez, comme ca marche très bien et c'est rapide:

Public Function fctVal(ByVal Chaine As String) As Double

    If Trim(Chaine) = "" Then
        fctVal = 0
        Exit Function
    End If

    Dim i As Long
    Dim j As Long
    i = InStrRev(Chaine, ".")
    j = InStrRev(Chaine, ",")
    If j > i Then
        i = j
    End If

    Dim lD As Long
    lD = Val(Mid(Chaine, i + 1))
    
    Chaine = Mid$(Chaine, 1, i - 1)
    
    Dim strTmp As String
    Dim charTmp As String

    For i = 1 To Len(Chaine)
        charTmp = Mid(Chaine, i, 1)
        If Asc(charTmp) >= 48 And Asc(charTmp) <= 57 Then
            strTmp = strTmp & charTmp
        ElseIf charTmp = "+" Or charTmp = "-" Then
            ' Le signe...
            strTmp = strTmp & charTmp
        ElseIf charTmp = " " Or charTmp = "." Or charTmp = "," Then
        End If
    Next i

    fctVal = Val(strTmp) & "." & lD

End Function

Commentaire de Renfield le 16/07/2009 10:56:43 administrateur CS

possible également :

Public Function fctVal(ByVal Chaine As String) As Double
    If IsNumeric(Chaine) Then
        fctVal = CDbl(Chaine)
    Else
        fctVal = Val(Chaine)
    End If
End Function


a lire:
http://blogs.codes-sources.com/renfield/archive/2009/04/14/param-tres-r-gionnaux-en-g-n-ral-et-avec-vb6.aspx

Commentaire de peug le 16/07/2009 11:03:43

Salut Renfiedl,
mais si le séparateur de millier est le point, ca marche pas dans ton cas. Ex : "123.456,7" renvoi  123.456

D'où dans ma fonction les "InStrRev"

Commentaire de Renfield le 16/07/2009 11:11:30 administrateur CS

j'avoue ne pas saisir.
Si la chaine est conforme aux parametres regionnaux du poste, IsNumeric la reconnaitra, quels que soient les parametres utilisés.

Sinon, on a affaire a une chaine formatée en utilisant le format international, et Val s'en sortira haut la main.

La seule alternative est une donnée mal formée, compte tenu des parametres du poste. Dans ce cas, ton code la trafique et tente d'en récupérer une valeur correcte.
Ce genre de manipulation est à éviter et met à jour une mauvaise conception a un endroit où a un autre.

Comme je le dit dans mon article, on doit toujours transmettre les données de manière internationale, sauf si le destinataire est un humain dont on peut présumer des parametres régionnaux. Auquel cas, on formatte la donnée de manière à ce qu'elle lui paraisse lisible et non ambigüe.

Commentaire de peug le 16/07/2009 11:16:18

oui ok pour IsNumeric c'est juste mais j'ai lu ton article mais j'ai été confronté à un problème similaire où un client a envoyé son fichier data d'un vieux logiciel où le stockage n'était pas correcte (comme tu le relate d'ailleurs) et boom patatrac, en France,  "123.456,7" renvoyait  123.456
D'où comme tu le soulignes, d'enregistrer de manière internationale !

Commentaire de Renfield le 16/07/2009 11:19:25 administrateur CS

sûr qu'il y a souvent un gouffre entre les bonnes moeurs et ce qui est fait dans le monde reel ^^

Commentaire de Patrice99 le 16/07/2009 12:01:15

Val utilise toujours le point quel que soit le séparateur décimal en vigueur : donc normalement le code de renfiled devrait fonctionner en france et dans les pays anglophones... sauf si on précise un séparateur décimal différent de virgule et point (rare !) et qu'on demande de traiter une chaine avec une virgule par exemple.
La solution est de lire le séparateur en vigueur, de regarder si elle est présente dans la chaine, et si oui de la remplacer par le point puis d'utiliser Val. Attention, la fonction IsNumeric peut être très longue : mieux vaut remplacer systématiquement le séparateur par le point et d'utiliser Val.

 Ajouter un commentaire


Discussions en rapport avec ce code source dans le forum

Séparateur Décimal URGENT!!!!! [ par xavier77 ] Salut à tous, J'utilise VB5 pour développer et Btrieve pour stocker mes données. Lors de l'exécution de mon prog, j'ai souvent des Erreur 13 lorsque j séparateur décimal et base de registre [ par bl5730 ] Dans un programme Excel (VBA) lorsque je change la base de registre pour modifier le séparateur décimal, le changement ne prend lieu qu'au redémarrage récupérer le séparateur décimal [ par yann1 ] Je cherche à réculérer le séparateur décimal de la machine (celui que l'on met dans les paramètres réginaux, format nombres)Merci Pb avec le séparateur décimal des paramètres régionaux [ par gagagogos ] Ayant crée un exe faisant aditions et soustraction et mettant dans un fichier mémoire le résultat.Pourquoi lorsque j'installe le programme sur un autr API Séparateur décimal [ par xavier77 ] salut, J'aimerais savoir s'il est possible de changer le séparateur décimal. J'arrive à le récupérer avec les API GetSystemDefaultLCID et GetUserLocal séparateur décimal entre vba et access [ par seblh ] Bonjour, j'ai un petit problème entre access et vba.En vba, j'éxécute une requête de mise à jour ou alors d'insertion d'enregistrement. Le problème c' NT4: Séparateur Décimal session fermée [ par webcyril ] Hello,Sous NT4, j'ai une application VB6 qui fonctionne avec séparateur décimal . (point) et shortdate 'dd/mm/yyyy'.Session ouverte sous mon compte NT Récupération langue Catia v5 et séparateur décimal [ par haiduc ] Bonjour, J'ai besoin de récupérer la langue de l'interface (menus, messages, etc.) du logiciel Catia v5. Je n'arrive pas à la trouver... De même, j' Séparateur de décimal sous excell [ par olivier857 ] Salut je voudrais savoir si il est possible sur excell de changer le s&#233;parateur de d&#233;cimal "," en "." sur un classeur uniquement. Je voudrai Séparateur décimal [ par xavier77 ] Salut, Alors, voila mon petit soucis : dans une fonction, je fait des calculs avec des coef "en dure" comme par exemple 1.2 Sur mon PC, ca marche, pas


Nos sponsors


Sondage...

CalendriCode

Février 2012
LMMJVSD
  12345
6789101112
13141516171819
20212223242526
272829    

Consulter la suite du CalendriCode

Photothèque

 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 3,260 sec (3)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales