In this Article
- VBA Round
- Syntax of the VBA Round Function
- VBA Round a Variable
- VBA Rounding Results
- VBA Round Cell Value
- VBA RoundUp Function
- RoundUp to the Nearest Whole Number
- RoundUp Function Results
- VBA RoundDown Function
- RoundDown to the Nearest Whole Number
- RoundDown Function Results
- Other VBA Rounding Functions
- VBA Ceiling – RoundUp to A Specified Significance
- VBA RoundUp To Specified Significance Results
- VBA Floor – RoundDown to A Specified Significance
- VBA RoundDown to Specified Significance Results
VBA Round
The VBA Round Function rounds numbers to a specified number of digits.
Syntax of the VBA Round Function
The syntax of the VBA Round Function is:
Round(Expression, [Decimal_places]) where:
- Expression – The number to round.
- Decimal_places (Optional) – An integer that specifies the number of decimal places to round. The value must be greater than or equal to 0 (>=0). If blank, the default of 0 is used, which means the function rounds to the nearest integer.
So, let’s look at an example so that you can see how the VBA Round function works, rounding to 1 decimal place:
Sub Round1()
Msgbox Round(7.25, 1)
End Sub
The resulting MessageBox:
VBA Round a Variable
In the above example, we entered the to-be-rounded number directly into the function, usually however, you’d round a variable instead. The following is an example using a variable instead:
Note: We use the Double variable type in order to store decimal values.
Sub RoundUsingVariable()
Dim unitcount As Double
unitcount = 7.25
MsgBox "The value is " & Round(unitcount, 1)
End Sub
The result is:
VBA Rounding Results
Actual Number | Number of Decimal Places | Result |
---|---|---|
7.25 | 0 | 7 |
7.25 | 1 | 7.2 |
7.25 | 2 | 7.25 |
-7.25 | 1 | -7.2 |
-7.25 | 2 | -7.25 |
VBA Round Cell Value
You can also round a cell value directly in VBA:
Sub RoundCell()
Range("A1").Value = Round(Range("A1").Value, 2)
End Sub
VBA RoundUp Function
Let’s say you want to round a number up, using VBA. There is no built-in VBA RoundUp equivalent function, instead what you can do is call the Excel RoundUp Worksheet function from your VBA code:
roundupUnitcount = Application.WorksheetFunction.RoundUp(unitcount, 3)
Excel’s worksheet functions are available to use in VBA, through the use of the WorksheetFunction object. The only worksheet functions that you can’t call, are those that already have a built-in VBA equivalent.
A reminder of the syntax of the Excel Worksheet RoundUp Function:
ROUNDUP(Number, Digits) where:
- Number – The number that you would like rounded up.
- Digits – The number of digits that you would like to round the number.
So, let’s look at an example, so that you can see how to access the RoundUp Worksheet function in your VBA code:
Sub RoundUp()
Dim unitcount As Double
Dim roundupUnitcount As Double
unitcount = 7.075711
roundupUnitcount = Application.WorksheetFunction.RoundUp(unitcount, 4)
MsgBox "The value is " & roundupUnitcount
End Sub
The result is:
VBA Coding Made Easy
Stop searching for VBA code online. Learn more about AutoMacro — A VBA Code Builder that allows beginners to code procedures from scratch with minimal coding knowledge and with many time-saving features for all users!
Learn More
RoundUp to the Nearest Whole Number
You can round up to the nearest whole number by specifying 0 as the number of decimal places:
Sub RoundUpWhole()
MsgBox Application.WorksheetFunction.RoundUp(7.1, 0)
End Sub
The result delivered:
RoundUp Function Results
Actual Number | Digits | Result |
---|---|---|
7.075711 | 0 | 8 |
7.075711 | 1 | 7.1 |
7.075711 | 2 | 7.08 |
7.075711 | 3 | 7.076 |
7.075711 | -1 | 10 |
7.075711 | -2 | 100 |
7.075711 | -3 | 1000 |
VBA RoundDown Function
Let’s say you want to round a number down, using VBA. There is no built-in VBA RoundDown equivalent function either, instead again, what you would do is call the Excel RoundDown Worksheet function from your VBA code.
A reminder of the syntax of the Excel Worksheet RoundDown Function:
ROUNDDOWN(Number, Digits) where:
• Number – The number that you would like rounded down.
• Digits – The number of digits that you would like to round the number.
So, let’s look at an example, so that you can see how to access the RoundDown Worksheet function in your VBA code:
Sub RoundDown()
Dim unitcount As Double
Dim rounddownUnitcount As Double
unitcount = 5.225193
rounddownUnitcount = Application.WorksheetFunction.RoundDown(unitcount, 4)
MsgBox "The value is " & rounddownUnitcount
End Sub
The result is:
VBA Programming | Code Generator does work for you!
RoundDown to the Nearest Whole Number
You can round down to the nearest whole number by specifying 0 as the number of decimal places:
Sub RoundDownWhole()
MsgBox Application.WorksheetFunction.RoundDown(7.8, 0)
End Sub
The result is:
RoundDown Function Results
Actual Number | Digits | Result |
---|---|---|
5.225193 | 0 | 5 |
5.225193 | 1 | 5.2 |
5.225193 | 2 | 5.22 |
5.225193 | 3 | 5.225 |
5.225193 | -1 | 0 |
5.225193 | -2 | 0 |
5.225193 | -3 | 0 |
Other VBA Rounding Functions
VBA Ceiling – RoundUp to A Specified Significance
VBA does not have a Ceiling.Math function equivalent, so if you want to round a number up to the nearest integer or to the nearest specified multiple of significance, then you can call Excel’s Ceiling.Math worksheet function from your VBA code.
A reminder of the syntax of the Excel Worksheet Ceiling.Math Function:
CEILING.MATH(Number, [Significance], [Mode]) where:
- Number – The number that you would like to round up.
- Significance (Optional) – The multiple to which you want your number to be rounded to.
- Mode (Optional) – Controls whether negative numbers are rounded towards or away from zero.
So, let’s look at an example, so that you can see how to access the Ceiling.Math Worksheet function in your VBA code:
Sub RoundUpToSignificance()
Dim unitcount As Double
Dim ceilingmathUnitcount As Double
unitcount = 4.1221
ceilingmathUnitcount = Application.WorksheetFunction.Ceiling_Math(unitcount, 5)
MsgBox "The value is " & ceilingmathUnitcount
End Sub
The result is:
VBA RoundUp To Specified Significance Results
Actual Number | Significance | Mode | Result |
---|---|---|---|
4.1221 | 5 | ||
4.1221 | 3 | 6 | |
4.1221 | 50 | 50 | |
-4.1221 | 3 | -3 | |
-4.1221 | 3 | -1 | -6 |
AutoMacro | Ultimate VBA Add-in | Click for Free Trial!
VBA Floor – RoundDown to A Specified Significance
VBA does not have a Floor.Math function equivalent either. However, once again, if you want to round a number down to the nearest integer or to the nearest specified multiple of significance, then you can call Excel’s Floor.Math worksheet function from VBA.
A reminder of the syntax of the Excel Worksheet Floor.Math Function:
FLOOR.MATH(Number, [Significance], [Mode]) where:
• Number – The number that you would like to round down.
• Significance (Optional) – The multiple to which you want your number to be rounded to.
• Mode (Optional) – Controls whether negative numbers are rounded towards or away from zero.
So, let’s look at an example, so that you can see how to access the Floor.Math Worksheet function in your VBA code:
Sub RoundDownToSignificance()
Dim unitcount As Double
Dim floormathUnitcount As Double
unitcount = 4.55555559
floormathUnitcount = Application.WorksheetFunction.Floor_Math(unitcount, 2)
MsgBox "The value is " & floormathUnitcount
End Sub
The result is:
VBA RoundDown to Specified Significance Results
Actual Number | Significance | Mode | Result |
---|---|---|---|
4.55555559 | 4 | ||
4.55555559 | 3 | 3 | |
4.55555559 | 50 | 0 | |
-4.55555559 | 3 | -6 | |
-4.55555559 | 3 | -1 | -3 |
Округление чисел в VBA Excel с помощью оператора Round и встроенной функции рабочего листа WorksheetFunction.Round. Особенности бухгалтерского и обычного округления.
Оператор Round
А вы знаете, что при использовании для округления чисел в VBA Excel оператора Round, вы можете получить совершенно не тот результат, который ожидали? И ведь это действительно так!
Скопируйте в модуль VBA следующую процедуру и запустите ее выполнение:
Sub Test_1() Dim a1 As Single, a2 As Single, a3 As Single, a4 As Single a1 = Round(1.5, 0) a2 = Round(2.5, 0) a3 = Round(3.5, 0) a4 = Round(4.5, 0) MsgBox «Round(1.5, 0)=» & a1 & vbNewLine & _ «Round(2.5, 0)=» & a2 & vbNewLine & _ «Round(3.5, 0)=» & a3 & vbNewLine & _ «Round(4.5, 0)=» & a4 End Sub |
В результате вы получите это:
Удивительно, не правда ли? Как же так получилось?
Дело в том, что оператор Round осуществляет «бухгалтерское» (или «банковское») округление, которое призвано при большом количестве таких операций свести погрешность к минимуму. Это достигается за счет того, что оператор Round использует при округлении правило, отличное от того, которое мы знаем еще со школы, когда округляемое число увеличивается на единицу, если отбрасываемое число равно пяти. Суть округления с помощью оператора Round состоит в том, что если перед отбрасываемой пятеркой стоит нечетная цифра, то она увеличивается на единицу (округление вверх), а если перед ней стоит четная цифра, то она не увеличивается (округление вниз).
Еще можно сформулировать «бухгалтерское» округление так: при отбрасывании пятерки число округляется к ближайшему четному. Обратите внимание, что в результатах нашего примера все полученные числа — четные.
Проверим погрешность:
- Сумма исходных чисел: 1.5 + 2.5 + 3.5 +4.5 = 12
- Сумма округленных чисел: 2 + 2 + 4 + 4 = 12
Результат получился просто идеальный для приведенного примера, так как суммы исходных и округленных чисел равны.
Оператор WorksheetFunction.Round
Если вам необходимо общепринятое математическое округление, используйте встроенную функцию рабочего листа — WorksheetFunction.Round.
Скопируйте в модуль VBA процедуру с использованием WorksheetFunction.Round и запустите ее выполнение:
Sub Test_2() Dim a1 As Single, a2 As Single, a3 As Single, a4 As Single a1 = WorksheetFunction.Round(1.5, 0) a2 = WorksheetFunction.Round(2.5, 0) a3 = WorksheetFunction.Round(3.5, 0) a4 = WorksheetFunction.Round(4.5, 0) MsgBox «WorksheetFunction.Round(1.5, 0)=» & a1 & vbNewLine & _ «WorksheetFunction.Round(2.5, 0)=» & a2 & vbNewLine & _ «WorksheetFunction.Round(3.5, 0)=» & a3 & vbNewLine & _ «WorksheetFunction.Round(4.5, 0)=» & a4 End Sub |
Результат будет следующий:
Получилось то, что мы и ожидали.
Проверим погрешность:
- Сумма исходных чисел: 1.5 + 2.5 + 3.5 +4.5 = 12
- Сумма округленных чисел: 2 + 3 + 4 + 5 = 14
Результат очевиден — в данном случае сумма округленных чисел на 2 единицы больше суммы исходных.
Исходя из этого результата, можно сделать вывод, что «банковское» округление с помощью оператора Round дает более точные результаты при массовых операциях с округленными числами. Но в повседневной жизни чаще встречается обычное математическое округление.
Выбирайте округление, которое вам больше подходит для решаемой задачи!
Главная » Функции VBA »
28 Апрель 2011 129168 просмотров
- ABS() — эта функция возвращает абсолютное значение переданного ей числа (то же число, но без знака). Например, ABS(3) и ABS(-3) вернут одно и то же значение 3.
- Int(), Fix() и Round()позволяют по разному округлять числа:
- Int() возвращает ближайшее меньшее целое;
- Fix() отбрасывает дробную часть;
- Round() округляет до указанного количества знаков после запятой.
Однако Round может вернуть не совсем ожидаемый результат, т.к. функция применяет финансовое округление. По правилам данного округления если за последней к округлению цифрой стоит 5, то округляемую цифру увеличивают в том случае, если она нечетная и уменьшают, если четная.
Математическое же округление всегда округляет цифру в большую сторону, если за ней идет цифра 5 и выше, и отбрасывает остаток если 4 и меньше.
Т.е. если мы выполним такую строку кодато результатом будет 2,5, хотя предполагалось получить 2,51. Поэтому порой для округления лучше использовать Format:
MsgBox Format(2.505, "#,##0.00")
но в этом случае мы получим не число в чистом виде, а текст. И если нужно именно число, то придется производить дополнительные преобразования:
MsgBox CDbl(Format(2.505, "#,##0.00"))
Так же, для математического округления, можно использовать и такой вариант:
MsgBox Application.Round(2.505, 2)
Но здесь стоит учитывать, что это не чистый VB и этот метод сработает только в Excel, т.к. по сути мы обращаемся к встроенной в Excel функции округления ОКРУГЛ(ROUND), которая применяет именно математическое округление.
- Rnd и команда Randomize используются для получения случайных значений (очень удобно для генерации имен файлов и в других ситуациях). Перед вызовом функции Rnd() необходимо выполнить команду Randomize для инициализации генератора случайных чисел.
Dim lRundNum As Long, lMinNum As Long, lMaxNum As Long lMinNum = 1: lMaxNum = 100 Randomize lRundNum = Int(lMinNum + (Rnd() * lMaxNum)) MsgBox lRundNum
- Sgn() — позволяет вернуть информацию о знаке числа. Возвращает 1, если число положительное, -1, если отрицательное и 0, если проверяемое число равно 0.
- Mod() — Делит два числа и возвращает только остаток. Например, выражение 8 Mod 3 вернет число 2, т.к. без остатка(в виде дроби у результата деления) 8 делится на 3 только до 2-х(8 / 3 = 2,66666666666667).
При этом функция Mod учитывает и знак числа — если первое число или оба числа отрицательные, то результатом будет отрицательное число. Если же отрицательное только второе число — то результат будет положительным числом.
При попытке получить остаток при делении чисел с плавающей запятой результат может быть не тем, который ожидается, потому что перед выполнением деления оба числа округляются по математическим законам(5 и выше до большего, 4 и ниже — до меньшего). Например, выражение 8 Mod 3.5 вернет 0, а выражение 8 Mod 3.4 — 2.
You can use the RoundUp method in VBA to round values up.
This function uses the following basic syntax:
Sub RoundUpValue()
Range("B1") = WorksheetFunction.RoundUp(Range("A1"), 0)
End Sub
This particular example will round up the value in cell A1 to the nearest whole number and display the result in cell B1.
Note that the second argument in the RoundUp method specifies the number of digits to round where:
- -3 rounds up to the nearest thousand
- -2 rounds up to the nearest hundred
- -1 rounds up to the nearest ten
- 0 rounds up to the nearest whole number
- 1 rounds up to the nearest tenth (one decimal place)
- 2 rounds up to the nearest hundredth (two decimal places)
- 3 rounds up to the nearest thousandth (three decimal places)
And so on.
The following examples show how to use the RoundUp method in practice.
Example 1: Round Up to Nearest Whole Number in VBA
We can create the following macro to round up the value in cell A1 to the nearest whole number and display the result in cell B1:
Sub RoundUpValue()
Range("B1") = WorksheetFunction.RoundUp(Range("A1"), 0)
End Sub
When we run this macro, we receive the following output:
Notice that the value 1,432.78 in cell A1 has been rounded up to the nearest whole number of 1,433 in cell B1.
Example 2: Round Up to Nearest Hundred in VBA
We can create the following macro to round up the value in cell A1 to the nearest hundred and display the result in cell B1:
Sub RoundUpValue()
Range("B1") = WorksheetFunction.RoundUp(Range("A1"), -2)
End Sub
When we run this macro, we receive the following output:
Notice that the value 1,432.78 in cell A1 has been rounded up to the nearest hundred of 1,500 in cell B1.
Example 3: Round Up to Nearest Tenth in VBA
We can create the following macro to round up the value in cell A1 to the nearest tenth (i.e. one decimal place) and display the result in cell B1:
Sub RoundUpValue()
Range("B1") = WorksheetFunction.RoundUp(Range("A1"), 1)
End Sub
When we run this macro, we receive the following output:
Notice that the value 1,432.78 in cell A1 has been rounded up to the nearest tenth of 1,432.8 in cell B1.
Note: You can find the complete documentation for the VBA RoundUp method here.
Additional Resources
The following tutorials explain how to perform other common tasks in VBA:
VBA: How to Write SUMIF and SUMIFS Functions
VBA: How to Write COUNTIF and COUNTIFS Functions
VBA: How to Write AVERAGEIF and AVERAGEIFS Functions
Округление – экселевские причуды и несоответствия одной из «причуд» Excelя, которая может вызвать некоторую путаницу, если о ней не знаешь — это применение программой двух разных алгоритмов округления чисел. Далее обо всем по порядку.
Разный результат округления в Excel и VBA
Последствия существования «причуд» на рисунке ниже:
Как вы можете видеть на рисунке, результаты округления (и итоги) СУЩЕСТВЕННО ОТЛИЧАЮТСЯ!
Все что было сделано, так это округлено каждое из чисел, а затем суммирование их. В первом случае (столбец B) был округлен с помощью стандартной экселевской функции ОКРУГЛ, во втором случае (столбец C) – было использовано написанную в VBA функцию пользователя, которая, однако, не делает ничего иного, кроме как только округляя указанные числа, но используя доступную в VBA функцию Round(). Чтобы посмотреть соответствующий код макроса для пользовательской функции нажмите комбинацию горячих клавиш ALT+F11:
В Module1 прописан код пользовательской макро-функции.
Функция ОКРУГЛ и Round VBA округляют по-разному?
В функции ОКРУГЛ, доступной в Excelе, использовался стандартный алгоритм, в котором «половинки» (пятерки в конце разряда десятичной дроби) округлены ВСЕГДА в большую сторону. То есть 2,5 округляется до 3; 10,345 до 10,35 и т. д. Это именно то правило, которое мы выучили в школе, и тот результат, который ожидало бы получить большинство из нас.
В случае использования доступных в VBA функций, (кроме Round () это также CByte (), CInt (), CLng () и CCur () ) используется алгоритм, называемый банковским или методом Гаусса. Здесь «половинки» округляются раз в большую сторону, а раз в меньшую сторону, всегда к ближайшему четному. Поэтому 5,5, как и в случае использования экселевской функции, будет округлено до 6. Однако VBA поступит иначе, например, с числом 2,5 — оно будет округлено до 2, а не до 3!
Банковское округление чисел в Excel и VBA
Является ли банковский алгоритм плохим? Само применение банковского алгоритма не является чем-то необычным, а тем более плохим. Так как в зависимости от применения он имеет свои существенные преимущества. Стандартное округление (всегда в большую сторону) в случае выполнения последующих арифметических операций с большим числом округленных таким методом значений, приводит к накоплению ошибки округления. Ниже приведен небольшой пример:
Здесь то же самое, что и в первом примере. Округлено каждое из чисел, а затем суммированы итоги. Полученные итоги сравниваются с итогом, который бы получил если бы не округлялись числа. Как видно, при применении банковского алгоритма округления чисел, используемого в VBA, полученный итог является намного более точным к «оригинальному» итогу. Это происходит из-за того, что банковский алгоритм округляя раз в большую сторону, раз в меньшую сторону, «амортизирует» ошибки, возникающие в результате округления.
Несоответствия функций округления в Excel и VBA
Можно было бы ожидать, что в Excelе выполнено простое разделение: экселевские функции используют один алгоритм, а функции VBA — другой. Это было бы все равно странным, но, по крайней мере, имело бы какую-то внутреннюю согласованность. К сожалению, программисты Microsoft по какой-то причине были очень непоследовательными и, например, в других функциях VBA, таких как FormatNumber или Format (при форматировании чисел с использованием этих функций в зависимости от выбранного формата также может происходить округление) используется стандартный алгоритм округления:
Следовательно, функция VBA Round (2,5, 0) вернет как результат 2, но уже функция FormatNumber (2,5, 0) вернет как результат 3. И где здесь логика?
Подытожим особенности округления чисел в Excel
Стоит помнить об этих различиях, создавая свои макросы, которые выполняют операции округления чисел. Как вы можете видеть, результат, возвращаемый макросом, может полностью отличаться от ожидаемого.
Как уже выше упоминалось, один алгоритм не является лучше или хуже другого. Каждый хорош в зависимости от применения. Стандартный алгоритм дает результаты, которые мы «ожидаем», в отличие от банковского алгоритма, который, помимо прочего, немного удивляет результатами.
Жаль, что эти два алгоритма были реализованы одновременно, кроме того, довольно хаотичным образом. Возможно было бы более естественным, если бы функция VBA Round() возвращала тот же результат, что и экселевская функция ОКРУГЛ (в конце концов, в английской версии Excelя, она называется также — ROUND).