Be careful, the VBA Round function uses Banker's rounding, where it rounds .5 to an even number, like so:

Round (12.55, 1) would return 12.6 (rounds up) 
Round (12.65, 1) would return 12.6 (rounds down) 
Round (12.75, 1) would return 12.8 (rounds up)   

Whereas the Excel Worksheet Function Round, always rounds .5 up.

I've done some tests and it looks like .5 up rounding (symmetric rounding) is also used by cell formatting, and also for Column Width rounding (when using the General Number format). The 'Precision as displayed' flag doesn't appear to do any rounding itself, it just uses the rounded result of the cell format.

I tried to implement the SymArith function from Microsoft in VBA for my rounding, but found that Fix has an error when you try to give it a number like 58.55; the function giving a result of 58.5 instead of 58.6. I then finally discovered that you can use the Excel Worksheet Round function, like so:

Application.Round(58.55, 1)

This will allow you to do normal rounding in VBA, though it may not be as quick as some custom function. I realize that this has come full circle from the question, but wanted to include it for completeness.

Answer from Lance Roberts on Stack Overflow
🌐
Microsoft Support
support.microsoft.com › en-us › office › round-function-921ce538-c9a6-41e2-be87-28e685b59935
Round Function - Microsoft Support
Syntax for the function that returns a number rounded to a specified number of decimal places in Access.
🌐
TechOnTheNet
techonthenet.com › access › functions › numeric › round.php
MS Access: Round Function
This MSAccess tutorial explains how to use the Access Round function with syntax and examples. The Microsoft Access Round function returns a number rounded to a specified number of decimal places.
Discussions

Ms ACCESS and SQL: round to two decimals through query - Stack Overflow
I use queries to calculate all kinds of supplier information (average lead time, total spend for that supplier, average price, etc.). All output is shown in listboxes in forms in Ms ACCESS. Exampl... More on stackoverflow.com
🌐 stackoverflow.com
sql - How to ROUNDUP a number in Access 2013? - Stack Overflow
For Access 2013, I need a way to round up any fractional numbers to the next whole number in an SQL query. Example: SELECT ROUNDUP(NumberValues) FROM Table1 In the above query, a row with 1.25 s... More on stackoverflow.com
🌐 stackoverflow.com
Solved - Rounding decimal places | Access World Forums
My understanding is that Microsoft products use bankers rounding on decimal places; i.e., the decimal is only rounding upwards if the decimal being rounded is 6 or higher. I looked at rounding in... More on access-programmers.co.uk
🌐 access-programmers.co.uk
May 3, 2022
Rounding Down In Access Take 2 - TechRepublic
Does anyone know how to round down numbers in Access. i.e. 99.999 becomes 99.99 not 100.00. Any function or formula will do. I need the same as the Excel function Rounddown. Thanks to who previously suggested convert to an integer, but I think you missed the point. Any help gratefully received More on techrepublic.com
🌐 techrepublic.com
September 10, 2003
Top answer
1 of 13
26

Be careful, the VBA Round function uses Banker's rounding, where it rounds .5 to an even number, like so:

Round (12.55, 1) would return 12.6 (rounds up) 
Round (12.65, 1) would return 12.6 (rounds down) 
Round (12.75, 1) would return 12.8 (rounds up)   

Whereas the Excel Worksheet Function Round, always rounds .5 up.

I've done some tests and it looks like .5 up rounding (symmetric rounding) is also used by cell formatting, and also for Column Width rounding (when using the General Number format). The 'Precision as displayed' flag doesn't appear to do any rounding itself, it just uses the rounded result of the cell format.

I tried to implement the SymArith function from Microsoft in VBA for my rounding, but found that Fix has an error when you try to give it a number like 58.55; the function giving a result of 58.5 instead of 58.6. I then finally discovered that you can use the Excel Worksheet Round function, like so:

Application.Round(58.55, 1)

This will allow you to do normal rounding in VBA, though it may not be as quick as some custom function. I realize that this has come full circle from the question, but wanted to include it for completeness.

2 of 13
11

To expand a little on the accepted answer:

"The Round function performs round to even, which is different from round to larger."
--Microsoft

Format always rounds up.

  Debug.Print Round(19.955, 2)
  'Answer: 19.95

  Debug.Print Format(19.955, "#.00")
  'Answer: 19.96

ACC2000: Rounding Errors When You Use Floating-Point Numbers: http://support.microsoft.com/kb/210423

ACC2000: How to Round a Number Up or Down by a Desired Increment: http://support.microsoft.com/kb/209996

Round Function: http://msdn2.microsoft.com/en-us/library/se6f2zfx.aspx

How To Implement Custom Rounding Procedures: http://support.microsoft.com/kb/196652

🌐
W3Schools
w3schools.com › sql › func_msaccess_round.asp
MS Access Round() Function
String Functions: Asc Chr Concat with & CurDir Format InStr InstrRev LCase Left Len LTrim Mid Replace Right RTrim Space Split Str StrComp StrConv StrReverse Trim UCase Numeric Functions: Abs Atn Avg Cos Count Exp Fix Format Int Max Min Randomize Rnd Round Sgn Sqr Sum Val Date Functions: Date DateAdd DateDiff DatePart DateSerial DateValue Day Format Hour Minute Month MonthName Now Second Time TimeSerial TimeValue Weekday WeekdayName Year Other Functions: CurrentUser Environ IsDate IsNull IsNumeric SQL Quick Ref
🌐
Allenbrowne
allenbrowne.com › round.html
Microsoft Access tips: Rounding numbers in Access
Access displays currency fields rounded to the nearest cent, but it stores the value to the hundredth of a cent (4 decimal places.) The Round() function in Access uses a bankers rounding. When the last significant digit is a 5, it rounds to the nearest even number.
🌐
Microsoft Learn
learn.microsoft.com › en-us › office › vba › language › reference › user-interface-help › round-function
Round function (Visual Basic for Applications) | Microsoft Learn
March 29, 2022 - For more predictable results, use Worksheet Round functions in Excel VBA. ?Round(0.12335,4) 0,1234 ?Round(0.12345,4) 0,1234 ?Round(0.12355,4) 0,1236 ?Round(0.12365,4) 0,1236 ?WorksheetFunction.Round(0.12345,4) 0,1235 ?WorksheetFunction.RoundUp(0.12345,4) 0,1235 ?WorksheetFunction.RoundDown(0.12345,4) 0,1234 ?Round(0.00005,4) 0 ?WorksheetFunction.Round(0.00005,4) 0,0001 ?WorksheetFunction.RoundUp(0.00005,4) 0,0001 ?WorksheetFunction.RoundDown(0.00005,4) 0
Find elsewhere
🌐
Computer Learning Zone
599cd.com › tips › access › round-int-fix
Round Int Fix - Microsoft Access
New Tips Added Weekly! Click here to get on our Mailing List · Access Excel Word Windows FrontPage Hardware Misc VB VBScript VB.NET ASP HTA
🌐
TechOnTheNet
techonthenet.com › access › functions › misc › customround.php
MS Access: Creating a custom round function
You'll need to open your Access database and create a new module. Then paste into the new module the following function: Function CustomRound(pValue As Double) As Double Dim LWhole As Long Dim LFraction As Double 'Retrieve integer part of the number LWhole = Int(pValue) 'Retrieve the fraction part of the number LFraction = pValue - LWhole If LFraction < 0.5 Then CustomRound = LWhole Else CustomRound = LWhole + 0.5 End If End Function · Now, when you want to round your values, you can use the round function as follows:
🌐
Access World
access-programmers.co.uk › home › forums › microsoft access discussion › modules & vba
Solved - Rounding decimal places | Access World Forums
May 3, 2022 - My understanding is that Microsoft products use bankers rounding on decimal places; i.e., the decimal is only rounding upwards if the decimal being rounded is 6 or higher. I looked at rounding in Microsoft documents and found Math.Round(value, MidpointRounding.AwayFromZero, decimal places)...
🌐
ConsultDMW
consultdmw.com › access-rounding-numbers.html
Access VBA Function That Rounds Numbers Like Excel ROUND
April 26, 2024 - Microsoft Access VBA function that rounds numbers up and down like Excel ROUND function to set number of decimal places in results to calculations
🌐
MyExcelOnline
myexcelonline.com › home › how to use excel round function – step by step guide
How to Use Excel ROUND Function - Step by Step Guide | MyExcelOnline
August 30, 2024 - This will adjust your figure to two decimal places, ideal for financial calculations involving dollars and cents. To quickly access the ROUND function in Excel, you can use the Formula tab on the ribbon.
🌐
EasyIT
easyit.com › round
How to Use the ROUND Function in Excel | Complete Tutorial
Look for ROUND in the dropdown menu, or click “Insert Function” (fx) to search for rounding functions. You can also access ROUND by clicking the fx button next to the formula bar and typing “ROUND” ...
Published   February 10, 2025
🌐
GeeksforGeeks
geeksforgeeks.org › sql › rnd-and-round-function-in-ms-access
Rnd() and Round Function in MS Access - GeeksforGeeks
September 2, 2020 - Otherwise, if we want to generate a number between a range then we will use the formula Int ((upperbound - lowerbound + 1) * Rnd + lowerbound). Syntax : ... 2. Round() Function : Round() function returns rounds a number to a specified number ...
🌐
TechRepublic
techrepublic.com › home › topics › software › web development › rounding down in access take 2
Rounding Down In Access Take 2 - TechRepublic
September 10, 2003 - Many thanks but this still rounds 99.998 to 100 We need to round down in every instance regardless of the third or subsequent decimal place. ... This statement works in Access 2000 and will round up any number to the next whole number.
Top answer
1 of 12
25

Be careful, the VBA Round function uses Banker's rounding, where it rounds .5 to an even number, like so:

Round (12.55, 1) would return 12.6 (rounds up) 
Round (12.65, 1) would return 12.6 (rounds down) 
Round (12.75, 1) would return 12.8 (rounds up)   

Whereas the Excel Worksheet Function Round, always rounds .5 up.

I've done some tests and it looks like .5 up rounding (symmetric rounding) is also used by cell formatting, and also for Column Width rounding (when using the General Number format). The 'Precision as displayed' flag doesn't appear to do any rounding itself, it just uses the rounded result of the cell format.

I tried to implement the SymArith function from Microsoft in VBA for my rounding, but found that Fix has an error when you try to give it a number like 58.55; the function giving a result of 58.5 instead of 58.6. I then finally discovered that you can use the Excel Worksheet Round function, like so:

Application.Round(58.55, 1)

This will allow you to do normal rounding in VBA, though it may not be as quick as some custom function. I realize that this has come full circle from the question, but wanted to include it for completeness.

2 of 12
9

To expand a little on the accepted answer:

"The Round function performs round to even, which is different from round to larger."
--Microsoft

Format always rounds up.

  Debug.Print Round(19.955, 2)
  'Answer: 19.95

  Debug.Print Format(19.955, "#.00")
  'Answer: 19.96

ACC2000: Rounding Errors When You Use Floating-Point Numbers: http://support.microsoft.com/kb/210423

ACC2000: How to Round a Number Up or Down by a Desired Increment: http://support.microsoft.com/kb/209996

Round Function: http://msdn2.microsoft.com/en-us/library/se6f2zfx.aspx

How To Implement Custom Rounding Procedures: http://support.microsoft.com/kb/196652

🌐
Webcheatsheet
webcheatsheet.com › access_functions › round
Access: Round Function – WebCheatSheet
In Access, the Round function returns a number rounded to a specified number of decimal places.
🌐
Datanumen
datanumen.com › blogs › make-use-rounding-feature-ms-access
How, When and Where to Make Use of the Rounding Feature in MS Access
September 29, 2017 - As mentioned above, in the MS Access edition of 2000 and later, the Rounding ( ) function was built in, it is present in the text box control source, and might also be found in any of the calculated query field. For any given expression in Field Row of Query Design, you only need to insert ( ), to round it off.
Top answer
1 of 2
4

You can use the RoundUp and RoundDown functions found here at Experts Exchange and here at GitHub.

Your usage would be:

Value = 27.605 
Value1 = RoundUp(Value, 2)    ' 27.61 
Value2 = RoundDown(Value, 2)  ' 27.6

These are the functions:

' Rounds Value up with count of decimals as specified with parameter NumDigitsAfterDecimals.
'
' Rounds to integer if NumDigitsAfterDecimals is zero.
'
' Optionally, rounds negative values away from zero.
'
' Uses CDec() for correcting bit errors of reals.
'
' Execution time is about 0.5µs for rounding to integer
' else about 1µs.
'
Public Function RoundUp( _
    ByVal Value As Variant, _
    Optional ByVal NumDigitsAfterDecimals As Long, _
    Optional ByVal RoundingAwayFromZero As Boolean) _
    As Variant

    Dim Scaling     As Variant
    Dim ScaledValue As Variant
    Dim ReturnValue As Variant

    ' Only round if Value is numeric and ReturnValue can be different from zero.
    If Not IsNumeric(Value) Then
        ' Nothing to do.
        ReturnValue = Null
    ElseIf Value = 0 Then
        ' Nothing to round.
        ' Return Value as is.
        ReturnValue = Value
    Else
        If NumDigitsAfterDecimals <> 0 Then
            Scaling = CDec(Base10 ^ NumDigitsAfterDecimals)
        Else
            Scaling = 1
        End If
        If Scaling = 0 Then
            ' A very large value for Digits has minimized scaling.
            ' Return Value as is.
            ReturnValue = Value
        ElseIf RoundingAwayFromZero = False Or Value > 0 Then
            ' Round numeric value up.
            If Scaling = 1 Then
                ' Integer rounding.
                ReturnValue = -Int(-Value)
            Else
                ' First try with conversion to Decimal to avoid bit errors for some reals like 32.675.
                On Error Resume Next
                ScaledValue = -Int(CDec(-Value) * Scaling)
                ReturnValue = ScaledValue / Scaling
                If Err.Number <> 0 Then
                    ' Decimal overflow.
                    ' Round Value without conversion to Decimal.
                    ScaledValue = -Int(-Value * Scaling)
                    ReturnValue = ScaledValue / Scaling
                End If
            End If
        Else
            ' Round absolute value up.
            If Scaling = 1 Then
                ' Integer rounding.
                ReturnValue = Int(Value)
            Else
                ' First try with conversion to Decimal to avoid bit errors for some reals like 32.675.
                On Error Resume Next
                ScaledValue = Int(CDec(Value) * Scaling)
                ReturnValue = ScaledValue / Scaling
                If Err.Number <> 0 Then
                    ' Decimal overflow.
                    ' Round Value without conversion to Decimal.
                    ScaledValue = Int(Value * Scaling)
                    ReturnValue = ScaledValue / Scaling
                End If
            End If
        End If
        If Err.Number <> 0 Then
            ' Rounding failed because values are near one of the boundaries of type Double.
            ' Return value as is.
            ReturnValue = Value
        End If
    End If

    RoundUp = ReturnValue

End Function

And:

' Rounds Value down with count of decimals as specified with parameter NumDigitsAfterDecimals.
'
' Rounds to integer if NumDigitsAfterDecimals is zero.
'
' Optionally, rounds negative values towards zero.
'
' Uses CDec() for correcting bit errors of reals.
'
' Execution time is about 0.5µs for rounding to integer
' else about 1µs.
'
Public Function RoundDown( _
    ByVal Value As Variant, _
    Optional ByVal NumDigitsAfterDecimals As Long, _
    Optional ByVal RoundingToZero As Boolean) _
    As Variant

    Dim Scaling     As Variant
    Dim ScaledValue As Variant
    Dim ReturnValue As Variant

    ' Only round if Value is numeric and ReturnValue can be different from zero.
    If Not IsNumeric(Value) Then
        ' Nothing to do.
        ReturnValue = Null
    ElseIf Value = 0 Then
        ' Nothing to round.
        ' Return Value as is.
        ReturnValue = Value
    Else
        If NumDigitsAfterDecimals <> 0 Then
            Scaling = CDec(Base10 ^ NumDigitsAfterDecimals)
        Else
            Scaling = 1
        End If
        If Scaling = 0 Then
            ' A very large value for Digits has minimized scaling.
            ' Return Value as is.
            ReturnValue = Value
        ElseIf RoundingToZero = False Then
            ' Round numeric value down.
            If Scaling = 1 Then
                ' Integer rounding.
                ReturnValue = Int(Value)
            Else
                ' First try with conversion to Decimal to avoid bit errors for some reals like 32.675.
                ' Very large values for NumDigitsAfterDecimals can cause an out-of-range error when dividing.
                On Error Resume Next
                ScaledValue = Int(CDec(Value) * Scaling)
                ReturnValue = ScaledValue / Scaling
                If Err.Number <> 0 Then
                    ' Decimal overflow.
                    ' Round Value without conversion to Decimal.
                    ScaledValue = Int(Value * Scaling)
                    ReturnValue = ScaledValue / Scaling
                End If
            End If
        Else
            ' Round absolute value down.
            If Scaling = 1 Then
                ' Integer rounding.
                ReturnValue = Fix(Value)
            Else
                ' First try with conversion to Decimal to avoid bit errors for some reals like 32.675.
                ' Very large values for NumDigitsAfterDecimals can cause an out-of-range error when dividing.
                On Error Resume Next
                ScaledValue = Fix(CDec(Value) * Scaling)
                ReturnValue = ScaledValue / Scaling
                If Err.Number <> 0 Then
                    ' Decimal overflow.
                    ' Round Value with no conversion.
                    ScaledValue = Fix(Value * Scaling)
                    ReturnValue = ScaledValue / Scaling
                End If
            End If
        End If
        If Err.Number <> 0 Then
            ' Rounding failed because values are near one of the boundaries of type Double.
            ' Return value as is.
            ReturnValue = Value
        End If
    End If

    RoundDown = ReturnValue

End Function

Note please, that the native Round of VBA is quite buggy. See the test module of the download.

2 of 2
3

You won't get a better answer than Gustav's for proper rounding functions, and in the case of only two constituent values, then the complimentary RoundDown and RoundUp functions are sufficient. (FYI, similar functions are often named Floor and Ceiling in other languages and programming libraries.)

However, when it is critical to have constituent values sum to an original/expected value, it is best to calculate the last of the constituent values by a difference of the expected total and the sum of all other rounded values. This will guarantee the correct sum even if there are unexpected results from rounding. Even if using the buggy VBA Round() function, this technique would have avoided the 1 cent errors to start with.

surcharge1 = SomeRoundFunction(Total_Surcharge / 2.0)
surcharge2 = Total_Surcharge - surcharge1

This is especially important with more than two constituent values, since there is no set of rounding functions that will properly round 3 or more values to guarantee they add up to some value. As an example, I recently had to split out total transaction amounts by (re)calculating discounts and taxes. Although I knew the percentages for both, I needed to figure each part rounded to the penny. Penny errors were acceptable in both discount and tax, but they still needed to add up to the total after any rounding. The only guarantee to ensure that the final transaction value remained unchanged was to first calculate and round the tax, next calculate and round the discount, then finally correct for penny errors by subtracting the sum of parts from the expected total.