Excel vba

Résolu
Bonjour,
J'ai un problème au niveau d'un calcul dans ma macro.
Mes nombres à additionner sont tous des décimaux à 2 chiffres après la virgule et pourtant j'obtiens un résultat avec jusqu'à 8 chiffres apères la virgule.
Grâce au débugger, j'ai trouvé à partir de quelle ligne le problème apparaît (et continue par la suite avec les autres lignes).
Voilà un exemple de ce que je peux avoir.
Ici par exemple, le bug ce produit à partir de la ligne 9.
157,59
80,34
110,21
25,34
110,21
32,45
46,58
41,16
94,76 <---
162,74
236,9
49,88
22,97
29,56
46,58

Voila mon code :
For Ligne = 1 To DerniereLigne
    For i = 0 To UBound(ListePays)
        If ListePays(i) = Workbooks(FichierUtiliseCA).Sheets(Onglet).Cells(Ligne, ColonnePays) Then
            TableauCAPays(i) = TableauCAPays(i) + Workbooks(FichierUtiliseCA).Sheets(Onglet).Cells(Ligne, ColonneCATotal)
        End If
    Next i


Merci,
Caféi.

10 réponses

  1. Je vois que ma question à fait fureur !
    Je vais utiliser Double.
    Merci beaucoup pour toutes les réponses que vous m'avez apporté !
    1. Contributeur
      Tu a fait la bonne options.
      A+
    2. Pour éviter ce genre de désagrément il suffit simplement d'utiliser systématiquement :
      Option Explicit
      en début de module
  2. Re,

    Ce n'est pas une bizarrerie mais un problème de précision mathématique.
    Les variables représentées par des nombres à virgule flottante sont des
    approximations
    plus ou moins précises.

    Le type Single utilise 32 bits pour représenter le nombre :
    - 1 bit de signe, 8 bits pour l'exposant et 23 bits pour la mantisse
    - soit un nombre décimal avec 7 chiffres significatifs

    Le type Double utilise 64 bits pour représenter le nombre :
    - 1 bit de signe, 11 bits pour l'exposant et 52 bits pour la mantisse
    - soit un nombre décimal avec 16 chiffres significatifs

    Pour prendre l'exemple actuel 1247,27 s'écrit :

    En Single :
    01000100100110111110100010100011
    soit :
    0 10001001 00110111110100010100011

    signe : 0
    = +

    exposant : 10001001
    = 137 - 127
    = 10

    mantisse : [1,]00110111110100010100011
    = 1 + 0/2 + 0/4 + 1/8 + 1/16 + 0/32 + 1/64 + ....
    = 1,2180370

    résultat : + 1,2180370 * 2 ^ 10
    = 1247,269888

    En Double :
    0100000010010011011111010001010001111010111000010100011110101110
    soit :
    0 10000001001 0011011111010001010001111010111000010100011110101110

    signe : 0
    = +

    exposant : 10000001001
    = 1033 - 1023
    = 10

    mantisse : [1,]0011011111010001010001111010111000010100011110101110
    = 1 + 0/2 + 0/4 + 1/8 + 1/16 + 0/32 + 1/64 + ....
    = 1,2180371093750000

    résultat : + 1,218037109375 * 2 ^ 10
    = 1247,27

    CQFD
    1. Contributeur
      Patrice... n'essaye pas d'en faire plus qu'il ne faut..
      Les constatations sont là.

      A+
  3. Contributeur
    Ont diraient que ça avance, :-)
    Patrice : Avec Single tu a bien en affichage 1247,2699 mais si tu sélectionne la cellule tu a dans la barre des formules.. 1247,26989746093 !!
    Avec un variant et un DOUBLE, 1247,27
    C'est encore une des bizarrerie d'excel, un double devrait donner au moins autant de décimales qu'un single or c'est pas le cas.
    Caféi : Il te reste 2 solutions.
    1°) Déclarer ton tableau en Double
    2°) Employer Round(), et si tu veux une fonction Round() avec disposition européenne tu peu employer la fonction de Patrice
    A+
    L'expérience instruit plus sûrement que le conseil. (André Gide)
    Si tu te cognes à un pot et que ça sonne creux, c'est pas forcément le pot qui est vide. ;-)(Confucius)
    1. Contributeur
      Re,
      Ont est (je pense) à côté du sujet, les additions ne génére jamais plus de décimales que celles des nombres additionnés.
      En faisant simplement ...
      For li = 1 To 15
        tots = tots + Cells(li, 1)
      Next li
      Range("A21").Value = tots

      ont optient 1247,27
      Non, le probléme est certainement dans ce que contient déjà TableauCAPays(i)
      Ou notre ami Caféi nous cache des choses :-D
      1. C'est probablement un problème de déclaration, par exemple si tu déclare :

        Dim TableauCAPays(1) As Single

        le résultat est 1247,2699
    2. Bonjour,

      La solution de ccm81 me semble être la bonne : il suffit d'utiliser le type Double pour TableauCAPays :

      Dim TableauCAPays(n) as double

      Par exemple si on place tes valeurs de A1 à A15, le code suivant fonctionne parfaitement :

      Sub test()
      
      Dim TableauCAPays(1) As Double
      Dim ctr As Integer
      
      For ctr = 1 To 15
      
        TableauCAPays(1) = TableauCAPays(1) + Cells(ctr, 1).Value
      
      Next ctr
      
      Cells(16, 2).Value = TableauCAPays(1)
      
      End Sub
      


      Patrice
      1. > re

        j'ai essayé ça en travaillant avec le type double, ça marche mais peut etre jusqu'à un certain point ....
        A1:A16 formatée a 2 ch decimaux
        A16 est le total calculé par excel
        A21 n'est pas formatée et ça donne le même resultat

        Private Sub CommandButton1_Click()   
        Dim cc s Long   
        Dim cs As Double   
        Dim tots As Double   
        Dim tot As Long   
        tot = 0   
        For li = 1 To 15   
          cs = Cells(li, 1)   
          cc = Int(Round(100 * cs, 2))   
          tot = tot + cc   
        Next li   
        tots = Round(tot / 100, 2)   
        Range("A21").Value = tots   
        End Sub


        bonne suite
        1. Contributeur
          Bonjour,
          d'accord si format de cellue = 2 décimales, mais pas valable si.. non.
          Reste toujour un nombre de décimales maxi.
          A+
        2. > lermitte222
          dans ma feuille A21 (la somme vba) est formatée "Normal"
      2. Contributeur
        Bonjour Ccm,
        Malheureusement, la solution que tu préconise ne donnerra pas de résultat, c'est un "défaut" d'excel et des MP, rien à faire si ce n'est Round().
        Mais bon... je peu avoir manquer un escalier.
        Il y a aussi la configuration des cellues avec 2 déc.
        A+
        L'expérience instruit plus sûrement que le conseil. (André Gide)
        Si tu te cognes à un pot et que ça sonne creux, c'est pas forcément le pot qui est vide. ;-)(Confucius)
        1. bonjour
          es tu sur que le nombre qui bugge n'est pas un arrondi a 2ch decimaux?
          sinon peut être puisque tes nombres ont tous 2 ch decimaux
          1. les x100
          2. les tranformer en entier
          3. faire la somme
          4. la diviser par 100
          bon courage
          1. Contributeur
            Bonjour,
            Rien à faire pour y remédier, inhérant à Excel. Tu peu employer Round().
            A+