Message de Philippe Allart date 2007-04-14 14:20 :
Puisque j'ai posté le message, je me dois de faire part de mes avancées au
fur et à mesure. Voici la séquence qui met en évidence le bug, de manière
indiscutable:
Sub f1
f2(16.50) ' on part d'un valeur numérique
End Sub
sub f2(v2 as string)
' la valeur est convertie en chaine,
' avec une virgule pour séparateur
f3(v2)
end sub
sub f3(v3 as double)
' la conversion en double demande un
' point pour séparateur => tronquage
msgBox(v3)
end sub
Exact, on peut le metre en évidence plus simplement:
dim d as double, s as string
s = 16.50 ' conversion double => string
d = s ' conversion string => double
print s, d
Notons que print (ou Msgbox) implique une conversion implicite de la
valeur de d en string.
Il y a dissymétrie dans les conversions implicites
nombre => chaîne
et
chaîne => nombre.
Exact. Cela existe aussi depuis les versions 1.x
La conversion implicite double => string utilise le séparateur décimal
de la variante de langue indiquée dans le panneau Outils > Options >
Paramètres linguistiques > Environnement linguistique
La conversion implicite string => double interprète la chaîne en
considérant toujours que le séparateur décimal est un point, comme dans
une instruction Basic.
La seule manière que j'ai trouvée de franchir le tunnel est la suivante:
Sub f1
f2(str(16.50))
End Sub
sub f2(v2 as string)
f3(Val(v2))
end sub
sub f3(v3 as double)
msgBox(v3)
end sub
A mon avis le problème est d'abord une mauvaise conception du programme.
Il faut faire attention aux conversions implicites, et éviter les
conversions inutiles.
Si le nombre est reçu de l'utilisateur, un contrôle numérique permet
d'obtenir le nombre, et non pas la chaîne.
Si on manipule des nombres on doit d'abord convertir la chaîne reçue
en nombre et n'avoir plus que des variables et arguments du type
numérique nécessaire aux calculs.
Si la routine appelée est censée manipuler des chaînes c'est
l'appelant qui devrait convertir sa valeur en chaîne et transmettre
cette chaîne en argument.
Str et Val fonctionnent de manière parfaitement symétrique. Val est
obligatoire, et ne peut être remplacé par CDbl qui renvoie n'importe quoi.
Chaque routine de conversion : implicite, CDbl, Val, a ses propres
particularités. Exemple :
dim d as double, s as string, v as variant
s = "123 4 56.78"
d = s ' conversion implicite
v = Val(s) ' conversion explicite
print v, typeName(v), d
L'espace est non significatif pour Val, alors qu'il indique la fin du
nombre pour la conversion implicite. CDbl déclenche une erreur s'il
trouve un espace.
La combinaison de Str et Val ne donne pas une fonction identité. Preuve:
print "resultat" & Str(Val("+ 123, 4,,56.78"))
Str affiche un espace devant un nombre positif
Val ignore les espaces et les virgules (supposées être des séparateurs
de milliers), et utilise le point décimal, quelle que soit la valeur de
l'Environnement linguistique.
CDbl tient compte de l'Environnement linguistique:
d = CDbl("123,456")
print d
donne une valeur 123,4565 en Français(France) et 123 en Anglais(USA).
D'autre part, CDbl n'accepte pas le caractère + devant le nombre.
CDbl ne renvoie pas n'importe quoi mais peut surprendre:
d = CDbl("1.7")
print Str(d), CDate(d)
Le CDbl a converti l'argument en : 39264. En fait CDbl commence par
chercher si l'argument chaîne représente une date. Ici il trouve la date
Janvier 2007 et convertit cette date de jour en double. A cause de cette
bizarrerie je pense qu'il faut s'abstenir d'utiliser CDbl pour convertir
une chaîne pouvant contenir un nombre avec décimales.
Tous ces comportements existent dans les versions précédentes
d'OpenOffice, ce qui fait qu'ils ne devraient pas être corrigés à cause
de la compatibilité.
Par contre j'ai trouvé une différence entre la version 1.1.5 et les
versions 2.1 / 2.2
d = CDbl("123 456")
est accepté en version 1.1.5, donnant la valeur 123456
En version 2.1 et 2.2 j'obtiens un message d'erreur "Argument incompatible".
A noter aussi:
- l'Issue 70236 montre l'influence d'une variable d'environnement du
système d'exploitation sur le comportement de CDbl
- l'Issue 64746 relève une bogue quand on passe une variable typée à une
routine dont l'argument est déclaré Variant, et que la routine modifie
la variable.
Bonne journée
Bernard
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]