ROUND関数にバグ?VBAの四捨五入で失敗しない2つの方法

エクセルで数値の『丸め』を行うことってありますよね。

『丸め』の代表格といえば四捨五入。

ROUND関数を思い浮かべる方も多いかと思いますが、実は少しクセがある関数なんです。

この記事では、『ROUND関数のクセを知って、四捨五入で失敗しない方法』について解説します。

1. ROUND関数のバグ?

こんにちは。エクセルマン・ブリーダーのしもむぎ(@re_znd13)です。

ROUND関数は、エクセルのヘルプによると『数値を四捨五入して指定された桁数にします』と書かれています。

一方、VBAのヘルプによると『指定した桁数に四捨五入した数値を返します』と書かれています。そして、注意点として、『この VBA 関数は、主に銀行の丸めと呼ばれるものを返します。』とも・・・

どういうことなのか、見ていきましょう。

1.1 ワークシート上とVBAで答えが異なるROUND関数

ワークシート関数としてのROUND関数と、VBA関数としてのROUND関数がどのように違うのか検証するため、簡単な実験をしてみます。

B列に0~3まで0.1刻みの数値を入力してあります。

C列はワークシート関数としてのROUND関数を使用してB列の数値を丸めます。『=round(B列, 0)』といった記述ですね。

D列は以下のようなVBAでB列の数値を丸めます。

Sub 四捨五入()
Dim i As Long
Dim x As String

For i = 2 To 32
x = Cells(i, 2).Value
Cells(i, 4).Value = Round(x, 0)
Next

End Sub
実験結果

実験結果の赤く囲った部分を見てみると・・・0.5と2.5のときの双方の答えが異なることがわかります。四捨五入としては、ワークシート関数の方が正解ですよね。一方で、青く囲った部分の1.5のときは双方の答えが正解になっています。

これってバグなのでしょうか?

1.2 バグじゃない!『丸め』の種類について

ここで、ヘルプの記述を思い出してみましょう。VBAのヘルプには注意として『銀行の丸めと呼ばれるものを返します』と書かれていました。

この銀行の丸めというのが関係ありそうですね。

そこで『丸め』というものを改めてwikipediaで調べてみると、切り捨て・切り上げ・四捨五入・五捨五超入・偶数への丸め・奇数への丸めという種類があることがわかりました。

説明を読み進めると、偶数への丸めの項目に『端数が0.5より小さいなら切り捨て、端数が0.5より大きいならは切り上げ、端数がちょうど0.5なら切り捨てと切り上げのうち結果が偶数となる方へ丸める』との記述があります。さらに、別称として『銀行家の丸め (bankers’ rounding)』との記述も。

つまり、VBA関数としてのROUND関数は四捨五入ではなく偶数への丸めを行うということなんです。

バグじゃないんですね!

2. VBAの四捨五入で失敗しない方法

日本で一般に使われるのは偶数への丸めではなく四捨五入ですよね。

上記の違いを知らずにVBAでROUND関数を使ってしまうと、おかしなことになってしまいます。

そこで、この章ではVBAの四捨五入で失敗しない方法について見ていきましょう。

2.1 WorksheetFunctionを使う方法

ワークシート関数としてのROUND関数は四捨五入を行うことが上記で確認できましたよね。

そこでひとつめは、WorksheetFunctionを使用する方法です。

WorksheetFunctionとはVBAでワークシート関数を呼び出すものです。

以下のように記述して使用します。

Sub WorksheetFunctionでの四捨五入()
Dim i As Long
Dim x As String

For i = 2 To 32
x = Cells(i, 2).Value
Cells(i, 5).Value = Application.WorksheetFunction.Round(x, 0)
Next

End Sub
WSFのround関数結果

2.2 Format関数を使う方法

もうひとつはFormat関数を使う方法です。

Format関数とは書式を設定する関数です。構文は以下の通り。

Format(Expression, [Format])

[Format]には、四捨五入した後の書式を記述します。

例えば、少数第一位を四捨五入すると整数になりますから、”0″と指定します。

少数第二位を四捨五入するときは”0.0″といった要領です。

Sub format関数での四捨五入()
Dim i As Long
Dim x As String

For i = 2 To 32
x = Cells(i, 2).Value
Cells(i, 6).Value = Format(x, "0")
Next

End Sub
Format関数結果

3. まとめ

VBAで四捨五入する方法はいかがでしたか?

よく使う四捨五入だからこそ、使いたい形の答えが得られるようにVBAの記述をしていきたいですね。