9/05/2021

Excel。VBA。ROUND関数をExcel VBAでつかうと四捨五入の結果が変なんです。【Rounding】

Excel。VBA。ROUND関数をExcel VBAでつかうと四捨五入の結果が変なんです。

<Excel VBA:ROUND>

四捨五入でお馴染みの、「ROUND関数」。

データをインポートした後に、ROUND関数をつかった計算式をつくるのもいいのですが、まとめて処理をしたほうが、楽だろうということで、Excel VBAでROUND関数をつかってプログラム文をつくると、普通のROUND関数と算出結果が異なるわけです。


次の表をつかって説明します。


C列は、A列÷B列で算出した結果です。


C2の数式は、

=A2/B2

としています。算出結果を四捨五入したのが、D列です。


D2の数式は、

=ROUND(C2,0)

第2引数を「0(ゼロ)」で設定したことにより、小数点第一位を四捨五入しています。


D列の算出結果は、なんら問題はないことがわかります。


E~G列は、Excel VBAでプログラム文を作ったものを実行していますが、E列のデータの一部に算出結果におかしな結果があります。

それでは、Excel VBAのプログラム文を見てみましょう。

Sub round関数()

    Dim i As Long

    Dim lastrow As Long

    

    lastrow = Cells(Rows.Count, "a").End(xlUp).Row

    

    For i = 2 To lastrow

        Cells(i, "e").Value = Round(Cells(i, "c"), 0)

        Cells(i, "f").Value = WorksheetFunction.Round(Cells(i, "c"), 0)

        Cells(i, "g").Value = Int(Cells(i, "c") + 0.5)

    Next

End Sub


簡単な説明ではありますが、変数宣言をしています。

Dim i As Long

Dim lastrow As Long

    

lastrow = Cells(Rows.Count, "a").End(xlUp).Row

「i」はこのあとのFor To Next文で使用します。

lastrowは、データの最終行の行番号を算出しています。

For To Next文でlastrowまで繰り返し実行するわけです。


For To Next文の中身を確認します。

Cells(i, "e").Value = Round(Cells(i, "c"), 0)

E列に算出しているのが、このプログラム文です。


Round(Cells(i, "c"), 0) と、Round関数を使用しています。

プログラム文自体おかしなところはありませんが、算出結果に、おかしな結果が出ているわけです。


実は、VBAのRound関数は、「四捨五入」するものではなくて、「数値を丸める」処理をする関数なのです。

4以下の場合は切り捨て、5以上の場合は切り上げという処理はしてくれないわけです。


偶数の場合、丸める値が、5だと、切り捨てをする「銀行での丸め処理」と同じで、AccessのRound関数と同じ動きをしています。


だから、通常のExcelと同じようにプログラム文をつくってしまうと、算出結果が、変わってしまうというわけです。


なので、Excel VBAで通常のExcelと同じ算出結果にしたい。

つまり通常のROUND関数と同じ算出結果にするには、次の2つの対応方法があります。


1つ目が、F列のWorksheetFunctionのROUND関数をつかいます。


WorksheetFunctionは、通常のExcel関数を用意しています。

今回のROUNDはWorksheetFunctionに用意されているので使用することができます。


WorksheetFunctionをつかったプログラム文が、

Cells(i, "f").Value = WorksheetFunction.Round(Cells(i, "c"), 0)


基本的に、WorksheetFunctionをつかうことで、問題は解決しますが、次のような方法もあります。


それが、2つ目の、

Cells(i, "g").Value = Int(Cells(i, "c") + 0.5)

これは、元の値に丸める「0.5」を加算した値を、整数化することで、ROUND関数を同じように算出することができます。


ただし、今回は、整数化した、四捨五入だったので、この数式で対応できますが、小数点第二位とか、色々かわると、加算値を考えないといけないので、WorksheetFunctionをつかうのがいいのかなと思います。


ということで、Excel VBAでROUND関数をつかうと、通常のROUND関数と算出結果が異なるので注意が必要です。