![]() |
|
Forum
|
|
|
#1 (permalink) |
|
XLDnaute Barbatruc
Date d'inscription: février 2005
Messages: 3 099
|
Bonjour à tous et toutes
Pour mon 886ème post du Forum XLD New Generation ce sera ma première question ! En fait je me trouve confronté à une incohérence de calcul avec la fonction Excel 'ARRONDI' et la même à travers VBA. Pour mieux figurer mon problème, j'ai mis en fichier joint les montants et les dates respectives pour ce calculs avec les Formules Excel comparées à celles rédigée en VBA... Lors de l'utilisation de 'ROUND' en VBA j'ai une erreur de calcul. Quelqu'un aurait-il déjà été confronté à un truc de ce genre ? Par avance merci @+Thierry [file name=VBA-Round-Wrong-Calculation_20050510160656.zip size=8261]http://www.excel-downloads.com/components/com_simpleboard/uploaded/files/VBA-Round-Wrong-Calculation_20050510160656.zip[/file] |
|
|
|
| ANNONCES | |||
|
|
|
|
#2 (permalink) |
|
XLDnaute Barbatruc
Date d'inscription: février 2005
Messages: 3 755
|
bonjour cher Thierry
effectivement c'est curieux Round((BaseAmount * InterestRate) / 100 * _ ((CDate(DateStop) - CDate(DateStart)) / DayPerYear), 2) renvoie 1409,37 par contre Application.WorksheetFunction.Round((BaseAmount * InterestRate) / 100 * _ ((CDate(DateStop) - CDate(DateStart)) / DayPerYear), 2) renvoie 1409,38 , comme la formule de la cellule B15 (testé avec Excel 2002 ) je te souhaite une bonne soiree MichelXld Message édité par: MichelXld, à: 10/05/2005 18:16 |
|
|
|
|
|
#3 (permalink) |
|
XLDnaute Accro
|
Bonsoir thierry
Le problème a du déjà posé problème à bien du monde étant donné le nombre de fonctions ecrites pour réaliser un arrondi correcte. Code:
Function Round2(X)
' Arrondi un nombre à 2 positions décimales
' Utilise l'arrondi arithmétique
Round2 = Int(X * 100 + 0.5) / 100
End Function
Function Round2C(X)
' Arrondi une valeur monétaire à 2 positions décimales
' Utilise l'arrondi arithmétique
If IsNull(X) Then
Round2C = Null
Else
Round2C = CCur(Int(X * 100 + 0.5) / 100)
End If
End Function
Function Round2CB(X As Variant) As Variant
' Arrondi bancaire d'une valeur monétaire à 2 décimales.
Dim Temp As Currency, ITemp As Currency, Digit As Integer
If IsNull(X) Then Exit Function
Round2CB = CCur(X / 100) * 100
End Function
Function RoundN(X, N As Integer)
' Arrondi un nombre à N positions décimales
' Utilise l'arrondi arithmétique
' N doit être dans la fourchette de 0-10 pour l'obtention de résultats corrects.
Dim Facteur As Long
Facteur = 10 ^ N
RoundN = Int(X * Facteur + 0.5) / Facteur
End Function
Function ArrondiG(Nombre As Double, Fraction As Integer, Direction As Integer)
'Objectif: Fonction générale d'arrondi jusqu'à 9'999'999'999'999.999
'Nombre: valeur à arrondir
'Fraction: Dénominateur de la fraction utilisée pour arrondir, par exemple 100 pour arrondir à 2 décimales,
' 4 pour arrondir au 1/4, 1000 pour arrondir à 3 décimales, etc.
'Direction: 1 = arrondi au plus proche, 2 arrondi au suivant, 3 arrondi au précédent
Dim NumFrac As Double, AFrac As Double, AFrac2 As Double, NouvArrond As Double
NumFrac = Nombre - Int(Nombre)
AFrac = 1 / Fraction
NumFrac = NumFrac / AFrac
NumFrac = Int(NumFrac + 0.5)
AFrac2 = AFrac * NumFrac
NouvArrond = Int(Nombre) + AFrac2
Select Case Direction
Case 1 'arrondi arithmétique au plus proche
ArrondiG = NouvArrond
Case 2 'arrondi arithmétique au suivant (plus haut)
If NouvArrond >= Nombre Then
ArrondiG = NouvArrond
Else
ArrondiG = NouvArrond + AFrac
End If
Case 3 'arrondi arithmétique au prédédent (plus bas)
If NouvArrond < Nombre Then
ArrondiG = NouvArrond
Else
ArrondiG = NouvArrond - AFrac
End If
End Select
End Function
Public Function ArrondiGlobal(ByVal Nombre As Variant, NbreDec As Long) As Double
'Objectif: Fonction générale d'arrondi au plus proche, jusqu'à 9'999'999'999'999.999
'Arguments: Nombre = valeur à arrondir, NbreDec = nombre de décimales désirées pour le résultat
Dim dblFraction As Double, varTemp As Variant, intSgn As Integer
If Not IsNumeric(Nombre) Then
'génère une erreur indiquant que l'on a fourni un paramètre incorrect
Err.Raise 5
End If
'Calcul de la fraction utilisée pour arrondir au nombre voulu de décimales
dblFraction = 10 ^ NbreDec
'Est-ce un nombre négatif ou positif ?
'intSgn contiendra -1, 0, ou 1
intSgn = Sgn(Nombre)
Nombre = Abs(Nombre)
'Effectue le calcul principal
varTemp = CDec(Nombre) * dblFraction + 0.5
'Termine le calcul de l'arrondi
ArrondiGlobal = intSgn * Int(varTemp) / dblFraction
End Function
__________________
@+ ![]()
|
|
|
|
|
|
#4 (permalink) |
|
XLDnaute Barbatruc
Date d'inscription: février 2005
Messages: 3 755
|
rebonsoir @+Thierry , bonsoir Didier
mon anglais n'est pas terrible mais il semblerait que ce lien traite du meme sujet http://support.microsoft.com/default...b;en-us;225330 les 2 fonctions ne renvoient donc pas toujours la meme valeur Sub Test() MsgBox Round(10.5, 0) MsgBox Application.WorksheetFunction.Round(10.5, 0) End Sub pourtant dans ton classeur tous les criteres ne semblent pas totalement remplis pour que le probleme survienne : You set the numdecimalplaces argument to zero, or omit this argument. and The expression contains an even numbered integer ending in the decimal .5. la solution proposée dans l'aide : If you want to use a round function consistent with Excel's worksheet function, use the WorksheetFunction property bonne soiree MichelXld |
|
|
|
|
|
#5 (permalink) |
|
XLDnaute Accro
Date d'inscription: mars 2005
Messages: 1 286
|
Bonjour a tous
Je te renvois ton fichier et dis moi ce que vous en pensez. [file name=VBA-Round-Wrong-Calculation_20050510215234.zip size=8637]http://www.excel-downloads.com/components/com_simpleboard/uploaded/files/VBA-Round-Wrong-Calculation_20050510215234.zip[/file] |
|
|
|
|
|
#6 (permalink) |
|
XLDnaute Barbatruc
Date d'inscription: février 2005
Messages: 3 099
|
Bonsoir Michel, Didier, Philippe
Tout d'abord grand merci à tous d'avoir pris un peu de votre temps pour me répondre et en plus pour Michel d'avoir même fait des recherches. Tout ce que vous avez testé démontre quand même bien une faille dans la programmation VBA : MyResult = Round(MySum / MyCalculation * etc, 2) Contrairement à : Application.WorksheetFunction.Round(MySum / MyCalculation * etc, 2) La démonstration de Michel est claire là dessus ! Ce qui m'interpelle le plus c'est qu'il faille que je m'en rende compte dans une application développée et surtout déployée professionnellement et dénoncée par un concours de circonstance pour que j'arrive à venir poster cette question avec vous mes amis d'XLD... (no comment, car c'est moi qui passe pour un c... vis à vis de mes collègues de travail !) Enfin, dons après une journée assez longue je ne vais pas plancher là dessus dès maintenant, mais ce que je peux vous dire dès maintenant c'est Merci !! Thank You !!! But I'll be back !!! Asta la vista baby ! Bonne Nuit (ou plutôt bonne journée !!!) @+Thierry |
|
|
|
| ANNONCES | |
![]() |
| Liens sociaux |
| Outils de la discussion | |
|
|