【VBA】名前定義(名前の管理)を一括作成・削除する方法(コピペOK)

VBA
スポンサーリンク
スポンサーリンク
  1. この記事でわかること
  2. どんな場面で使う?
  3. 完成イメージ(Before / After)
  4. 実行前の準備
    1. バックアップを取る
    2. Excelをマクロ有効ブック(.xlsm)で保存する
    3. シート構成を確認する(実務版で使用)
  5. 手順(コピペ → 実行まで約5分)
    1. VBE(コードを書く画面)を開く
    2. 標準モジュールを挿入する
    3. コードを貼り付けて実行する
  6. コード(基本版)– Names.Addで名前定義を作成 / Names.Deleteで削除
    1. 書き換えポイント
  7. コード(応用版)– 全名前定義の一覧取得・エラー名前の削除
  8. コード(実務版)– 一覧表から名前定義を一括登録
    1. 書き換えポイント
    2. 一覧表の例
  9. よくある落とし穴5選
    1. 1. 名前定義を削除したら #NAME? エラーが大量発生
    2. 2. RefersTo に = を付け忘れて参照先がずれる
    3. 3. 相対参照で名前定義を作ったら参照先がずれた
    4. 4. 同名の名前定義を追加したら上書きされた
    5. 5. 非表示の名前定義が残っていて名前が重複した
    6. 6. 名前定義の名前にスペースや特殊文字を使ってエラーになった
    7. 7. For Each ループの中で名前定義を削除するとコレクションがずれる
    8. VBAで名前定義の作成時にエラーが出るときの対処法
    9. VBAのNames.Addで参照先がずれるときの対処法
  10. FAQ
    1. Q1: ブックレベルとシートレベルの名前定義の違いは?
    2. Q2: 同じ名前の名前定義を追加したらどうなる?
    3. Q3: 非表示の名前定義を表示に変えたい
    4. Q4: 特定の名前定義だけ残して他を全部削除したい
    5. Q5: 名前定義の参照先を変更したい
  11. まとめ
    1. 関連記事
  12. 次にやりたくなること
  13. もっとカスタマイズしたい場合

この記事でわかること

  • VBAで名前定義を作成・削除できる(Names.Add / Names.Delete)
  • ブック内の全名前定義を一覧取得し、エラーになっている名前を検出・削除できる
  • シート上の一覧表から名前定義を一括登録できる

対象: Excel 2016以降 / Microsoft 365、Windows 10/11

どんな場面で使う?

名前定義の一括管理が役立つのは、たとえばこんな場面だ。

  • ドロップダウンリストのソース範囲を大量に登録したい — 部門名、商品カテゴリ、都道府県など、入力規則で使う名前定義を10個以上まとめて登録する場合。「名前の管理」ダイアログで1つずつ追加するのは時間がかかりすぎる
  • テンプレートの名前定義を別のブックに移植したい — 既存のテンプレートで使っている名前定義の構成を、新しいブックにそのまま再現したい場面。一覧表で管理していれば、シートごとコピーしてマクロを実行するだけで済む
  • 壊れた名前定義(#REF!エラー)を一括で掃除したい — シートの削除や移動で参照先が壊れた名前定義が溜まっていくと、「名前の管理」ダイアログが汚くなるし、数式の参照先を追うときに紛らわしい
  • 定期的に参照先が変わる名前定義を更新したい — 月次集計で「今月の売上範囲」のような名前定義の参照先を毎月更新する場合。一覧表の参照先を書き換えてマクロを実行すれば一括更新できる
  • ブック引き継ぎ時に名前定義の一覧を整理して渡したい — 前任者が作ったブックに大量の名前定義があり、どれが使われていてどれが不要か分からない。一覧取得で全体像を把握してから整理できる

名前定義はExcelの便利機能だが、数が増えると手動管理が破綻しやすい。VBAで一括処理すれば、登録も削除も棚卸しも一瞬で終わる。

完成イメージ(Before / After)

Before(名前の管理ダイアログで1つずつ手作業):

操作 所要時間
名前定義を1つ追加 約30秒
30個追加 約15分
不要な名前を探して削除 さらに数分

After(VBAで一括処理):

操作 所要時間
一覧表に名前と参照先を記入 数分
マクロ実行で一括登録 数秒
エラー名前の検出・削除 数秒

自分も以前、数十個の名前定義を1つずつ「名前の管理」ダイアログで追加していた。スクロールして確認して、新規作成して、参照先を入力して……を繰り返すうちに、どこまで設定したか分からなくなることがあった。VBAで一括登録するようにしてからは、一覧表にまとめて書くだけで数十個の名前定義が数秒で完了するようになった。追加漏れもゼロ。同じように名前定義の管理に苦労している人に、この記事で一括処理を体験してほしい。

名前定義の追加・削除は手作業だと数が増えるほど管理が大変になる。VBAで一括処理すれば速くて正確。

なお、名前定義をドロップダウンリスト(入力規則)と組み合わせて使いたい場合は 入力規則(ドロップダウンリスト)をVBAで一括設定 を参照。

実行前の準備

バックアップを取る

名前定義を削除すると、その名前を参照している数式が #NAME? エラーになる。 必ずファイルのコピーを別フォルダに保存してから実行する。

Excelをマクロ有効ブック(.xlsm)で保存する

拡張子が .xlsx のままだとマクロが保存できない。

  1. 「ファイル」→「名前を付けて保存」
  2. ファイルの種類を「Excelマクロ有効ブック (*.xlsm)」に変更
  3. 保存

シート構成を確認する(実務版で使用)

実務版コードは以下のシート構成を前提としている:

  • 一覧シート: シート名「名前定義一覧」— A列に名前、B列に参照先を記入

基本版・応用版はシート構成を問わない。

手順(コピペ → 実行まで約5分)

VBE(コードを書く画面)を開く

  1. Excelで Alt + F11 を押す

標準モジュールを挿入する

  1. VBEのメニュー →「挿入」→「標準モジュール」

コードを貼り付けて実行する

  1. コードウィンドウに、下のコードをそのままコピペする
  2. Alt + F8 → マクロ名を選んで「実行」

ボタンに割り当てれば毎回Alt+F8を押さなくて済む。方法は マクロをボタン1つで実行する方法 を参照。

コード(基本版)– Names.Addで名前定義を作成 / Names.Deleteで削除

名前定義の作成と削除の基本。まずはこの2つを押さえる。


'============================================================
' ■ 名前定義を作成する(基本版)
'   → 指定した名前と参照先で名前定義を追加
'============================================================
Sub CreateNamedRange()

    '--- ★書き換えポイント ---
    Dim nmName As String
    nmName = "売上範囲"               '← 名前定義の名前

    Dim nmRefersTo As String
    nmRefersTo = "=Sheet1!$A$1:$D$100" '← 参照先(= 付き、絶対参照)
    '--- ★ここまで ---

    '--- 名前定義を追加(同名があれば上書き)
    ThisWorkbook.Names.Add Name:=nmName, RefersTo:=nmRefersTo

    MsgBox "名前定義「" & nmName & "」を作成しました。", vbInformation

End Sub

'============================================================
' ■ 名前定義を削除する(基本版)
'   → 指定した名前の名前定義を削除
'============================================================
Sub DeleteNamedRange()

    '--- ★書き換えポイント ---
    Dim nmName As String
    nmName = "売上範囲"               '← 削除する名前定義の名前
    '--- ★ここまで ---

    '--- 名前定義が存在するか確認してから削除
    On Error Resume Next
    Dim nm As Name
    Set nm = ThisWorkbook.Names(nmName)
    On Error GoTo 0

    If nm Is Nothing Then
        MsgBox "名前定義「" & nmName & "」は存在しません。", vbExclamation
        Exit Sub
    End If

    nm.Delete
    MsgBox "名前定義「" & nmName & "」を削除しました。", vbInformation

End Sub

書き換えポイント

変数 説明 初期値
nmName 名前定義の名前 "売上範囲"
nmRefersTo 参照先(作成時のみ) "=Sheet1!$A$1:$D$100"

ポイント: RefersTo の値は必ず = 付き・絶対参照($付き) で指定する。"=Sheet1!$A$1:$D$100" のように書く。相対参照にするとアクティブセルの位置によって参照先がずれる。

基本版コードの処理の解説:

作成コード(CreateNamedRange)では、ThisWorkbook.Names.Add メソッドで名前定義を追加している。Name 引数に名前、RefersTo 引数に参照先を渡すだけのシンプルな構文だ。同名の名前定義が既に存在する場合はエラーにならず上書きされる。これは便利な反面、意図しない上書きに気づきにくいので注意が必要だ。

削除コード(DeleteNamedRange)では、まず On Error Resume Next で一時的にエラーを無視し、指定した名前が存在するか確認している。存在しない名前を直接 Names("名前").Delete で削除しようとすると実行時エラーが発生するため、先に存在チェックを入れている。On Error GoTo 0 でエラー処理を元に戻してから If nm Is Nothing Then で判定するのが定番パターンだ。名前定義の存在確認以外のエラー処理については エラー処理で止まらないマクロを作る方法 で詳しく解説している。

コード(応用版)– 全名前定義の一覧取得・エラー名前の削除

ブック内の名前定義が何個あるか分からない、どれがエラーか分からない――そんなときに使う。


'============================================================
' ■ 全名前定義の一覧をイミディエイトウィンドウに出力(応用版)
'   → 名前・参照先・スコープを一覧表示
'============================================================
Sub ListAllNames()

    Dim nm As Name
    Dim cnt As Long
    cnt = 0

    Debug.Print "===== 名前定義一覧 ====="
    Debug.Print "No.", "名前", "参照先", "表示/非表示"

    For Each nm In ThisWorkbook.Names
        cnt = cnt + 1
        Debug.Print cnt, nm.Name, nm.RefersTo, _
                   IIf(nm.Visible, "表示", "非表示")
    Next nm

    Debug.Print "===== 合計: " & cnt & " 個 ====="

    MsgBox cnt & " 個の名前定義が見つかりました。" & vbCrLf & _
           "イミディエイトウィンドウ(Ctrl+G)で一覧を確認してください。", vbInformation

End Sub

'============================================================
' ■ エラーになっている名前定義を検出・削除(応用版)
'   → 参照先が壊れている(#REF! など)名前を一括削除
'============================================================
Sub DeleteErrorNames()

    Dim nm As Name
    Dim rng As Range
    Dim errCount As Long
    Dim errList As String
    errCount = 0
    errList = ""

    For Each nm In ThisWorkbook.Names
        On Error Resume Next
        Set rng = nm.RefersToRange
        If Err.Number <> 0 Then
            errCount = errCount + 1
            errList = errList & "  " & nm.Name & " → " & nm.RefersTo & vbCrLf
            Err.Clear
        End If
        Set rng = Nothing
        On Error GoTo 0
    Next nm

    '--- エラー名前がなければ終了
    If errCount = 0 Then
        MsgBox "エラーの名前定義はありませんでした。", vbInformation
        Exit Sub
    End If

    '--- 削除確認
    Dim ans As VbMsgBoxResult
    ans = MsgBox(errCount & " 個のエラー名前定義が見つかりました。" & vbCrLf & vbCrLf & _
                 errList & vbCrLf & _
                 "すべて削除しますか?", vbYesNo + vbExclamation)

    If ans <> vbYes Then
        MsgBox "削除をキャンセルしました。", vbInformation
        Exit Sub
    End If

    '--- エラー名前を削除
    Dim delCount As Long
    delCount = 0

    For Each nm In ThisWorkbook.Names
        On Error Resume Next
        Set rng = nm.RefersToRange
        If Err.Number <> 0 Then
            nm.Delete
            delCount = delCount + 1
            Err.Clear
        End If
        Set rng = Nothing
        On Error GoTo 0
    Next nm

    MsgBox delCount & " 個のエラー名前定義を削除しました。", vbInformation

End Sub

応用版コードの処理の解説:

一覧取得コード(ListAllNames)は、For Each nm In ThisWorkbook.Names で全ての名前定義をループし、Debug.Print でイミディエイトウィンドウに出力している。nm.Visible で表示/非表示の区別もチェックしている点がポイントだ。非表示の名前定義は「名前の管理」ダイアログに表示されないため、VBAでしか確認できない。

エラー名前削除コード(DeleteErrorNames)は2段階のループで動いている。1回目のループで RefersToRange プロパティの取得を試み、エラーが発生した名前定義をリストアップする。RefersToRange は参照先をRangeオブジェクトとして返すプロパティで、参照先が壊れている場合(シートが削除された、#REF! になっている等)にはエラーが発生する仕組みだ。リストアップ結果を確認ダイアログで表示し、ユーザーが「はい」を選んだ場合のみ2回目のループで実際に削除を行う。確認ダイアログの使い方については MsgBoxで確認ダイアログを出して処理を分岐する方法 を参照。

名前定義を使ったデータ抽出の効率化については 複数条件でデータを抽出してまとめる方法 も参考になる。

コード(実務版)– 一覧表から名前定義を一括登録

実務で名前定義を管理するなら、シート上に一覧表を作って一括登録するのが最も効率的。名前定義の追加・変更・削除がすべて一覧表ベースで管理できる。

一覧表で名前定義を管理するようにしてからは、どの名前がどの範囲を指しているか一目で分かるようになった。引き継ぎ時の説明も楽になった。


'============================================================
' ■ 一覧表から名前定義を一括登録(実務版)
'   → 「名前定義一覧」シートのA列=名前、B列=参照先
'   → 既存の名前定義はクリアしてから再登録
'============================================================
Sub BulkCreateNames()

    '--- ★書き換えポイント ---
    Dim listSheet As String
    listSheet = "名前定義一覧"         '← 一覧表のシート名

    Dim nameCol As Long
    nameCol = 1                        '← 名前が入っている列(A列=1)

    Dim refCol As Long
    refCol = 2                         '← 参照先が入っている列(B列=2)

    Dim dataStartRow As Long
    dataStartRow = 2                   '← データの開始行(1行目はヘッダー)

    Dim clearExisting As Boolean
    clearExisting = False              '← True: 既存の名前定義を全削除してから登録
    '--- ★ここまで ---

    Dim wsL As Worksheet
    Set wsL = ThisWorkbook.Worksheets(listSheet)

    '--- 最終行を取得
    Dim lastRow As Long
    lastRow = wsL.Cells(wsL.Rows.Count, nameCol).End(xlUp).Row

    If lastRow < dataStartRow Then
        MsgBox "一覧表にデータがありません。", vbExclamation
        Exit Sub
    End If

    '--- 既存の名前定義をクリア(オプション)
    If clearExisting Then
        Dim ans As VbMsgBoxResult
        ans = MsgBox("既存の名前定義をすべて削除してから登録します。" & vbCrLf & _
                     "よろしいですか?", vbYesNo + vbExclamation)
        If ans <> vbYes Then
            MsgBox "処理をキャンセルしました。", vbInformation
            Exit Sub
        End If

        Dim nmDel As Name
        For Each nmDel In ThisWorkbook.Names
            nmDel.Delete
        Next nmDel
    End If

    '--- 一覧表から名前定義を一括登録
    Dim addCount As Long
    Dim skipCount As Long
    Dim errNames As String
    addCount = 0
    skipCount = 0
    errNames = ""

    Dim r As Long
    For r = dataStartRow To lastRow
        Dim nmName As String
        nmName = Trim(CStr(wsL.Cells(r, nameCol).Value))

        Dim nmRef As String
        nmRef = Trim(CStr(wsL.Cells(r, refCol).Value))

        '--- 空行はスキップ
        If nmName = "" Or nmRef = "" Then
            skipCount = skipCount + 1
            GoTo NextRow
        End If

        '--- 参照先の先頭に = がなければ付加
        If Left(nmRef, 1) <> "=" Then
            nmRef = "=" & nmRef
        End If

        '--- 名前定義を追加
        On Error Resume Next
        ThisWorkbook.Names.Add Name:=nmName, RefersTo:=nmRef
        If Err.Number <> 0 Then
            errNames = errNames & "  行" & r & ": " & nmName & "(" & Err.Description & ")" & vbCrLf
            skipCount = skipCount + 1
            Err.Clear
        Else
            addCount = addCount + 1
        End If
        On Error GoTo 0

NextRow:
    Next r

    '--- 結果を表示
    Dim msg As String
    msg = "名前定義の一括登録が完了しました。" & vbCrLf & vbCrLf & _
          "登録: " & addCount & " 個" & vbCrLf & _
          "スキップ: " & skipCount & " 個"

    If errNames <> "" Then
        msg = msg & vbCrLf & vbCrLf & "エラー:" & vbCrLf & errNames
    End If

    MsgBox msg, vbInformation

End Sub

書き換えポイント

変数 説明 初期値
listSheet 一覧表のシート名 "名前定義一覧"
nameCol 名前が入っている列 1(A列)
refCol 参照先が入っている列 2(B列)
dataStartRow データの開始行 2(1行目はヘッダー)
clearExisting 既存の名前定義を全削除するか False

一覧表の例

「名前定義一覧」シートに以下のように記入する:

A列(名前) B列(参照先)
売上範囲 Sheet1!$A$1:$D$100
商品リスト マスタ!$A$2:$A$50
税率 設定!$B$2
部門一覧 マスタ!$C$2:$C$20

ポイント: 参照先の先頭に = がなくても自動で付加される。$(絶対参照)は必ず付ける。

実務版コードの処理の解説:

このコードは一覧表シートの各行を上から順にループし、A列の名前とB列の参照先を読み取って Names.Add で登録している。空行はスキップし、参照先の先頭に = がなければ自動で付加する仕組みだ。On Error Resume Next で個別のエラーを捕捉しているため、1行でエラーが出ても残りの行の登録は続行される。エラーが出た行は名前とエラー内容をリストに溜めておき、最後にまとめて表示する。clearExisting = True に設定した場合は、登録前に既存の名前定義を全削除するが、確認ダイアログを挟むので誤操作で全削除されることはない。一覧表ベースで管理する利点は、Excelのシート上で名前と参照先を一覧で確認・編集できること、変更履歴をシートのバージョン管理で残せることだ。

名前定義とドロップダウンリストを組み合わせて使いたい場合は 入力規則(ドロップダウンリスト)をVBAで一括設定 を参照。

よくある落とし穴5選

1. 名前定義を削除したら #NAME? エラーが大量発生

自分もこれで焦った。名前定義を一括削除したら、その名前を参照していた数式が全部 #NAME? エラーになった。削除前に参照先を確認する習慣がなかった。

対策: 削除前に Ctrl+F で名前を検索し、数式で使われていないか確認する。応用版の削除コードには確認ダイアログを入れてある。

2. RefersTo に = を付け忘れて参照先がずれる

原因: RefersTo:="Sheet1!$A$1:$D$100" のように = を付け忘れると、文字列としてそのまま登録されてしまう場合がある。

対策: RefersTo:="=Sheet1!$A$1:$D$100" のように必ず先頭に = を付ける。実務版コードでは自動付加する処理を入れてある。

3. 相対参照で名前定義を作ったら参照先がずれた

原因: $ を付けずに "=Sheet1!A1:D100" と指定すると、アクティブセルの位置によって参照先がずれる。

対策: 名前定義の参照先は必ず 絶対参照($付き) で指定する。"=Sheet1!$A$1:$D$100" のように書く。

4. 同名の名前定義を追加したら上書きされた

原因: Names.Add は同名の名前定義が既にある場合、エラーにならずに上書きする。意図せず参照先が変わってしまう。

対策: 登録前に既存の名前定義を確認するか、実務版コードのように一覧表ベースで管理して上書きを把握する。

5. 非表示の名前定義が残っていて名前が重複した

原因: Visible = False の名前定義は「名前の管理」ダイアログに表示されない。VBAでしか確認できない。

対策: 応用版の一覧取得コードで「表示/非表示」列を出力しているので、非表示の名前定義も把握できる。

6. 名前定義の名前にスペースや特殊文字を使ってエラーになった

原因: 名前定義の名前にはルールがある。先頭は文字またはアンダースコアでなければならず、スペースは使えない。「売上 範囲」のように空白を含むとエラーになる。

対策: スペースの代わりにアンダースコアを使う(例: 売上_範囲)。また、名前の先頭に数字は使えないため、2024年売上 ではなく 売上_2024年 のように書く。セル参照と同じ文字列(A1R1C1 など)も名前として使えないので注意。

7. For Each ループの中で名前定義を削除するとコレクションがずれる

原因: For Each nm In ThisWorkbook.Names のループ中に nm.Delete を実行すると、Namesコレクションの要素数が変わるため、一部の名前定義がスキップされることがある。

対策: 応用版のエラー名前削除コードのように2回ループを回すか、For i = ThisWorkbook.Names.Count To 1 Step -1 でインデックスを逆順に回す方法が確実だ。行の削除と同じく、下から上(大きい番号から小さい番号)にループするのが鉄則。

VBAで名前定義の作成時にエラーが出るときの対処法

「Names.Addを実行したらエラーになって名前定義が作成できない」という場合、原因は名前の命名ルールに違反していることがほとんどだ。名前定義の名前には「先頭は文字またはアンダースコア」「スペースは使えない」「セル参照と同じ文字列(A1, R1C1等)は不可」「先頭が数字はNG」というルールがある。自分も「2024年売上」という名前を付けようとしてエラーになり、「売上_2024年」に変えたら通った。対処法は、スペースの代わりにアンダースコアを使い、先頭を文字にすること。エラーメッセージだけでは原因が分かりにくいので、名前のルールを事前に把握しておくのが大事だ。

VBAのNames.Addで参照先がずれるときの対処法

「名前定義を作成したのに、参照先が意図したセル範囲と違う」という場合、原因は参照先を相対参照($なし)で指定していることだ。RefersTo:="=Sheet1!A1:D100" のように $ を付けないと、名前定義を設定した時点のアクティブセルの位置を基準に相対的なオフセットとして解釈されてしまう。対処法は、参照先を必ず絶対参照で書くこと。RefersTo:="=Sheet1!$A$1:$D$100" のように $ を付ければ、どのセルがアクティブでも同じ範囲を指す。実務版コードでは先頭の = を自動付加する処理が入っているが、$ は自分で付ける必要があるので注意してほしい。

FAQ

Q1: ブックレベルとシートレベルの名前定義の違いは?

ブックレベルはブック内のどのシートからでも使える。シートレベルは特定のシートでのみ有効。


'--- ブックレベル(既定)
ThisWorkbook.Names.Add Name:="売上範囲", RefersTo:="=Sheet1!$A$1:$D$100"

'--- シートレベル
ThisWorkbook.Worksheets("Sheet1").Names.Add Name:="売上範囲", RefersTo:="=Sheet1!$A$1:$D$100"

Q2: 同じ名前の名前定義を追加したらどうなる?

上書きされる。エラーにはならない。意図しない上書きを防ぐには、登録前に存在確認を入れる:


Dim nm As Name
On Error Resume Next
Set nm = ThisWorkbook.Names("売上範囲")
On Error GoTo 0

If Not nm Is Nothing Then
    MsgBox "「売上範囲」は既に存在します。", vbExclamation
    Exit Sub
End If

Q3: 非表示の名前定義を表示に変えたい

VBAで Visible = True に変更する:


ThisWorkbook.Names("非表示の名前").Visible = True

Q4: 特定の名前定義だけ残して他を全部削除したい

ループ内で条件分岐する:


Dim nm As Name
For Each nm In ThisWorkbook.Names
    If nm.Name <> "残したい名前1" And nm.Name <> "残したい名前2" Then
        nm.Delete
    End If
Next nm

Q5: 名前定義の参照先を変更したい

Names.Add で同じ名前・新しい参照先を指定すると上書きで変更される:


ThisWorkbook.Names.Add Name:="売上範囲", RefersTo:="=Sheet1!$A$1:$F$200"

まとめ

  • Names.Add: 名前定義の作成。RefersTo= 付き・絶対参照で指定
  • Names.Delete: 名前定義の削除。削除前に参照している数式がないか確認
  • 一覧取得: For Each nm In ThisWorkbook.Names で全名前定義をループ
  • エラー名前: RefersToRange でエラーが出る名前定義を検出・削除
  • 一覧表から一括登録: シート上の一覧表で名前定義を管理すれば、追加・変更・引き継ぎが楽

関連記事

次にやりたくなること

名前定義の一括管理ができるようになったら、次はこのあたりを組み合わせると実務がさらに効率化する。

もっとカスタマイズしたい場合

「名前定義のルールが複雑(動的範囲やOFFSET関数を使いたい)」「複数ブックの名前定義を一括管理したい」「名前定義の変更履歴を残したい」など、業務に合わせたカスタマイズが必要な場合は、ココナラで相談できる。

相談時に伝えると話が早い情報:

  • Excel のバージョン / OS
  • 名前定義の個数と用途(数式参照・入力規則・マクロなど)
  • ブックレベル / シートレベルの使い分けの有無
  • 複数ブックでの共有が必要か

コメント

タイトルとURLをコピーしました