VBAで四捨五入や切り上げ・切り捨てを行う方法 | システムエンジニアライフ

VBAで四捨五入や切り上げ・切り捨てを行う方法

ヘッダー広告
スポンサードリンク

私は今はWebアプリケーション開発を行っておりますが、以前の職場ではVBAでの開発を行っておりました。

その為、たまにはVBAに関する記事も更新しようと思います。

ちなみに経験的にはVBAの方が長いので、Webよりも皆様の役に立てる記事が書けるとは思います。
是非ご覧ください。

当記事では、自作の関数を使用した四捨五入や切り上げ・切り捨ての方法もご紹介しています。
そのままコピーして使用できますので、是非使用してみてください。

VBAで四捨五入や切り上げ・切り捨てを行う方法

勘違いしやすいRound関数

VBAにはRound関数という関数が用意されています。
しかしRound関数を普通の四捨五入と思ってコーディングを行うと想定していない動きをすることと思います。

VBAで使用される四捨五入は”銀行型“の丸め処理を行うからです。

私たちが普段の生活の中で使用している四捨五入は、”算術型“と呼ばれるものです。

VBAのRound関数で処理される銀行型というのは、四捨五入対象の値が”5″の場合に、結果が偶数になるように切り上げられたり切り捨てられたりします。

参考:[OFFXP]VBAのRound関数について

では銀行型と算術型それぞれの四捨五入を比較してみます。

こちらをご覧ください。

計算対象 関数 VBA
1.5 2 2
2.5 3 2
3.5 4 4
4.5 5 4
5.5 6 6
6.5 7 6

こちらが計算対象の数値を、EXCELのRound関数で計算した結果と、VBAのRound関数で計算した結果を比較した結果となります。

Round関数は、「=ROUND(A2,0)」という計算式。

VBAでは以下のようなコードとなっております。

Public Sub Test()

    With ThisWorkbook.Worksheets("Sheet1")
    
        .Range("C2") = Round(.Range("A2"), 0)
        .Range("C3") = Round(.Range("A3"), 0)
        .Range("C4") = Round(.Range("A4"), 0)
        .Range("C5") = Round(.Range("A5"), 0)
        .Range("C6") = Round(.Range("A6"), 0)
        .Range("C7") = Round(.Range("A7"), 0)

    End With

End Sub

このようにVBAでRoundを行うと想定した結果が返らず困るかと思います。
そのため、今回はVBAで算術型の四捨五入を行う方法をご紹介したいと思います。

VBAで四捨五入を行う方法

EXCEL関数で四捨五入を行う

まず定番の方法ですが、Excelを使用したVBAであれば、VBA内でEXCEL関数も呼び出すことが可能です。
EXCEL関数を使用すれば、セル内の関数と同様にRound関数を呼び出すことが出来ます。

使用方法は以下の構文となります。

WorksheetFunction.Round(四捨五入対象数字, 四捨五入する桁数)

四捨五入対象数字には、四捨五入を行いたい数値を入力します。
四捨五入する桁数には、四捨五入を行う桁を指定します。

これはEXCEL関数を使用したRound関数と同じ方法での記述になりますので、そこまで迷わず使うことが可能だと思います。

VBAで使用する場合は、「WorksheetFunction.Round(.Range(“A2”), 0)」というようにすれば、VBAでも”算術型”の四捨五入が可能となります。

ですが、コードが長いため少し見にくくなってしまったり、ACCESSで使用したい場合、このような記述ではEXCEL関数は呼び出せないため、処理が複雑になってしまいます。

そのため私は自分で関数を作成して四捨五入を再現しています。 以下のコードをコピーすればそのまま使用可能ですので、是非ご使用いただければと思います。

算術型の四捨五入を行う自作の関数


自作の四捨五入関数はFunctionプロシージャを作成して使用しています。

'Round関数
'Number   ・・・ 四捨五入対象となる数値を指定する。
'Num_digits ・・・ 四捨五入後に、保有する小数点の桁数を指定する。
Public Function Round(ByVal Number As Variant, ByVal Num_digits As Long) As Variant

    Dim MidResult As Variant
    
    Number = CDec(Number)
    
    '切り捨て対象の数値(Number)に、四捨五入後の保有桁数(Num_digits)分 位上げする    ・・・①
    '切り上げ対象の数値が 0より大きい場合、①の結果に0.5を足し、小数点以下を切り捨てる   ・・・②
    '                     0より小さい場合、①の結果から0.5を引き、小数点以下を切り捨てる ・・・②
    '②の結果に対して、保有桁数(Num_digits)分 位下げする                              ・・・③
    MidResult = CDec(Number * 10 ^ Num_digits)                                          '・・・①
    MidResult = Fix(CDec(MidResult + 0.5 * Sgn(Number)))                                '・・・②
    MidResult = CDec(MidResult / 10 ^ Num_digits)                                       '・・・③
    
    Round = MidResult

End Function

上記のFunctionを使用することで、VBAでも”算術型”の四捨五入が可能となります。

切り上げ・切り捨てを行う関数

続いて切り上げ切り捨てを行う関数も紹介します。 VBAでは桁数を指定した切り上げ・切り捨てを行う関数も存在しません。
(こう考えると結構厄介な言語ですね。。。)

そこでこちらもこのようなFunctionプロシージャを作成して使用しております。

'RoundDown関数
'Number   ・・・ 切り捨て対象となる数値を指定する。
'Num_digits ・・・ 切り捨て後に、保有する小数点の桁数を指定する。
Public Function RoundDown(ByVal Number As Variant, ByVal Num_digits As Long) As Variant

    Dim MidResult As Variant
    
    Number = CDec(Number)
    
    '切り捨て対象の数値(Number)に、切り捨て後の保有桁数(Num_digits)分 位上げする  ・・・①
    '①の結果に対して、小数点以下を切り捨てる                                          ・・・②
    '②の結果に対して、保有桁数(Num_digits)分 位下げする                            ・・・③
    MidResult = CDec(Number * 10 ^ Num_digits)                                        '・・・①
    MidResult = Fix(CDec(MidResult))                                                  '・・・②
    MidResult = CDec(MidResult / 10 ^ Num_digits)                                     '・・・③
    
    RoundDown = MidResult

End Function

'RoundUp関数
'Number   ・・・ 切り上げ対象となる数値を指定する。
'Num_digits ・・・ 切り上げ後に、保有する小数点の桁数を指定する。
Public Function RoundUp(ByVal Number As Variant, ByVal Num_digits As Long) As Variant

    Dim MidResult As Variant
    
    Number = CDec(Number)
    
    '切り捨て対象の数値(Number)に、切り捨て後の保有桁数(Num_digits)分 位上げする     ・・・①
    '①の結果 - ①の結果を小数点以下切り捨てした値を計算                   ・・・②
    '計算結果が0ではない場合、①の結果に対して1を足す                    ・・・②
    '②の結果に対して、保有桁数(Num_digits)分 位下げする                 ・・・③
    MidResult = CDec(Number * 10 ^ Num_digits)                                           '・・・①
    MidResult = Fix(CDec(MidResult)) + Sgn(CDec(MidResult - RoundDown(MidResult, 0)))    '・・・②
    MidResult = CDec(MidResult / 10 ^ Num_digits)                                        '・・・③
    
    
    RoundUp = MidResult

End Function

上記の関数を呼び出すことでVBAでも四捨五入や切り上げ・切り捨てを実現することが可能となります。

2018/6/26 ご指摘いただきましたので、RoundUp関数を修正しました。
以前のロジックだと小数点切り上げ対象の桁が0 でそれ以下の小数点に値がある際に、繰り上げされないことが判明しました。
例えば、1.01を切り上げ後の小数点桁数 0 で切り上げても2になりませんでした。
そこで、今回の方法に修正し、上記の場合も繰り上げされるように対応しました。
もし修正前の関数を利用されている方は新しい関数に修正をお願いします。

さて今回はVBAを使用した四捨五入や切り上げ・切り捨ての処理方法をお伝えしました。
いづれもEXCEL関数のように使用することが出来ますので、簡単に導入いただけると思います。

もしよろしければ是非お使いください。

以上が、VBAでRound関数を使用する方法の説明となります。

フッター広告

スポンサードリンク



シェアする

  • このエントリーをはてなブックマークに追加

フォローする

コメント

  1. t-kaki より:

    この方法ですと切り上げがうまくいかないですね。
    例えば、1.01を整数に切り上げても(途中の計算で1.91となり)2になりません。
    ですので、元の値と「切下げた値」を比較してやるのがいいかと思います。
    例) 123.001を小数点以下第1位に切り上げる
    x=123.001、y=RoundDown(x,1)=123
    xy なので、RoundUp(x)=y+0.1=123.1
    ご参考まで。

    • uc4w6c より:

      t-kakiさん
      ご指摘いただきましてありがとうございます。
      確かに以前のロジックだと記載の問題が起きておりましたので、ロジックを修正しました。
      今回のRoundUpは整数部の切り上げも想定しておりましたので、アドバイスいただいた方法から少し加工して修正させていただきました。
      この度はありがとうございました。