Reputation: 37
I am trying to build an UDF, dealing with floating decimal points (like if input value was between 1 to 10, round value to 2 dp and if input value was between 10 to 100, round value to 1 dp, etc). And I would like to keep the trailing zeros.
I wrote the code based on these 2 threads:
How do I keep the trailing zero (or zeros) when I round with Excel VBA?
change cell format within functions in excel VBA
I know my major problem was that I am not used to UDF syntax.
Below are my lines:
Public Function FDP(Rng As Range)
Dim DP As Integer, CelRef As Range
For Each CelRef In Rng
If CelRef.Value2 >= 100 Then
DP = 0
ElseIf CelRef.Value2 < 100 And CelRef.Value2 >= 10 Then
DP = 1
ElseIf CelRef.Value2 < 10 And CelRef.Value2 >= 1 Then
DP = 2
ElseIf CelRef.Value2 < 1 And CelRef.Value2 >= 0.1 Then
DP = 3
ElseIf CelRef.Value2 < 0.1 Then
DP = 4
Else
FDP = WorksheetFunction.Round(CelRef.Value2, 3 - (Int(log(CelRef.Value2)) + 1))
End If
FDP = WorksheetFunction.Round(CelRef.Value2, DP)
CelRef.NumberFormat = "0." & WorksheetFunction.Rept("0", DP) ' not sure if this line was correct
Next CelRef
End Function
If I change the line:
CelRef.NumberFormat = "0." & WorksheetFunction.Rept("0", DP)
to
FDP.NumberFormat = "0." & WorksheetFunction.Rept("0", DP)
the function does not work. While I keep this line, a cell with value of 3.40112458 will be converted to 3.4, not 3.40 as I expected.
How should I correct my lines so that it will work? Any help would be appreciated.
Below lines were my original version, dealing with the rounding to floating decimal points:
Public Function FDP(ByVal CelRef As Double) As Double
Dim DP As Integer
If CelRef >= 100 Then
DP = 0
ElseIf CelRef < 100 And CelRef >= 10 Then
DP = 1
ElseIf CelRef < 10 And CelRef >= 1 Then
DP = 2
ElseIf CelRef < 1 And CelRef >= 0.1 Then
DP = 3
ElseIf CelRef < 0.1 Then
DP = 4
Else
FDP = WorksheetFunction.Round(CelRef, 3 - (Int(log(CelRef)) + 1)) ' this line round to 3 significant figures
End If
FDP = WorksheetFunction.Round(CelRef, DP)
End Function
Upvotes: 0
Views: 552
Reputation: 1524
Fist the decimal places can be quickly computed with
DP = 3-WorksheetFunction.Floor(WorksheetFunction.Log10(Abs(x)), 1)
with the following results
' x DP
' 0.000502655 7
' 0.002513274 6
' 0.012566371 5
' 0.062831853 5
' 0.314159265 4
' 1.570796327 3
' 7.853981634 3
' 39.26990817 2
' 196.3495408 1
' 981.7477042 1
' 4908.738521 0
' 24543.69261 -1
' 122718.463 -2
and then to round with trailing zeros your only option with a UDF is to return a formatted string.
and
Function RoundCustom(ByVal x As Double) As String
Dim DP As Long, s As Long, t As String
s = CLng(Sgn(x))
x = Abs(x)
DP = 3 - CLng(WorksheetFunction.Floor(WorksheetFunction.Log10(Abs(x)), 1))
If DP >= 4 Then DP = DP - 1 ' if value <1.0 reduce the DP by one
DP = WorksheetFunction.Max(0, DP)
x = Round(x, DP)
t = Format(s*x, "0." & Strings.String(DP, "0"))
RoundCustom = t
End Function
Upvotes: 1