Contents
この記事でできること
- VBAで四捨五入・切り上げ・切り捨てを正しく使い分けられる
- VBA Round関数の「銀行家の丸め」問題を回避できる
- 請求書の税込金額を端数処理方法を選んで一括計算できる
対象: Excel 2016以降 / Microsoft 365、Windows 10/11
完成イメージ(Before / After)
Before(手作業):
- 税抜金額にExcelの数式で消費税を計算
- 端数が出たら手動で四捨五入・切り上げ・切り捨て
- 100件あると計算ミスや処理漏れが起きる
- VBAのRound関数を使ったら「2.5」が「2」になって混乱
After(マクロ実行):
- 「売上一覧」シートに税抜金額を入力
- マクロを実行する
- 端数処理方法を選ぶ(1:四捨五入, 2:切り上げ, 3:切り捨て)
- 税込金額が全件一括で計算される
- 100件が数秒で完了。計算ミスゼロ
売上一覧シート(処理前):
| A | B | C | D | |
|---|---|---|---|---|
| 1 | 商品名 | 税抜金額 | 消費税 | 税込金額 |
| 2 | 商品A | 1980 | ||
| 3 | 商品B | 2550 | ||
| 4 | 商品C | 3333 |
売上一覧シート(処理後 — 四捨五入の場合):
| A | B | C | D | |
|---|---|---|---|---|
| 1 | 商品名 | 税抜金額 | 消費税 | 税込金額 |
| 2 | 商品A | 1980 | 198 | 2178 |
| 3 | 商品B | 2550 | 255 | 2805 |
| 4 | 商品C | 3333 | 333 | 3666 |
請求書のマクロを作ったとき、消費税の計算で Round(2.5, 0) と書いたら結果が「2」になった。Excelのワークシートで =ROUND(2.5, 0) と入力すると「3」になるのに、VBAだと結果が違う。バグかと思って1時間調べた。
原因はVBAのRound関数が「銀行家の丸め」という特殊なルールを使っていること。.5のときに最も近い偶数に丸めるため、2.5は2に、3.5は4になる。一般的な四捨五入とは違う。
WorksheetFunction.Round に切り替えてからは、Excelの関数と同じ結果になるので安心して金額計算ができるようになった。請求書の消費税で1円ズレる問題が完全になくなった。
VBAのRound関数の罠は、知らないと絶対にハマる。請求書の金額で1円ズレたら信用問題になる。同じ落とし穴に落ちる人を減らしたい。請求書を自動作成する方法と組み合わせれば、金額計算から請求書の作成まで一気通貫で自動化できる。
VBA Round の「銀行家の丸め」を知らないと、金額計算で確実にハマる。
事前準備
シート構成を用意する
実務版コードでは以下の構成を使う。最小版はシート構成不要(イミディエイトウィンドウで結果を確認する)。
「売上一覧」シート — 税抜金額を入力する場所
| 列 | 内容 | 例 |
|---|---|---|
| A列 | 商品名 | 商品A |
| B列 | 税抜金額 | 1980 |
| C列 | 消費税 | (マクロで計算) |
| D列 | 税込金額 | (マクロで計算) |
- 1行目はヘッダー。データは2行目から入力する
- B列が空の行が最終行として判定される
バックアップを取る
金額の計算結果をセルに書き込む処理のため、実行前にファイルのコピーを取っておくこと。テスト用のダミーデータで動作確認してから本番データで実行することを強く推奨する。
Excelをマクロ有効ブック(.xlsm)で保存する
拡張子が .xlsx のままだとマクロは保存できない。
- 「ファイル」→「名前を付けて保存」
- ファイルの種類を「Excelマクロ有効ブック (*.xlsm)」に変更
- 保存
手順(コピペ → 実行まで約5分)
VBE(コードを書く画面)を開く
- Excelで
Alt + F11を押す - VBE(Visual Basic Editor)が開く
標準モジュールを挿入する
- VBEのメニュー →「挿入」→「標準モジュール」
- 白い画面(コードウィンドウ)が表示される
コードを貼り付けて実行する
- コードウィンドウに、下のコードをそのままコピペする
- コード内の書き換えポイント(★マーク)を自分の環境に合わせて変更する
Alt + F8→ マクロ名を選んで「実行」
コード(最小版)– 端数処理の動作を確認する
まず各関数の動作を確認する。イミディエイトウィンドウ(Ctrl + Gで表示)に結果が出力される。
Sub 端数処理の動作確認()
Dim val As Double
val = 2.5
' ★ VBA Round(銀行家の丸め=偶数丸め)
Debug.Print "--- VBA Round(銀行家の丸め) ---"
Debug.Print "Round(2.5, 0) = " & Round(2.5, 0) ' → 2
Debug.Print "Round(3.5, 0) = " & Round(3.5, 0) ' → 4
Debug.Print "Round(2.15, 1) = " & Round(2.15, 1) ' → 2.2
' ★ WorksheetFunction.Round(算術丸め=一般的な四捨五入)
Debug.Print "--- WorksheetFunction.Round(算術丸め) ---"
Debug.Print "WF.Round(2.5, 0) = " & WorksheetFunction.Round(2.5, 0) ' → 3
Debug.Print "WF.Round(3.5, 0) = " & WorksheetFunction.Round(3.5, 0) ' → 4
Debug.Print "WF.Round(2.15, 1) = " & WorksheetFunction.Round(2.15, 1) ' → 2.2
' ★ WorksheetFunction.RoundUp(切り上げ)
Debug.Print "--- WorksheetFunction.RoundUp(切り上げ) ---"
Debug.Print "WF.RoundUp(2.31, 1) = " & WorksheetFunction.RoundUp(2.31, 1) ' → 2.4(小数第1位に切り上げ)
Debug.Print "WF.RoundUp(2.31, 0) = " & WorksheetFunction.RoundUp(2.31, 0) ' → 3(整数に切り上げ)
' ★ WorksheetFunction.RoundDown(切り捨て)
Debug.Print "--- WorksheetFunction.RoundDown(切り捨て) ---"
Debug.Print "WF.RoundDown(2.39, 1) = " & WorksheetFunction.RoundDown(2.39, 1) ' → 2.3(小数第1位に切り捨て)
Debug.Print "WF.RoundDown(2.39, 0) = " & WorksheetFunction.RoundDown(2.39, 0) ' → 2(整数に切り捨て)
' ★ Int / Fix の違い(負の数で差が出る)
Debug.Print "--- Int / Fix の違い ---"
Debug.Print "Int(2.9) = " & Int(2.9) ' → 2
Debug.Print "Int(-2.9) = " & Int(-2.9) ' → -3(負の無限大方向)
Debug.Print "Fix(2.9) = " & Fix(2.9) ' → 2
Debug.Print "Fix(-2.9) = " & Fix(-2.9) ' → -2(ゼロ方向)
MsgBox "イミディエイトウィンドウ(Ctrl+G)に結果を出力しました。"
End Sub
実行結果(イミディエイトウィンドウ)
--- VBA Round(銀行家の丸め) ---
Round(2.5, 0) = 2
Round(3.5, 0) = 4
Round(2.15, 1) = 2.2
--- WorksheetFunction.Round(算術丸め) ---
WF.Round(2.5, 0) = 3
WF.Round(3.5, 0) = 4
WF.Round(2.15, 1) = 2.2
--- WorksheetFunction.RoundUp(切り上げ) ---
WF.RoundUp(2.31, 1) = 2.4
WF.RoundUp(2.31, 0) = 3
--- WorksheetFunction.RoundDown(切り捨て) ---
WF.RoundDown(2.39, 1) = 2.3
WF.RoundDown(2.39, 0) = 2
--- Int / Fix の違い ---
Int(2.9) = 2
Int(-2.9) = -3
Fix(2.9) = 2
Fix(-2.9) = -2
Round(2.5, 0) が 2 になっている点に注目。これがVBA Round関数の「銀行家の丸め」。一般的な四捨五入をしたい場合は WorksheetFunction.Round を使う。
動作確認
- マクロを実行する
- 「イミディエイトウィンドウに結果を出力しました」のメッセージが出る
Ctrl + Gでイミディエイトウィンドウを表示して結果を確認する
最小版で各関数の動作が確認できたら、次の実務版に進む。
コード(実務版)– 請求書の税込金額を端数処理で一括計算
自分はこの方法で毎月の請求書の消費税計算を処理している。端数の1円ズレがなくなって安心して請求書を送れるようになった。
売上一覧の税抜金額に対して、消費税(10%)を計算し、端数処理方法を選んで一括適用する。請求書作成の全体の流れはExcelで請求書を自動作成する方法を参照。
Sub 税込金額を一括計算()
Dim ws As Worksheet
Dim lastRow As Long
Dim i As Long
Dim taxRate As Double
Dim taxAmount As Double
Dim roundMethod As String
Dim cnt As Long
' ★ シート名を指定
Set ws = Worksheets("売上一覧")
' ★ 税率を指定(10% = 0.1)
taxRate = 0.1
' ★ 最終行を取得(B列=税抜金額で判定)
lastRow = ws.Cells(ws.Rows.Count, 2).End(xlUp).Row
If lastRow < 2 Then
MsgBox "データがありません。", vbExclamation
Exit Sub
End If
' 端数処理方法を選択
roundMethod = InputBox( _
"端数処理方法を番号で入力してください。" & vbCrLf & vbCrLf & _
"1: 四捨五入" & vbCrLf & _
"2: 切り上げ" & vbCrLf & _
"3: 切り捨て", _
"端数処理の選択", "1")
If roundMethod = "" Then
Exit Sub ' キャンセル時
End If
If roundMethod <> "1" And roundMethod <> "2" And roundMethod <> "3" Then
MsgBox "1, 2, 3 のいずれかを入力してください。", vbExclamation
Exit Sub
End If
' 確認ダイアログ
Dim methodName As String
Select Case roundMethod
Case "1": methodName = "四捨五入"
Case "2": methodName = "切り上げ"
Case "3": methodName = "切り捨て"
End Select
If MsgBox((lastRow - 1) & " 件の税込金額を計算します。" & vbCrLf & _
"端数処理: " & methodName & vbCrLf & _
"税率: " & Format(taxRate * 100, "0") & "%" & vbCrLf & vbCrLf & _
"実行しますか?", vbYesNo + vbQuestion) = vbNo Then
Exit Sub
End If
On Error GoTo ErrHandler
Application.ScreenUpdating = False
For i = 2 To lastRow
' 税抜金額が数値でない場合はスキップ
If Not IsNumeric(ws.Cells(i, 2).Value) Then GoTo NextRow
If ws.Cells(i, 2).Value = "" Then GoTo NextRow
' 消費税を計算(端数処理を適用)
Select Case roundMethod
Case "1" ' 四捨五入(算術丸め)
taxAmount = WorksheetFunction.Round(ws.Cells(i, 2).Value * taxRate, 0)
Case "2" ' 切り上げ
taxAmount = WorksheetFunction.RoundUp(ws.Cells(i, 2).Value * taxRate, 0)
Case "3" ' 切り捨て
taxAmount = WorksheetFunction.RoundDown(ws.Cells(i, 2).Value * taxRate, 0)
End Select
' ★ C列に消費税、D列に税込金額を書き込む
ws.Cells(i, 3).Value = taxAmount
ws.Cells(i, 4).Value = ws.Cells(i, 2).Value + taxAmount
cnt = cnt + 1
NextRow:
Next i
' 金額列の表示形式を設定
ws.Range("B2:D" & lastRow).NumberFormat = "#,##0"
Application.ScreenUpdating = True
MsgBox cnt & " 件の税込金額を計算しました。" & vbCrLf & _
"端数処理: " & methodName, vbInformation
Exit Sub
ErrHandler:
Application.ScreenUpdating = True
MsgBox "エラーが発生しました。" & vbCrLf & _
"行番号: " & i & vbCrLf & _
Err.Description, vbCritical
End Sub
書き換えポイント
| # | 書き換え箇所 | 初期値 | 説明 |
|---|---|---|---|
| 1 | Worksheets("売上一覧") |
売上一覧 | データのシート名 |
| 2 | taxRate = 0.1 |
0.1 | 消費税率(10%)。軽減税率なら0.08 |
| 3 | ws.Cells(i, 2) |
列2(B列) | 税抜金額の列番号 |
| 4 | ws.Cells(i, 3) |
列3(C列) | 消費税の出力先列 |
| 5 | ws.Cells(i, 4) |
列4(D列) | 税込金額の出力先列 |
実務版で追加した機能
| 機能 | 説明 | 参考記事 |
|---|---|---|
| 端数処理の選択 | InputBoxで四捨五入/切り上げ/切り捨てを選択 | — |
| 確認ダイアログ | 件数+端数処理方法+税率を表示してYes/No確認 | — |
| 数値チェック | IsNumericで非数値セルをスキップ | エラー処理の方法 |
| 表示形式の自動設定 | NumberFormatで金額列にカンマ区切りを設定 | 書式を一括変更する方法 |
| 高速化 | ScreenUpdating = Falseで画面更新を停止 | — |
| エラー復帰 | On Error GoTo ErrHandlerでScreenUpdating復帰 | エラー処理の方法 |
各関数の違いと使い分け
比較表(入力値ごとの結果)
| 入力値 | VBA Round | WF.Round | WF.RoundUp | WF.RoundDown | Int | Fix |
|---|---|---|---|---|---|---|
| 2.5 | 2 | 3 | 3 | 2 | 2 | 2 |
| 3.5 | 4 | 4 | 4 | 3 | 3 | 3 |
| 2.4 | 2 | 2 | 3 | 2 | 2 | 2 |
| 2.6 | 3 | 3 | 3 | 2 | 2 | 2 |
| -2.5 | -2 | -3 | -3 | -2 | -3 | -2 |
| -2.3 | -2 | -2 | -3 | -2 | -3 | -2 |
※ 第2引数はすべて 0(整数に丸め)。WF = WorksheetFunction
使い分けの結論
| やりたいこと | 使う関数 |
|---|---|
| 一般的な四捨五入(算術丸め) | WorksheetFunction.Round(値, 桁数) |
| 切り上げ | WorksheetFunction.RoundUp(値, 桁数) |
| 切り捨て | WorksheetFunction.RoundDown(値, 桁数) |
| 正の数の整数切り捨て(高速) | Int(値) |
| 負の数も含む整数切り捨て(ゼロ方向) | Fix(値) |
| 表示上だけ丸めたい | Format(値, "書式") |
重要: VBAの Round 関数は銀行家の丸め(偶数丸め)のため、一般的な四捨五入には使わない。金額計算には WorksheetFunction.Round を使う。
第2引数(桁数)の意味
| 第2引数 | 意味 | 例(値: 1234.567) |
|---|---|---|
| 2 | 小数第2位に丸め | 1234.57 |
| 1 | 小数第1位に丸め | 1234.6 |
| 0 | 整数に丸め | 1235 |
| -1 | 十の位に丸め | 1230 |
| -2 | 百の位に丸め | 1200 |
Format関数の注意点
表示形式の変換には日付や数値の表示形式をFormatで自由に変換する方法が便利だが、Format関数は表示用の文字列を返すだけで、元の値は変わらない。
Dim val As Double
val = 1234.567
' Format関数: 表示は丸まるが、値は変わらない
Debug.Print Format(val, "#,##0.0") ' → "1,234.6"(文字列)
Debug.Print val ' → 1234.567(値はそのまま)
' WorksheetFunction.Round: 値そのものが丸まる
val = WorksheetFunction.Round(val, 1)
Debug.Print val ' → 1234.6(値が変わる)
計算に使う場合はWorksheetFunction.Roundで値を丸めてから使うこと。Format関数で丸めた「つもり」になると、合計金額がズレる原因になる。
よくある落とし穴5選
| # | 症状 | 原因 | 対策 |
|---|---|---|---|
| 1 | Round(2.5, 0) が 2 になる |
VBAのRound関数は「銀行家の丸め(偶数丸め)」を採用。.5のとき偶数側に丸める | WorksheetFunction.Round(2.5, 0) を使えば 3 になる(算術丸め) |
| 2 | Format関数で丸めたが合計が合わない | Format(val, "#,##0") は文字列を返すだけで値は変わらない。後続の計算で元の値が使われる |
計算には WorksheetFunction.Round で値を丸めてからセルに書き込む |
| 3 | Int(-2.3) が -3 になる |
Int関数は「負の無限大方向」に丸める。-2.3 → -3。ゼロ方向に切り捨てたいなら Fix(-2.3) → -2 |
負の数がある場合は Fix または WorksheetFunction.RoundDown を使う |
| 4 | 小数第2位で丸めたいのに結果がおかしい | 第2引数の桁数を間違えている。0=整数、1=小数第1位、2=小数第2位。-1=十の位 | 第2引数の一覧表を確認してから設定する |
| 5 | Round(2.15, 1) が 2.1 になる |
浮動小数点の内部表現で 2.15 が 2.14999… として格納される | WorksheetFunction.Round(2.15, 1) を使う。または通貨型(Currency)で変数を宣言する |
Format関数で “#,##0” にしたら見た目は四捨五入されたが、実際の値は元のまま。表示と値が違うことに気づかず、後続の計算で合計が合わなくなったことがある。端数処理は「見た目」ではなく「値」を変えるのが鉄則。
FAQ
Q1. VBAのRound関数とExcelのROUND関数は同じ動作?
違う。VBAのRound関数は「銀行家の丸め(偶数丸め)」、ExcelのROUND関数は「算術丸め(一般的な四捨五入)」。VBAでExcelと同じ四捨五入をするには WorksheetFunction.Round を使う。
' VBA Round(銀行家の丸め)
Debug.Print Round(2.5, 0) ' → 2
' WorksheetFunction.Round(算術丸め = ExcelのROUNDと同じ)
Debug.Print WorksheetFunction.Round(2.5, 0) ' → 3
Q2. 消費税の計算で切り捨てにしたい場合は?
WorksheetFunction.RoundDown を使う。正の数のみなら Int でも同じ結果。
Dim tax As Long
' 切り捨て(小数点以下を切り捨て)
tax = WorksheetFunction.RoundDown(1980 * 0.1, 0) ' → 198
' 正の数なら Int でも同じ
tax = Int(1980 * 0.1) ' → 198
Q3. 十の位で四捨五入したい(1234 → 1230)場合は?
第2引数に -1 を指定する。引数の「向き」に注意。正の数が小数側、負の数が整数側を指す。
Debug.Print WorksheetFunction.Round(1234, -1) ' → 1230
Debug.Print WorksheetFunction.Round(1256, -1) ' → 1260
Debug.Print WorksheetFunction.Round(1234, -2) ' → 1200
Q4. 通貨型(Currency)を使えば浮動小数点の問題は起きない?
Currency型は小数第4位まで正確に扱える固定小数点型。金額計算にはDouble型よりCurrency型が安全。ただし小数第5位以下は切り捨てられる。
Dim price As Currency
price = 2.15
Debug.Print Round(price, 1) ' → 2.2(Currency型なら正確)
Q5. 既に入力済みの金額を一括で端数処理したい
実務版コードの構成を応用する。対象範囲をループして WorksheetFunction.Round で値を上書きする。実行前にバックアップを取ること。
Sub 金額を一括四捨五入()
Dim ws As Worksheet
Dim lastRow As Long
Dim i As Long
Set ws = ActiveSheet
lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
For i = 2 To lastRow
If IsNumeric(ws.Cells(i, 1).Value) Then
ws.Cells(i, 1).Value = WorksheetFunction.Round(ws.Cells(i, 1).Value, 0)
End If
Next i
MsgBox "完了しました。"
End Sub
まとめ
この記事では、VBAで四捨五入・切り上げ・切り捨てを正しく使い分ける方法を解説した。
- 最小版: 各関数の動作をイミディエイトウィンドウで確認
- 実務版: 請求書の税込金額を端数処理方法を選んで一括計算
最も重要なポイントは VBAのRound関数は一般的な四捨五入ではない こと。金額計算には WorksheetFunction.Round を使う。
テスト用のダミーデータで動作確認してから、本番データで実行すること。
関連記事
- Excelで請求書を自動作成する方法 — 税込金額の計算を請求書作成マクロと組み合わせる
- 日付や数値の表示形式をFormatで自由に変換する方法 — Format関数の表示形式。端数処理とは異なる「表示上の丸め」
- セルの書式を一括変更する方法 — 金額のカンマ区切りや小数点の表示形式
- エラー処理の方法 — IsNumericでの数値チェックやOn Error GoToの使い方
- 日付・曜日の判定で月末処理を自動化 — 月末の請求書処理と端数処理の組み合わせ
次にやりたくなること
- 表示形式をもっと自由に変えたい → 日付や数値の表示形式をFormatで自由に変換する方法で、金額・日付・パーセントの表示形式を自在にコントロールできる
- 端数処理を含む請求書を自動作成したい → Excelで請求書を自動作成する方法で、一覧表からテンプレートに転記してPDF保存まで一括処理できる


コメント