Contents
この記事でできること
- VBAで数値を0埋め(ゼロパディング)して桁を揃えられる
- Format関数・Right関数・NumberFormatの違いを理解して使い分けられる
- 管理番号を0埋め付き連番で自動採番できる(例: INV-001, INV-002…)
対象: Excel 2016以降 / Microsoft 365、Windows 10/11
完成イメージ(Before / After)
Before(手作業):
- 管理番号を手入力で「001, 002, 003…」と入力
- Excelが先頭のゼロを消して「1, 2, 3…」になる
- セルの書式を「文字列」に変えたり、アポストロフィを付けたり試行錯誤
- 並べ替えると「1, 10, 11, 2, 20…」の順になって混乱
After(マクロ実行):
- 「管理台帳」シートにデータを入力
- マクロを実行する
- 管理番号が「INV-001, INV-002, INV-003…」と自動採番される
- 100件が数秒で完了。桁が揃って見やすく、ソートも正しい順番
管理台帳シート(処理前):
| A | B | C | |
|---|---|---|---|
| 1 | 管理番号 | 品名 | 登録日 |
| 2 | ノートPC | 2026/01/15 | |
| 3 | モニター | 2026/02/01 | |
| 4 | キーボード | 2026/03/10 |
管理台帳シート(処理後):
| A | B | C | |
|---|---|---|---|
| 1 | 管理番号 | 品名 | 登録日 |
| 2 | INV-001 | ノートPC | 2026/01/15 |
| 3 | INV-002 | モニター | 2026/02/01 |
| 4 | INV-003 | キーボード | 2026/03/10 |
管理台帳で連番を振ったとき、「1, 2, 3…」のままだとエクスプローラーやExcelで並べ替えると「1, 10, 11, 2, 20…」の順になった。ファイル名に連番を付けたときも同じ問題が起きた。ファイル名を一括変更する方法でリネームマクロを作ったときにこの問題にぶつかった。
Format関数で「001, 002, 003…」と0埋めしてからは、ソートしても正しい順番になるし、見た目も揃って一覧が見やすくなった。取引先に送る管理番号も統一感が出て、業務の信頼性が上がった。
0埋めは地味だが、管理番号・ファイル名・伝票番号など使う場面が多い。Format関数とRight関数の違い、NumberFormat(表示形式)との違いを整理しておけば迷わなくなる。自動連番を振る方法と組み合わせれば、管理番号の採番から連番管理まで一気通貫で自動化できる。
0埋めは「見た目」の話ではなく「値」の話。NumberFormatと混同すると、VLOOKUPで一致しなくなる。
事前準備
シート構成を用意する
実務版コードでは以下の構成を使う。最小版はシート構成不要(イミディエイトウィンドウで結果を確認する)。
「管理台帳」シート — 管理番号を採番する場所
| 列 | 内容 | 例 |
|---|---|---|
| A列 | 管理番号 | INV-001(マクロで採番) |
| B列 | 品名 | ノートPC |
| C列 | 登録日 | 2026/01/15 |
- 1行目はヘッダー。データは2行目から入力する
- A列が空の行に管理番号を採番する
- B列にデータがある行を処理対象とする
バックアップを取る
管理番号をセルに書き込む処理のため、実行前にファイルのコピーを取っておくこと。テスト用のダミーデータで動作確認してから本番データで実行することを強く推奨する。
Excelをマクロ有効ブック(.xlsm)で保存する
拡張子が .xlsx のままだとマクロは保存できない。
- 「ファイル」→「名前を付けて保存」
- ファイルの種類を「Excelマクロ有効ブック (*.xlsm)」に変更
- 保存
手順(コピペ → 実行まで約5分)
VBE(コードを書く画面)を開く
- Excelで
Alt + F11を押す - VBE(Visual Basic Editor)が開く
標準モジュールを挿入する
- VBEのメニュー →「挿入」→「標準モジュール」
- 白い画面(コードウィンドウ)が表示される
コードを貼り付けて実行する
- コードウィンドウに、下のコードをそのままコピペする
- コード内の書き換えポイント(★マーク)を自分の環境に合わせて変更する
Alt + F8→ マクロ名を選んで「実行」
コード(最小版)– 数値を0埋めして桁を揃える
まずFormat関数・Right関数・NumberFormatの動作を確認する。イミディエイトウィンドウ(Ctrl + Gで表示)に結果が出力される。
Sub ゼロパディングの動作確認()
Dim num As Long
' ★ Format関数で0埋め(推奨)
Debug.Print "--- Format関数で0埋め ---"
Debug.Print "Format(1, ""000"") = " & Format(1, "000") ' → "001"
Debug.Print "Format(42, ""000"") = " & Format(42, "000") ' → "042"
Debug.Print "Format(999, ""000"") = " & Format(999, "000") ' → "999"
Debug.Print "Format(1000, ""000"") = " & Format(1000, "000") ' → "1000"(桁超えはそのまま)
' ★ Right関数で0埋め
Debug.Print "--- Right関数で0埋め ---"
Debug.Print "Right(""000"" & 1, 3) = " & Right("000" & 1, 3) ' → "001"
Debug.Print "Right(""000"" & 42, 3) = " & Right("000" & 42, 3) ' → "042"
Debug.Print "Right(""000"" & 999, 3) = " & Right("000" & 999, 3) ' → "999"
Debug.Print "Right(""000"" & 1000, 3) = " & Right("000" & 1000, 3) ' → "000"(★危険: 桁溢れで先頭が切れる)
' ★ 桁数を変えたい場合
Debug.Print "--- 桁数を変える ---"
Debug.Print "Format(7, ""0000"") = " & Format(7, "0000") ' → "0007"(4桁)
Debug.Print "Format(7, ""00000"") = " & Format(7, "00000") ' → "00007"(5桁)
' ★ 接頭辞を付ける場合
Debug.Print "--- 接頭辞付き ---"
Debug.Print "INV-" & Format(1, "000") ' → "INV-001"
Debug.Print "INV-" & Format(42, "000") ' → "INV-042"
Debug.Print "ORD-" & Format(7, "0000") ' → "ORD-0007"
' ★ NumberFormat(セルの表示形式)との違い
' ※ テスト用にJ20セルを一時使用します(実行後にクリアします)
Debug.Print "--- NumberFormatとの違い ---"
Dim ws As Worksheet
Set ws = ActiveSheet
ws.Cells(20, 10).Value = 1
ws.Cells(20, 10).NumberFormat = "000"
Debug.Print "セルの表示: " & ws.Cells(20, 10).Text ' → "001"(見た目)
Debug.Print "セルの値: " & ws.Cells(20, 10).Value ' → 1(数値のまま)
Debug.Print "TypeName: " & TypeName(ws.Cells(20, 10).Value) ' → "Double"
ws.Cells(20, 10).Clear ' テスト用セルをクリア
' ★ 文字列として0埋めした場合のソートの利点
Debug.Print "--- ソートの比較 ---"
Debug.Print "数値のまま(辞書順): 1, 10, 11, 2, 20, 3"
Debug.Print "0埋め文字列(辞書順): 001, 002, 003, 010, 011, 020"
MsgBox "イミディエイトウィンドウ(Ctrl+G)に結果を出力しました。"
End Sub
実行結果(イミディエイトウィンドウ)
--- Format関数で0埋め ---
Format(1, "000") = 001
Format(42, "000") = 042
Format(999, "000") = 999
Format(1000, "000") = 1000
--- Right関数で0埋め ---
Right("000" & 1, 3) = 001
Right("000" & 42, 3) = 042
Right("000" & 999, 3) = 999
Right("000" & 1000, 3) = 000
--- 桁数を変える ---
Format(7, "0000") = 0007
Format(7, "00000") = 00007
--- 接頭辞付き ---
INV-001
INV-042
ORD-0007
--- NumberFormatとの違い ---
セルの表示: 001
セルの値: 1
TypeName: Double
--- ソートの比較 ---
数値のまま(辞書順): 1, 10, 11, 2, 20, 3
0埋め文字列(辞書順): 001, 002, 003, 010, 011, 020
Right("000" & 1000, 3) が "000" になっている点に注目。Right関数は桁溢れで先頭が切れる。Format関数なら "1000" とそのまま表示される。基本はFormat関数を使う。
動作確認
- マクロを実行する
- 「イミディエイトウィンドウに結果を出力しました」のメッセージが出る
Ctrl + Gでイミディエイトウィンドウを表示して結果を確認する
最小版でFormat関数・Right関数・NumberFormatの違いが確認できたら、次の実務版に進む。
コード(実務版)– 管理番号を0埋め付き連番で自動採番
自分はこの方法で備品管理台帳の管理番号を採番している。0埋めで桁が揃うので一覧が見やすく、ソートしても正しい順番になる。
管理台帳の空欄に対して、接頭辞+0埋め連番(INV-001形式)を自動採番する。連番の自動採番の基本的な考え方は自動連番を振る方法を参照。
Sub 管理番号を自動採番()
Dim ws As Worksheet
Dim lastRow As Long
Dim i As Long
Dim nextNum As Long
Dim maxNum As Long
Dim prefix As String
Dim digits As Long
Dim currentID As String
Dim numPart As Long
Dim cnt As Long
' ★ シート名を指定
Set ws = Worksheets("管理台帳")
' ★ 接頭辞を指定(例: "INV-", "ORD-", "EMP-")
prefix = "INV-"
' ★ 連番の桁数を指定(3なら001~999)
digits = 3
' ★ 最終行を取得(B列=品名で判定)
lastRow = ws.Cells(ws.Rows.Count, 2).End(xlUp).Row
If lastRow < 2 Then
MsgBox "データがありません。", vbExclamation
Exit Sub
End If
' 既存の最大連番を取得
maxNum = 0
For i = 2 To lastRow
currentID = CStr(ws.Cells(i, 1).Value)
If Left(currentID, Len(prefix)) = prefix Then
' 接頭辞以降の数値部分を取得
numPart = Val(Mid(currentID, Len(prefix) + 1))
If numPart > maxNum Then
maxNum = numPart
End If
End If
Next i
nextNum = maxNum + 1
' 採番対象の空欄をカウント
Dim emptyCount As Long
For i = 2 To lastRow
If ws.Cells(i, 1).Value = "" And ws.Cells(i, 2).Value <> "" Then
emptyCount = emptyCount + 1
End If
Next i
If emptyCount = 0 Then
MsgBox "採番対象の空欄がありません。", vbInformation
Exit Sub
End If
' 確認ダイアログ
' ★ String(digits, "0") は "0" を digits 回繰り返す(例: String(3, "0") → "000")
If MsgBox(emptyCount & " 件の管理番号を採番します。" & vbCrLf & _
"形式: " & prefix & Format(nextNum, String(digits, "0")) & " ~" & vbCrLf & vbCrLf & _
"実行しますか?", vbYesNo + vbQuestion) = vbNo Then
Exit Sub
End If
On Error GoTo ErrHandler
Application.ScreenUpdating = False
For i = 2 To lastRow
' A列(管理番号)が空かつB列(品名)にデータがある行を採番対象にする
If ws.Cells(i, 1).Value = "" And ws.Cells(i, 2).Value <> "" Then
' ★ 接頭辞 + 0埋め連番を書き込む
' String(digits, "0") で桁数分の "0" を生成(例: String(3, "0") → "000")
ws.Cells(i, 1).Value = prefix & Format(nextNum, String(digits, "0"))
nextNum = nextNum + 1
cnt = cnt + 1
End If
Next i
Application.ScreenUpdating = True
MsgBox cnt & " 件の管理番号を採番しました。" & vbCrLf & _
"形式: " & prefix & "XXX", vbInformation
Exit Sub
ErrHandler:
Application.ScreenUpdating = True
MsgBox "エラーが発生しました。" & vbCrLf & _
"行番号: " & i & vbCrLf & _
Err.Description, vbCritical
End Sub
書き換えポイント
| # | 書き換え箇所 | 初期値 | 説明 |
|---|---|---|---|
| 1 | Worksheets("管理台帳") |
管理台帳 | データのシート名 |
| 2 | prefix = "INV-" |
INV- | 管理番号の接頭辞。”ORD-“や”EMP-“など自由に変更可 |
| 3 | digits = 3 |
3 | 連番の桁数。3なら001~999、4なら0001~9999 |
| 4 | ws.Cells(i, 1) |
列1(A列) | 管理番号の出力先列 |
| 5 | ws.Cells(i, 2) |
列2(B列) | データ有無の判定列(品名列) |
実務版で追加した機能
| 機能 | 説明 | 参考記事 |
|---|---|---|
| 接頭辞の指定 | prefix変数で接頭辞を自由に変更可能 | — |
| 桁数の指定 | digits変数で連番の桁数を変更可能 | — |
| 既存番号の継続 | 既存の最大連番を取得して続きから採番 | 自動連番を振る方法 |
| 確認ダイアログ | 対象件数+開始番号を表示してYes/No確認 | — |
| 空欄のみ採番 | A列が空の行だけを対象にするため、既存データは上書きしない | — |
| 高速化 | ScreenUpdating = Falseで画面更新を停止 | — |
| エラー復帰 | On Error GoTo ErrHandlerでScreenUpdating復帰 | — |
Format vs Right vs NumberFormat の使い分け
3つの方法の比較
| 項目 | Format関数 | Right関数 | NumberFormat |
|---|---|---|---|
| 構文 | Format(num, "000") |
Right("000" & num, 3) |
Range.NumberFormat = "000" |
| 戻り値 | 文字列 | 文字列 | –(セルの表示を変更) |
| セルの値 | 文字列(”001″) | 文字列(”001″) | 数値(1) |
| 桁溢れ時 | そのまま表示(安全) | 先頭が切れる(危険) | そのまま表示(全桁表示) |
| VLOOKUPでの照合 | 文字列として一致 | 文字列として一致 | 数値として照合(文字列の”001″とは不一致) |
| 計算での利用 | 数値に戻す必要あり | 数値に戻す必要あり | そのまま計算可能 |
| 推奨場面 | 管理番号・伝票番号 | 簡易的な0埋め | 表示上だけ桁を揃えたい場合 |
使い分けの結論
| やりたいこと | 使う方法 |
|---|---|
| 管理番号や伝票番号として0埋めしたい | Format(num, "000") を使い、文字列としてセルに書き込む |
| 簡易的に0埋めしたい(桁溢れしない前提) | Right("000" & num, 3) でもOK |
| 見た目だけ揃えたい(値は数値のまま) | Range.NumberFormat = "000" |
| 数値として計算に使いつつ見た目を揃えたい | NumberFormat で表示形式を設定 |
重要: NumberFormat = “000” はセルの「表示形式」を変更するだけで、値は数値のまま。セルの書式を一括変更する方法で解説している通り、表示と値は別物。管理番号として文字列で扱いたい場合はFormat関数を使う。
NumberFormatの落とし穴(見た目 vs 値)
NumberFormatで「000」を設定したら見た目は0埋めされたが、セルの値は数値のまま。VLOOKUPで文字列の管理番号と照合したら一致しなくてハマったことがある。
' NumberFormat: 見た目だけ変わる
Range("A1").Value = 1
Range("A1").NumberFormat = "000"
Debug.Print Range("A1").Text ' → "001"(見た目)
Debug.Print Range("A1").Value ' → 1(値は数値のまま)
' Format関数: 文字列として0埋め
Range("A2").Value = Format(1, "000")
Debug.Print Range("A2").Text ' → "001"(見た目)
Debug.Print Range("A2").Value ' → "001"(値も文字列)
' VLOOKUPでの違い
' A1(NumberFormat): 数値1 → 文字列"001"では検索ヒットしない
' A2(Format関数): 文字列"001" → 文字列"001"で検索ヒットする
表示形式の詳細は日付や数値の表示形式をFormatで自由に変換する方法を参照。型変換の仕組みは型変換の方法で解説している。
よくある落とし穴5選
| # | 症状 | 原因 | 対策 |
|---|---|---|---|
| 1 | Right("000" & 1000, 3) が "000" になる |
Right関数は右から指定文字数を取得するため、桁溢れで上位桁が消える | Format(1000, "000") を使えば "1000" とそのまま表示される |
| 2 | NumberFormatで0埋めしたがVLOOKUPで一致しない | NumberFormat = "000" は表示形式の変更のみ。セルの値は数値のまま |
文字列として0埋めしたいなら Format 関数でセルに書き込む |
| 3 | 0埋めした文字列を Val で数値に戻したら0が消えた |
Val("007") → 7。数値に変換すると先頭のゼロは消える仕様 |
数値に戻す必要がある場合は Val の動作を理解して使う。再度0埋めするなら Format を再適用 |
| 4 | セルに直接「001」と入力しても「1」になる | Excelは数値として認識できる入力を自動的に数値に変換する | VBAから Cells(i,1).Value = Format(num, "000") で書き込むか、セルの書式を事前に「文字列」に設定 |
| 5 | 途中から桁数を変えたら過去データと不整合になった | “000” → “0000” に変更すると、過去は3桁・新規は4桁で混在する | 最初に最大桁数を決めておく。変更する場合は過去データも一括変換する |
NumberFormatで「000」を設定したら見た目は0埋めされたが、セルの値は数値のまま。VLOOKUPで文字列の管理番号と照合したら一致しなくてハマった。0埋めは「見た目」ではなく「値」を文字列として設定するのが鉄則。
FAQ
Q1. Format関数とRight関数、どちらを使うべき?
基本は Format関数を推奨。桁溢れ時に安全(切り詰めずにそのまま表示)。Right関数は桁溢れで先頭が切れるリスクがある。
' Format関数(安全): 桁数を超えてもそのまま表示
Debug.Print Format(1000, "000") ' → "1000"
' Right関数(危険): 桁数を超えると先頭が切れる
Debug.Print Right("000" & 1000, 3) ' → "000" ← 意図しない結果
Q2. 5桁に0埋めしたい場合は?
Format の書式文字列の 0 の数を5つにする。
Debug.Print Format(7, "00000") ' → "00007"
Debug.Print Format(42, "00000") ' → "00042"
Debug.Print Format(12345, "00000") ' → "12345"
Q3. 0埋めした文字列を数値に戻すには?
Val 関数または CLng 関数で変換できる。型変換の詳細は型変換の方法を参照。
Debug.Print Val("007") ' → 7
Debug.Print CLng("007") ' → 7
Debug.Print Val("INV-007") ' → 0(数値以外が含まれると0になる)
' 接頭辞付きの場合はMidで数値部分を抜き出す
Debug.Print Val(Mid("INV-007", 5)) ' → 7
Q4. NumberFormatとFormat関数の違いは?
NumberFormatはセルの「表示形式」を変えるだけで値は数値のまま。Format関数は「文字列」として0埋めした値を返す。管理番号として使うならFormat関数。
' NumberFormat: 表示だけ変わる
Range("A1").Value = 1
Range("A1").NumberFormat = "000"
' → 見た目: 001、値: 1(数値)
' Format関数: 値が文字列になる
Range("A2").Value = Format(1, "000")
' → 見た目: 001、値: "001"(文字列)
Q5. ファイル名に0埋め連番を付けたい
Format関数で0埋めした文字列をファイル名に組み込む。ファイル名を一括変更する方法と組み合わせて使える。
Dim fileName As String
Dim i As Long
For i = 1 To 10
fileName = "報告書_" & Format(i, "000") & ".xlsx"
Debug.Print fileName
' → 報告書_001.xlsx, 報告書_002.xlsx, ...
Next i
まとめ
この記事では、VBAで数値を0埋め(ゼロパディング)して桁を揃える方法を解説した。
- 最小版: Format関数・Right関数・NumberFormatの動作をイミディエイトウィンドウで確認
- 実務版: 管理番号を0埋め付き連番で自動採番(INV-001形式)
最も重要なポイントは NumberFormat(表示形式)とFormat関数(文字列変換)は別物 ということ。管理番号として使うなら Format(num, "000") で文字列として書き込む。
テスト用のダミーデータで動作確認してから、本番データで実行すること。
関連記事
- 自動連番を振る方法 — 0埋め連番と組み合わせて管理番号の自動採番に使える
- 日付や数値の表示形式をFormatで自由に変換する方法 — Format関数の書式パターン一覧。0埋め以外の数値・日付変換にも対応
- 型変換の方法 — Val / CStr / CLng など、文字列と数値の相互変換
- セルの書式を一括変更する方法 — NumberFormatの設定方法。表示形式と値の違い
- ファイル名を一括変更する方法 — ファイル名に0埋め連番を付けたいときに使える
次にやりたくなること
- 連番をもっと本格的に管理したい → 自動連番を振る方法で、重複チェック・欠番検出・連番リセットまで対応できる
- 日付や通貨の表示も自由に変えたい → 日付や数値の表示形式をFormatで自由に変換する方法で、Format関数の全パターンを網羅できる


コメント