piątek, 6 lutego 2015

Zaokrąglanie liczb- funkcja Round vs. UDF

W dobie operacji finansowych wykonywanych dla jednostek wyrażanych w czterech, pięciu miejscach po przecinku zaokrąglanie wyników może sprawiać pewien problem. Szczególny problem pojawia się w momencie, gdy sięgamy po standardową, wbudowaną funkcję VBA Round. Okazuje się bowiem, że funkcja ta nie zaokrągla w sposób jaki oczekujemy. Zobrazuje to poniższy przykładowy kod:
1Debug.Print Round(0.515, 2) '>> 0,52
2Debug.Print Round(0.525, 2) '>> 0,52
3Debug.Print Round(0.535, 2) '>> 0,54
4Debug.Print Round(0.545, 2) '>> 0,55
5Debug.Print Round(0.555, 2) '>> 0,56
6Debug.Print Round(0.565, 2) '>> 0,56
7Debug.Print Round(0.575, 2) '>> 0,57
8Debug.Print Round(0.585, 2) '>> 0,58
Jak widać zwracane wynik są w niektórych sytuacjach lekko zaskakujące. Teoretycznie bowiem obowiązuje tu zasada, iż w sytuacji, gdy zaokrąglana wartość wynosi 5 (jak w każdym powyższym przypadku) to zaokrąglenie w górę nastąpi o ile poprzednia liczba jest nieparzysta, oraz w dół- gdy poprzednia liczba jest parzysta. Jak widać nie w każdym przypadku jest to prawdziwe.

Jeżeli więc potrzebujemy klasycznej techniki zaokrąglania to niezbędne jest stworzenie własnej funkcji zaokrąglającej. Poniżej przykład takie funkcji:
01Public Function RoundUDF(Wartosc As Double, _
02                    Optional MiejscPoPrzecinku As Integer = 0) As Double
03         
04On Error GoTo ErrHandler
05     
06    RoundUDF = Round((Wartosc * (10 ^ MiejscPoPrzecinku)) + 0.5, 0) / _
07                               (10 ^ MiejscPoPrzecinku)
08 
09Exit Function
10ErrHandler:
11    MsgBox Err.Number & vbNewLine & Err.Description
12       
13End Function


Wyniki działania naszej funkcji zaokrąglającej prezentuje poniższy przykład:
1Debug.Print RoundUDF(0.515, 2) '>> 0,52
2Debug.Print RoundUDF(0.525, 2) '>> 0,53
3Debug.Print RoundUDF(0.535, 2) '>> 0,54
4Debug.Print RoundUDF(0.545, 2) '>> 0,55
5Debug.Print RoundUDF(0.555, 2) '>> 0,56
6Debug.Print RoundUDF(0.565, 2) '>> 0,57
7Debug.Print RoundUDF(0.575, 2) '>> 0,58
8Debug.Print RoundUDF(0.585, 2) '>> 0,59

Brak komentarzy:

Prześlij komentarz