エクセルVBA業務ツール 多用途目次シートを自動増設する

vbatoclisteyecatch

エクセルVBAでハイパーリンク型では難しい、多目的に利用できる目次シートの自動作成です。
シートを改訂・変更・内容検索など、今回はシート削除機能を付加します。

こんにちは じゅんぱ店長 (@junpa33) です。

日々の業務で、溜まりに溜まった渦高いエクセルシート。

中にはシート名「〇〇〇〇(5)」とか「この子は一体誰のコピー」なんて非常に” グチャッ ”となっていることもあるかもしれません。

ちゃんとしたシート名は最低付けてあげましょう。こんなエクセルBOOKたくさん持っていませんか?

今回は、そんな大量のシートが詰まったエクセルBOOKを整理するためのツールをVBAでつくってみましょう!ということです。

そのエクセルファイルに、新たに「シートの目次」シートを自動設置し、一覧表管理からの多目的利用を出来るようにします。

一覧表は何度も更新できますので、不要なシートを整理整頓削除を行っても大丈夫です。

ちなみに、目次機能だけですが、別記事でシートリンクタイプの「シート目次」も紹介しますので、そちらもまた参考にしてください。

「プチなVBAコード」の記事一覧を開く

「エクセルVBA最速理解」の記事一覧を開く

なぜに、多目的利用の「目次シート」を作成するか

エクセルシートが大量に詰まったエクセルBOOKに目次一覧をハイパーリンクで作るというのは見かけます。

自分も一つのエクセルBOOKにシート数30(1ヶ月分)なんて普通にあります。

実際、ハイパーリンク目次を設置してもいますが、それはシートを表示するだけのもの。それが出来るだけの事でしかありません。

「で、それで・・」が次にありません。

使い道的には、目次だけを作っても次の段階の整理という作業につなげていき辛いです。

それは結局、シートの整理作業は、以前からの手作業のまま、何にも変わらないからです。

そこで、「多用途型目次シート」作成の発想に至ったのですが、

この「多用途型目次シート」作成の意味は、目次からのシート表示に続いて、その流れで、シートを改訂・変更・内容検索や削除などを出来るようにするためのベースのシートとなるものです。

今回作成するのは、シートを選択して、内容チェックで要らないなら即削除できるようなプログラムです。

もくじ一覧表を利用したシート整理ツールの1パターンを紹介していきます。

既存のエクセルBOOKに埋め込みますので、実際、プログラム起動初期では、ユーザーフォームだけが追加されるイメージです。

今回は、不要シートの整理に着目しています。削除機能シート目次一覧新設更新機能を付けています。

  1.  シート名一覧からそのページに飛んで、不要なシートを「ワンクリック削除」
  2.  削除した場合は逆ジャンプ機能で自動的にシート目次一覧に戻ることが出来る
  3.  削除したシートを排除したシート目次一覧に即更新することが出来る

というようなものに仕上げます。

目次シートを自動増設するVBAコード

「多機能シート目次.xlsm」VBAプログラムを作るために、ザックリ作業種類を書くと、

  •  標準モジュールにプログラム本体のVBAコードを張り付ける
  •  プログラムのコントロールを行うユーザーフォームを作成する
  •  本プログラムの設置先エクセルBOOKのブックモジュールに、ユーザーフォームの視覚化コードを設置する

の様になります。

プログラムをいずれかのエクセルBOOKに移植する場合に、必要なことと、必要でないこと

  • <必要なこと>「そのエクセルBOOKを、マクロ有効ブック(拡張子を.xlsm)にして変更保存することです。」
  • <必要のないこと>「プログラムを埋め込んだエクセルBOOKの名称を変更する必要はありません。」

標準モジュールにペーストする本体のVBAコード

コピペの方法はこちら↓です。

vbacopipeeyecatchWebで見つけたマクロをコピペで使う

標準モジュールにプログラム本体のVBAコードを張り付ける全コードです。

実行するためのコマンドは全て、ユーザーフォームのボタンで行います。

標準モジュール用VBAコード
Option Explicit

'解説1
Function Flag() As Boolean
    Dim ws As Worksheet
        For Each ws In ThisWorkbook.Worksheets
            If ws.Name = "もくじシート" Then
                Flag = True
                Exit For
            Else
                Flag = False
            End If
        Next
End Function


'解説2
Sub シート一覧()
    Dim s, i, BorRow As Long
    Dim mySheetName() As String
        If Flag = False Then
            ThisWorkbook.Worksheets.Add(before:=Worksheets(1)).Name = "もくじシート"
        End If
        Worksheets("もくじシート").Select
        With Worksheets("もくじシート")
            With .Cells
                .Clear
                .Font.Bold = True
                .Font.Size = 13
            End With
            .Columns(1).HorizontalAlignment = xlCenter
            .Range("A2") = "NO."
            .Range("B2") = "シート名称"
            .Range("A1") = "シートもくじからそのシートにジャンプできます。"
            With .Range("A1:B2")
                .Font.ColorIndex = 5
                .Font.Size = 15
            End With
        ReDim mySheetName(1 To Worksheets.Count)      '
            For i = 1 To Worksheets.Count
                mySheetName(i) = Worksheets(i).Name
                .Range("A" & i + 2) = i
                .Range("B" & i + 2) = mySheetName(i)
            Next i
            With .Cells(1, 1).CurrentRegion
                BorRow = .Rows(.Rows.Count).Row
                .Offset(1).Resize(BorRow - 1, 2).Borders.LineStyle = True
                .Columns(2).AutoFit
            End With
            With .Range("A1")
                .HorizontalAlignment = xlLeft
                .Select
            End With
        End With
End Sub


'解説3
Sub シートジャンプ()
    Dim shRow As Long
    Dim SV As String
    Dim ws As Worksheet
    Dim Flagn As Boolean
        If Flag = False Then
            MsgBox "もくじシートがまだ作成されていません。"
            Exit Sub
        End If
    
            Worksheets("もくじシート").Select
            shRow = Cells(Rows.Count, 2).End(xlUp).Row
            If ActiveCell.Row < shRow + 1 And ActiveCell.Column = 2 Then
                SV = ActiveCell.Value
                If SV = "もくじシート" Then
                    Exit Sub
                Else
                    For Each ws In Worksheets
                        If ws.Name = SV Then Flagn = True
                    Next ws
                    If Flagn = True Then
                        Worksheets(SV).Select
                        Range("A1").Select
                    Else
                        MsgBox SV & " シートは存在しません。", vbInformation, "メッセージ"
                    End If
                End If
            End If
End Sub


'解説4
Sub シートを削除()
Dim ActSh As String
Dim Ans As Long
Dim DelRow, n As Long
    If Flag = False Then
        MsgBox "もくじシートがまだ作成されていません。"
        Exit Sub
    End If
    ActSh = ActiveSheet.Name
    Ans = MsgBox("削除しようとしているシートは、「 " & ActSh & " 」です。" _
        & vbCrLf & "削除しますか?", vbYesNo + vbExclamation, "削除許可申請")
    If Ans = vbNo Then
        Exit Sub
    ElseIf Ans = vbYes Then
        If ActSh = "もくじシート" Then
            MsgBox "もくじシートは削除出来ません。"
        Else
        
            Worksheets(ActSh).Delete
            Worksheets("もくじシート").Select
            With Cells(1, 1).CurrentRegion
                DelRow = .Rows(.Rows.Count).Row
            End With
            For n = 3 To DelRow
                If Cells(n, 2) = ActSh Then
                    Cells(n, 2).ClearContents
                End If
            Next n
        End If
    End If
End Sub

解説1

Functionプロシージャーを使って、エクセルBOOKに「もくじシート」が作成されているかどうかをチェックしています。

作成されていれば「True」、いなければ「False」が変数「Flag」に代入されます。

解説2

「もくじシート」が作成されていなければ、新規にシートを左端に増設して「もくじシート」を作成します。

「もくじシート」が作成されていればスルーです。

左端からシートのタブ順に従って、リスト化します。

罫線を引いて一覧表を作成します。

解説3

「もくじシート」が作成されていなければ、「もくじシートがまだ作成されていません。」とメッセージが表示されこのプログラムは停止します。

選択した「シート名」のシートに移動しそのシートを開きます。

シートの指定方法は、「シート名のセル」を選択してください。

「もくじシート」に戻る場合は、「もくじシート更新」が逆ジャンプボタンを兼用しています。

解説4

「もくじシート」が作成されていなければ、「もくじシートがまだ作成されていません。」とメッセージが表示されこのプログラムは停止します。

このプログラムを実行する前に、「本当に削除するかのメッセージ」が表示されます。「はい」「いいえ」で応答します。

「はい」をクリックした場合は、エクセルのデフォルトの機能の方から「削除警告メッセージ」が再度表示されますので、さらに「削除」で削除実行されます。(2重にクリックミスを防止します。)

「もくじシート」はこの方法では削除できません。

削除完了後、「もくじシート」に自動で逆ジャンプします。シート一覧表で、削除したシート名が記入されたセルは「空白」になっています。

「もくじシート更新」ボタンをクリックすると最新のリストに改訂されます。

step1
step2
step3
step4

ユーザーフォームを作成してプログラムをコントロール

ユーザーフォームに実行ボタンを設置することで、フローティングボタンとしてシート横断で常に表示されるので、使い勝手が非常によくなります。

ユーザーフォームオブジェクト

ユーザーフォームオブジェクトはコピペが出来ませんので、自力で作成してください。

【ユーザーフォーム】のプロパティ

  •  オブジェクト名  目次コントロール
  •  Caption      目次コントロール

【もくじシート更新】のプロパティ

  •  オブジェクト名  もくじシート更新
  •  Caption      もくじシート更新

【シート表示】のプロパティ

  •  オブジェクト名  シート表示
  •  Caption      シート表示

【シート削除】のプロパティ

  •  オブジェクト名  シート削除
  •  Caption      シート削除

ユーザーフォームモジュール

ユーザーフォームに配置したコマンドボタンと、標準モジュールにある本体VBAコードを接続するVBAコードを、ユーザーフォームモジュールに記述します。

ユーザーフォームオブジェクト作成モードからの遷移は赤矢印のボタンでモジュールモードになります。

ユーザーフォームモジュール用VBAコード
Option Explicit


'解説5
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
    If CloseMode = vbFormControlMenu Then
        MsgBox "機能の性質上このボタンでは終了出来ません。"
        Cancel = True
    End If
End Sub

Private Sub シート削除_Click()
Call Module1.シートを削除
End Sub

Private Sub シート表示_Click()
Call Module1.シートジャンプ
End Sub

Private Sub もくじシート更新_Click()
Call Module1.シート一覧
End Sub

解説5

このVBAコードは、ユーザーフォームオブジェクトの右上肩にある「✖」を無効(ユーザーフォームを終了させない)にするためのコードになります。

理由ーー少々長くなりますが・・・

フーザーフォームを視覚化させるにはそのための設定コードが必要です。

通常、エクセルBOOKを立ち上げた時やシートを選択(アクティブに)した時に視覚化するようにセットします。

今回の想定では、「もくじシート」以外の全てのシートが削除可能な対象であり、また「もくじシート」もプログラム起動前では ”シートが存在しない” ということで、いずれのシートにも視覚化コードを設置することは出来ません。

ですのでつまりは、エクセルBOOKを起動したときに、視覚化するように仕組むことになります。

しかし一旦、この「✖」ボタンでユーザーフォームが閉じられてしまうと、このエクセルBOOKそのものを再起動しないとユーザーフォームが再表示されないことになってしまいます。これは大きなデメリットです。

故に

この「✖」ボタンを無効化して、エクセルBOOK起動中は常にユーザーフォームが表示されている状態にする必要があるのです。

ブックモジュールにユーザーフォーム視覚化コードを設置

最後は、ブックモジュールです。

プロジェクトエクスプローラーの「ThisWorkbook」をダブルクリックしてください。

ブックモジュール用VBAコード
Option Explicit

Private Sub Workbook_Open()
    目次コントロール.Show vbModeless
End Sub

以上でVBAコード配置等は終了です。

多用途に使える目次シートの自動設置のまとめ

みなさんが「こういう事をしたい」という場合、Webで探したコードで、プラン全体の中の半分はこれで出来る!という発見は多いでしょう。

自分のやりたいことそのことすべてが見つかるなんてことはほぼ無いので、当然と言えば当然ですが・・・。

例えば、このような目次一覧の場合なんかは、ハイパーリンクをVBAでコントロールするパターンが、ある意味メジャーです。

確かに、ハイパーリンクを使うと非常に簡単に目次一覧を作成することが出来ます。

でも今回の目的の多用途化をはかる場合には、自分的には、逆にちょっと使いずらいかなという考えです。

単にシートに飛ぶだけの目次機能を目的とするのなら、ハイパーリンクはおススメできます。

エクセルVBAを独習するのに参考書は欠かせません。 参考書選びは自分に合った「相棒」にできるものを選んでいきたいです。

今回の記事はここまでです。   最後までご覧いただき有難うございました。

<記事内容についての告知>VBAコードの記述記事においては、その記述には細心の注意をしたつもりですが、掲載のVBAコードは動作を保証するものではりません。 あくまでVBAの情報の一例として掲載しています。 掲載のVBAコードのご使用は、自己責任でご判断ください。 万一データ破損等の損害が発生しても当方では責任は負いません。