Affichage curieux

un internaute

XLDnaute Impliqué
Bonsoir le forum,
Il me semble avoir rencontré ce problème mais il y a longtemps.
Dans une cellule je suis à 0.00 €
Si je fait Format => Cellule => Standard ça m'affiche -1.56319E-13
Merci pour vos éventuels retours
Bonne fin de soirée
 

Dranreb

XLDnaute Barbatruc
Bonjour.
Je suppose qu'il doit y avoir des différences entre Excel 2016 et Excel 2010.
Et des bogues Microsoft.
Chez moi ma fonction TypeDon donne bien "Currency" sur des cellules dont les valeurs sont de ce type de donnée. Mais il s'en faut de peu dans une formule ou même une expression VBA pour qu'il reconvertisse tout les termes en Double avant de faire le calcul.
J'ignore pourquoi en mettant -0 en fin de formule ça change le résultat, et j'ignore pourquoi il trouve une différence entre D20 et B20. Je soupçonne vaguement que l'une est évaluée en Currency, l'autre en double et seulement après convertie en Currency pour l'attribuer comme valeur à la cellule, mais j'ignore pourquoi une autre cellule calculant en Double prend la valeur évaluée en Double au lieu de la valeur Currency de la cellule.
Je crois qu'il faut en conclure qu'il vaut mieux éviter des calculs trop compliqués sur les Currency et se contenter principalement de simples sommes. Là on est sûr avec les Currency de ne pas cumuler des erreurs dues aux représentations internes imparfaites.
 

eriiic

XLDnaute Barbatruc
Je vais paraitre insistant :)mais :
Chez moi ma fonction TypeDon donne bien "Currency"
pour moi avec TypeName(Cel.Value) c'est vba qui converti en currency (du fait du format monétaire) le double présent dans la cellule .

Je crois qu'il faut en conclure qu'il vaut mieux éviter des calculs trop compliqués sur les Currency et se contenter principalement de simples sommes. Là on est sûr avec les Currency de ne pas cumuler des erreurs dues aux représentations
Justement, on est sur une simple somme et ce n'est pas ce que montre B20.
Si on approfondi on s'aperçoit que la perte apparait sur B18, sensée être currency et donc avec 4 décimales fixes. Hors :
=B17-ARRONDI(B17;4) = 0
=B18-ARRONDI(B18;4) = -1.7764E-15

Ca serait intéressant d'avoir des avis tiers sur l'interprétation de ces résultats.
Pour l'instant, de mon point de vue actuel, la seule explication simple qui les rend tous cohérents reste cellule=Double

Edit : finalement un exemple encore plus simple.
Je saisis 0.000015 et met le format monétaire.
J'ai quoi dans ma cellule ?
0.000015 et ça ne peut être qu'un Double, un Currency donnerait 0.
 
Dernière édition:

mapomme

XLDnaute Barbatruc
Supporter XLD
Bonjour tous :),

(...) Ca serait intéressant d'avoir des avis tiers sur l'interprétation de ces résultats. (...)

Pour tout vous dire, quand je reçois l'avis du virement de la paye, je compte les chiffres avant la virgule et pas ceux après la virgule :p.

Sinon je ne vois pas bien comment on peut trancher :
  1. Est-ce que Excel stocke un nombre selon le format d'affichage ?
  2. Est-ce que Excel effectue les calculs d'une façon différente selon le format d'affichage ?
C'est encore plus flagrant avec des Range au format Date qui disposent de deux propriétés Value et Value2 qui ne sont pas égales. Les Range au format monétaire ont la même caractéristique. Voir le fichier joint (bouton Test).

AMHA, pour trancher, il faudrait savoir ce que les programmeurs Excel et VBA ont pondu comme code au sein d'Excel. Je suis assez enclin à répondre par OUI aux deux questions.
 

Pièces jointes

  • mapomme- type excel VBA- v1.xlsm
    16.8 KB · Affichages: 29

Dranreb

XLDnaute Barbatruc
pour moi avec TypeName(Cel.Value) c'est vba qui converti en currency (du fait du format monétaire) le double présent dans la cellule .
Alors mettons un format standard à 2 cellule puis des valeurs dont la 2ième en Currency et voyons le type des valeurs de cellules

j'ai fait déjà l'essai comme j'ai dit, mais j'ai vu qu' Excel mettait d'office un format monétaire quand on affectait un Currency. Alors j'ai remis un format Standard derrière, et là surprise, la valeur repasse en Double. Ce serais bien la première fois que je verrais un changement de format de cellule changer sa valeur. Alors je suis perplexe.
VB:
Sub TEST()
With ActiveSheet
   .[A1:A2].NumberFormat = "General"
   .[A1].Value = 123
   .[A2].Value = 123@
   MsgBox "TypeName([A1].value) = """ & TypeName([A1].Value) & """," & vbLf _
      & "TypeName([A2].value) = """ & TypeName([A2].Value) & """."
   .[A1:A2].NumberFormat = "General"
   MsgBox "TypeName([A1].value) = """ & TypeName([A1].Value) & """," & vbLf _
      & "TypeName([A2].value) = """ & TypeName([A2].Value) & """."
   End With
End Sub
En tout cas ce n'est certainement pas VBA qui transforme un Double en Currency, ce serait plutôt Excel qui se contenterait de convertir et restituer en Currency, lorsque elle porte un format monétaire, une valeur de cellules effectivement toujours enregistrée en Double. Sagouins … Microsoft :mad:

finalement un exemple encore plus simple.
Je saisis 0.000015 et met le format monétaire.
J'ai quoi dans ma cellule ?
0.000015 et ça ne peut être qu'un Double, un Currency donnerait 0.
Ça ç’aurait été tout à fait normal en soit, que la valeur reste Double si elle était déjà double avant qu'on ne change le format. Jusqu'à présent je n'avais jamais vu un changement de format de cellule changer sa valeur.
Ce n'est pas par exemple parce qu'on met un format de date à une cellule contenant un texte représentant une date que sa valeur devient une date. Elle demeure le texte qu'elle était. Pour qu'elle devienne effectivement une date il faut revalider la cellule.
Là ou ça ne va plus c'est que pour les Currency Excel triche: du seul fait qu'on met un format monétaire il renverra dès lors un Currency comme propriété Value d'un Range la représentant, alors que sa valeur est restée Double. C'est suspect, ça donne l'impression qu'il stocke toujours les valeurs en Double. Mais, qui sait, c'est peut être pire que ça…

De plus en plus bizarre :
VB:
Sub TEST()
With ActiveSheet
   .[A1:A2].NumberFormat = "General"
   .[A1].Value = 123
   .[A2].Value = 123@
   MsgBox Audit(.[A1]) & vbLf & Audit(.[A2])
   .[A1:A2].NumberFormat = "General"
   MsgBox Audit(.[A1]) & vbLf & Audit(.[A2])
   .[A1:A2].NumberFormat = "0.00 €"
   MsgBox Audit(.[A1]) & vbLf & Audit(.[A2])
   .[A1:A2].NumberFormat = "#,##0.00 $"
   MsgBox Audit(.[A1]) & vbLf & Audit(.[A2])
   End With
End Sub
Private Function Audit(ByVal Cel As Range) As String
Audit = Cel.Address(False, False) & ": Format """ & Cel.NumberFormat & """, Type: " & TypeName(Cel.Value) & ", Valeur: " & Cel.Value
End Function
 
Dernière édition:

mapomme

XLDnaute Barbatruc
Supporter XLD
Bonsoir Dranreb, le forum,

(...) Alors je suis perplexe. (...) Mais, qui sait, c'est peut être pire que ça… (...)

ça me conforte dans mon opinion. Nous ne voyons que les entrées et sorties de la programmation Excel et VBA. Tant qu'on ne connaîtra pas la boite noire de cette programmation, nous ne pourrons que constater et supputer.

La seule chose qui me semble certain : c'est la dualité des nombres au format monétaire ou date (de par la différence des valeurs de Value et Value2). Si c'est deux valeurs existent, c'est que MS en a ressenti l'utilité.
 
Dernière édition:

Dranreb

XLDnaute Barbatruc
Bonjour.
Difficile de savoir ce qu'il en est. Mais je partirai désormais des principes suivants:
1) – Excel enregistre effectivement les valeurs constantes numériques tapées au clavier comme valeurs de cellules Currency ou Double selon que le format de nombre préétablit de la cellule est ou non monétaire (un changement après coup du format ne change plus ce type).
2) – Les valeurs de cellules portant une formule sont stockée sous le type déterminé par son calcul quel que soit leur format. Pour des montants, éviter donc les fonctions telles que Arrondi et sans doute bien d'autres, qui rendent un résultat Double.
3) – Le type de la propriété Value renvoyée d'une cellule est Currency ou Double selon que le format préétablit de la cellule est ou non monétaire, et cela sans tenir aucun compte du type de donnée sous lequel elle est réellement stockée, que ce soit une constante ou calculé par formule.
4) – Le type de donnée affecté à la propriété Value d'une cellule est respecté pour son stockage, mais Excel se réserve le droit de corriger son format de telle sorte qu'il resservirait la valeur du même type en vertu du point 3.
 
Dernière édition:

eriiic

XLDnaute Barbatruc
Bonjour,

Tu as fait la complète mapomme ;-)
Bonne idée.
Ca me conforte dans l'idée qu'il stocke tout en double, avec des interprétation différentes en vba pour typer au mieux selon le format.

tests Dranreb
En tout cas ce n'est certainement pas VBA qui transforme un Double en Currency
Pourquoi pas ?
En fait je pense qu'il ne transforme pas, il type au moment de la lecture

Alors j'ai remis un format Standard derrière, et là surprise, la valeur repasse en Double. Ce serais bien la première fois que je verrais un changement de format de cellule changer sa valeur.
Pour moi le format quel qu'il soit ne change que l'affichage (en aucun cas la valeur , tu voulais sans doute dire le type), et l'interprétation de la valeur par vba pour la typer, comme dit au-dessus.
Avec ce point de vue, les résultats de ton test 1 s'expliquent.
Ceux du test 2 aussi.
J'ai eu des Double sur 2nd test .[A1:A2].NumberFormat = "0.00 €", mais bizarrement en consultant le format j'avais un format personnalisé 0.00\ \€
Ca suffit à le perdre et qu'il ne détecte plus le format comme monétaire, gênant en effet.
On se demande pourquoi il a été coller 2 \ dans le format (?!?). La suppression du dernier suffit à ce qu'il reconnaisse à nouveau un currency.

Si c'est deux valeurs existent, c'est que MS en a ressenti l'utilité.
J'ai dans l'idée que la vraie et unique valeur dans la cellule est .value2 (oui, je prêche pour ma paroisse ;-) ) qu'il conserve tout le temps et nous permet d'utiliser, et qu'il fabrique .value et .text en fonction du contexte (format, largeur de colonne)

suite...
Mapomme, j'ai élargi ton test avec des variables de tous les types :
VB:
    Dim b As Boolean, i As Integer, l As Long, s As Single, d As Variant
    b = 1: i = 1: l = 1: s = 1: d = CDec("12345678901234567890")
    '...
Tout est converti et récupéré (et donc je suppose stocké) en Double, sauf Boolean qu'on arrive à avoir en type booléen.
(et encore, sans doute que cette valeur VRAI est stockée en numérique -1 et pourquoi faire une exception à Double, il a .formula=True ou autre chose pour typer correctement).

L'idée initiale était de valider ou non l'existence des currency sur feuille, je ne vois rien qui peut confirmer leur existence.
On ne peut pas compter sur le format monétaire pour s'affranchir des pertes de précision des flottants.
eric

edit: j'avais démarré la rédaction avant ta dernière intervention Dranreb.
Je ne suis toujours pas d'accord avec le 2), ce n'est pas ce que j'ai sous les yeux
 
Dernière édition:

Dranreb

XLDnaute Barbatruc
Ne pas confondre VBA proprement dit avec une propriété de l'objet Range de la bibliothèque Excel. Quand on détermine TypeName(Cel.Value), VBA n'a pas à sa disposition le format de la cellule. C'est donc le code de la bibliothèque Excel qui détermine en amont de cela le type de donnée de cette propriété et non VBA.
 

eriiic

XLDnaute Barbatruc
Pas de soucis pour moi que ce soit fait en amont, au moment de la modif de la feuille c'est le plus logique.

Mais recentrons sur le débat du type de stockage des valeurs sur une feuille.
Les valeurs de cellules portant une formule sont stockée sous le type déterminé par son calcul quel que soit leur format.
non
et ...
Pour des montants, éviter donc les fonctions telles que Arrondi et sans doute bien d'autres, qui rendent un résultat Double.
non plus.

Enfin quoi...
Met A1 en monétaire et en A2: =A1=0, tu lis VRAI
Saisis maintenant 0.000001 en A1, tu lis FAUX, il conserve bien cette valeur.
0.000001 n'existe pas en Currency, c'est 0.
A1 ne peut être qu'un Double (un Single à la rigueur), format monétaire ou non.
Ou alors ajoute des règles en plus d'interdire toute fonction, celle d'interdire toute saisie à plus de 4 décimales entre autre.

Maintenant j'en suis sûr à 99.99% :
- toutes les valeurs sont Double sur la feuille.
- un format modifie l'affichage. Aucune exception, même pour le format monétaire.
 

Dranreb

XLDnaute Barbatruc
Effectivement si on saisit plus de 4 décimales il stocke aussi la valeur en Double.
Il est de fait impossible de savoir sous quelle type de donnée est réellement stockée une valeur de cellule, quand elle n'est pas manifestement Double. Mais je ne vois pas pourquoi Excel ne la stockerait pas en Currency quand c'est possible, puisqu'il est de toute façon obligé de tenir compte de ce type de donnée quand on travaille avec la propriété Value d'une cellule en entrée ou en sortie. C'est le seul argument qui me reste, mais je crois qu'on ne saura jamais la vérité.

La valeur VRAI semble stockée comme 1 et non -1 comme le montre la formule =N(VRAI)
Elle est restituée en Value comme type Boolean =True, qui à pourtant, lui, comme représentation interne -1 (tous les bits à 1, ce qui permet, en VBA seulement, de combiner des Long, Integer, Byte et Boolean, bit par bit, par les opérateurs logiques).
 

eriiic

XLDnaute Barbatruc
Bah, ma conviction est faite maintenant. Jusqu'à preuve du contraire... :)
Je voulais éclairer ce point qui ne semblait pas coller à des constats.
Il me faudrait un contre-exemple en béton pour me faire changer d'avis ;-)
Quand il y a plusieurs explications à un problème, la plus simple est plus souvent la bonne, et de loin.

Le format monétaire n'existait pas sur les premières version d'excel.
J'ai l'impression qu'il a été ajouté a minima juste pour respecter les règles d'écritures comptables selon les pays et permettre l'affichage de la monnaie et c'est tout.
Si on veut la précision comptable, c'est soit avec des arrondi(), soit en vba avec currency.
 

Dranreb

XLDnaute Barbatruc
Bonjour.
Vous m'avez induit une forte suspicion sur l’authenticité du stockage sous forme de Currency des valeur de cellules, au point que je suis maintenant convaincu à 99% que vous avez raison, et je vous en remercie.
J'ai du nouveau: les Date aussi semblent être du flan ! Ce serait tout du Double également, et la restitution d'un .Value en type Date dépendrait seulement de la présence d'un format de date !
Reste à savoir pourquoi je n'ai pas réussi à mettre en évidence des erreurs de précision dans des cumuls de valeurs décimales (Même si tout ça c'est toujours stocké en Double, les calculs seraient-ils quand même, eux, effectués en Currency chaque fois que c'est possible ?… mystère… En tout cas on ne sait plus du tout comment Microsoft triche avec tout !)
 

eriiic

XLDnaute Barbatruc
Bonjour,

oui, pour moi tout ce qui est numérique est stocké en Double sur une feuille.
Difficile de montrer quoi que ce soit via vba puisqu'effectivement il va convertir en Variant/Double, Variant/Date ou Variant/Currency selon les cellules.

Pour les cellules en monétaires les mêmes erreurs se produisent, même si elles sont masquées.
Un exemple pour tenter de le démontrer en restant sur feuille.
2017-10-06_17-56-30.png

eric
 

Pièces jointes

  • Classeur1.xlsx
    545.7 KB · Affichages: 44

Discussions similaires

Statistiques des forums

Discussions
312 185
Messages
2 086 016
Membres
103 093
dernier inscrit
Molinari