I originally tried to post this with a lengthy explanation but it got lost when I tried to Sumbit it. The notes now included are but a shadow! It's dinner time...
You actually need a function which rounds numbers to any number of decimal places. Vb has the Round function; but that has issues
Any rounding function which return a numeric variable type runs the risk of returning a 'silly' number eg. 1.1200001. To print the rounded result you have to resort to Format$ which has fixed rounding rules(next or even I think).
So consider having the function return a string hammered into the required format.
The following does Standard rounding with consideration for the computer's decimal character.
Public Function round$(ByVal n As Single, ByVal places&, Optional ByVal formatResult As Boolean = True)
Static dp$, p!, Prevn!, PrevNPlaces&, PrevResult$, PrevFormat As Boolean, WeMustSupplyLeadingZero As Boolean
If p = 0 Then
WeMustSupplyLeadingZero = Asc(CStr(0.1)) <> 48 'By default OS will usually supply them; affected by OS regional settings
p = 1!
dp$ = dpChar$()
End If
If PrevNPlaces = places Then
If n = Prevn Then
If formatResult = PrevFormat Then
round$ = PrevResult$
Exit Function
End If
End If
Else
p = 10 ^ places
PrevNPlaces = places
End If
Prevn = n
PrevFormat = formatResult
round$ = n
If InStrB(round$, dp$) Then 'its a fractional number having a decimal portion
If Len(round$) - InStr(round$, dp$) = places + 1 Then ' the original figure is one place longer than required
If right$(round$, 1) = "5" Then
' has a 5 in the position requiring round off
'make sure it will be rounded up, that is away from zero
Mid$(round$, Len(round$), 1) = "6"
n = Val(round$)
End If
End If
round$ = Int(n * p + 0.5!) / p
ElseIf places < 0 Then
round$ = Int(n * p + 0.5!) / p
'Else
'its a whole number and there is no need to round it
End If
If formatResult Then
'leading zero
If WeMustSupplyLeadingZero Then
If InStrB(round$, dp$) = 1 Then
round$ = "0" + round$
ElseIf InStrB(round$, "-" + dp$) = 1 Then
round$ = " " + round$
Mid$(round$, 1, 3) = "-0" + dp$
End If
End If
'trailing dp and zeroes
If places > 0 Then
If InStrB(round$, dp$) = 0 Then round$ = round$ + dp$ + "0"
While Len(round$) - InStr(round$, dp$) < places
round$ = round$ + "0"
Wend
End If
End If
PrevResult$ = round$
End Function
Function dpChar$()
dpChar$ = Mid$(Format$(0.1, "fixed"), 2, 1)
End Function
Function Val#(ByVal txt$)
'Wraps VBA.Val
' VBA val only works on decimals when the decimal char is "."
Static normal As Boolean, init As Boolean, dp$
If init = False Then
dp$ = dpChar()
normal = (dp$ = ".")
init = True
End If
If normal Then
Val = VBA.Val(txt$)
Else
Val = VBA.Val(Replace(txt$, dp$, "."))
End If
'VB help recommends CDbl but..
'the following dos'nt work with strings that contain numbers and text
' like eg. "5.4 mp" because the error is tripped and 0 is returned
'On Error Resume Next
'Val = CDbl(txt$)
End Function