VBAで四捨五入を行うには

VBAには四捨五入を行う関数は用意されていません。近い動きするVBA関数にROUND関数がありますが、四捨五入とは違う動きになります。

そのため別の方法を考える必要があります。方法として2つあります。

1つは正しい四捨五入を行ってくれるワークシート関数のROUND関数を使う方法で、もう1つは自作で四捨五入関数を作成することです。

それぞれについて紹介しますが、自作の四捨五入関数の方が圧倒的に処理速度が速いです。もし大量の四捨五入計算が必要な場合は自作関数の利用を検討してください。

ワークシート関数のROUND関数を使う方法

ワークシート関数を使う場合、書き方が2種類あります。Evaluateメソッドで書く方法と[]で書く方法です。どちらで書いても結果は変わりません。

以下は555.555をROUND関数で四捨五入するサンプルコードです。

 

四捨五入関数を自作する

ワークシート関数のROUND関数と同じ使い方をする関数を自作すると以下のコードのような感じになります。

四捨五入の考え方は判定桁の値が5以上であれば繰り上がり、5未満であれば繰り上がらない、となります。あとは判定桁位置とマイナスの場合の考慮を入れればOKです。

Double型同士の引き算がちょうど0.5になる場合は誤差により0.5にならず0.4999999・・となるため21行目の0.5の判定をわざと誤差を考慮して0.499としています。

Double型の代わりにCurrency型を使えば誤差は無くなりますが、小数部分が4桁までのためDouble型を使っています。

使い方

RoundEx関数の使い方です。

1番目の引数に元の数値をセットし、2番目の引数に繰り上げ対象の桁位置を指定します。

 

マイナス値の四捨五入の考え方

マイナス値の場合の四捨五入は、絶対値(プラス値)として四捨五入を行い、そのあとでマイナスにするという計算になります。この考え方はJIS規格の「JISZ8401」で示されています。

日本工業標準調査会のサイト
https://www.jisc.go.jp/app/jis/general/GnrJISSearch.html

このサイトで「Z8401」を検索する出てきます。

値の丸め方について正数で記載がされているのですが、附則部分に「負の数値を対象とする場合は、その絶対値に適用する」との内容が記載されています。ということは、マイナスの場合は一度絶対値として計算して、マイナス化する、と読めます。

なので、1.5を四捨五入すると2になるのであれば、-1.5は一度絶対数の1.5として考えて、四捨五入の2にして、マイナス化の-2となります。

ワークシート関数のROUND関数と自作関数の処理速度比較

実はこの速度比較を行うまで、ワークシート関数のROUND関数の方が処理は速いだろうなあ、と思いながらテストコードを書いてました。

ところが実際に比較してみると圧倒的に自作のRoundEx関数の方が速く、あ、そうなの?と思ってしまいました。

計測結果は以下のようになりました。

Application.Evaluate関数でのワークシート関数のROUND関数を1万回実行:5.68秒
Application.WorksheetFunction.Round関数を1万回実行:0.31秒
自作のRoundEx関数を同じく1万回実行すると、0.03秒。

ここまで違うとは思ってもみませんでした。Evaluate関数でのループ呼び出しは処理時間が掛かりますが、WorksheetFunction.Round関数と比べても自作の方が速いのは以外でした。