2026/06/12
【ExcelVBA】書類(請求書、見積書など)を瞬時に再利用可能にする技

【ExcelVBA】書類(請求書、見積書など)を瞬時に再利用可能にする技

以下は、見積書のサンプルになります。

このシートを再利用するために、入力済みの値を1つずつ削除するのは大変です。
そこで今回は、先頭の項目「No」を変更したときに、自動でリセットの有無を確認するメッセージを表示させ、瞬時に入力済みの値を削除できる仕組みを実現していきます。

※こちらで作成したファイルは、記事の最後にて配布しています。


1. 開発準備

以下のシートを元に作成していきます。

今回は、指定したセルを編集して確定すると同時に、メッセージを表示し、シートをリセットする仕組みを実現します。
そのような、特定のシートのセルを編集すると同時に何かしらの処理を実行するには、「シートモジュール」「イベントプロシージャ」を活用します。
シートモジュールは、対象シートのタブ上で右クリックし、[コードの表示]を選択することで表示できます。

選択すると、以下のエディタ画面(VBE)が表示されます。
また、対象シートのシートモジュールが表示された状態になります。
「Option Explicit」は、VBEの設定次第では表示されません。「Option Explicit」についての解説はこちらでは省略します。

次に、対象シートのセルを編集すると同時に処理が実行される特殊なプロシージャ(イベントプロシージャ)を用意する必要があります。
そのためには、シートモジュールの左上のリストから「Worksheet」を選択します。

「Worksheet」を選択すると、自動で「Worksheet_SelectionChange」というプロシージャが表示されます。
このプロシージャは、対象シートのいずれかのセルが選択されると同時に処理が実行されるイベントプロシージャになります。

ただ、今回使用するイベントプロシージャは、セルを編集すると同時に処理が実行されるものになります。
そのため、右上のリストから「Change」を選択します。

表示された「Worksheet_Change」というプロシージャを活用します。
「Worksheet_SelectionChange」というプロシージャは削除して問題ないです。


2. コードの記述

以下のコードを記述します。

Private Sub Worksheet_Change(ByVal Target As Range)
    
    Dim rngStr As String
    rngStr = "B4,E6:E8,B13:B17,G13:G17,I13:I17,B23"
    
    If Target.Address(False, False) = "C1" Then
        If MsgBox("リセットしますか?", vbYesNo) = vbYes Then
            Range(rngStr).Value = ""
        End If
    End If
    
End Sub

では、コードについて解説していきます。

Private Sub Worksheet_Change(ByVal Target As Range)
    
    '省略
    
End Sub

「Worksheet_Change」というプロシージャの引数「Target」に、編集されたセルの情報が渡されます。
複数セルを同時に編集した場合は、複数セルの情報が渡されます。

    Dim rngStr As String
    rngStr = "B4,E6:E8,B13:B17,G13:G17,I13:I17,B23"

rngStrという変数を用意し、その変数に「削除する対象のセルのアドレス」をカンマ区切りで指定しています。
結合されたセルの場合は、結合範囲の先頭のセルを指定します。

    If Target.Address(False, False) = "C1" Then
        If MsgBox("リセットしますか?", vbYesNo) = vbYes Then
            Range(rngStr).Value = ""
        End If
    End If

編集されたセルのアドレスをTargetから取得し、そのアドレスが「C1」であることを確認しています。

そのアドレスが「C1」のときに、「リセットしますか?」というメッセージを表示し、「はい」か「いいえ」で回答させます。

このとき、標準では「はい」にフォーカスが当たります。
そのため、メッセージが表示されたあとにEnterを押してしまうと「はい」が選択されてしまいます。
標準を「いいえ」にしたいときは、以下のように指定します。

        If MsgBox("リセットしますか?", vbYesNo + vbDefaultButton2) = vbYes Then

ここで「はい」が選択されたときに、変数「rngStr」に割り当てたセルの値を空にしています。
※ClearContentsは結合セルでは使えません。


3. 完成

以上の内容で実現できます。
先頭の項目「No」を変更したときに、自動でリセットの有無を確認するメッセージが表示されます。
そこで「はい」を選択することで、瞬時に入力済みの値が削除されます。

▼サンプルファイル▼

2026/06/05
【ExcelVBA】選択セルの行の高さを自動調整

【ExcelVBA】選択セルの行の高さを自動調整

複数行の文字がセル内に入力されていて、行の高さを高くしている場合、確認時の縦スクロールの回数が増えてしまいます。

そのため今回は、選択したセルの行の高さを自動で調整し、他のセルを選択すると同時に行の高さが初期値に戻る仕組みを実現していきます。

※こちらで作成したファイルは、記事の最後にて配布しています。


1. 仕組み

今回の仕組みは、以下のようになります。

① セルを選択すると同時に、選択しているセルの行の高さを自動調整
② 他のセルを選択すると同時に、行の高さを初期値に戻す

「① 」については、2行目以降のセルが選択されたときのみに適用します。

「② 」については、1行目の行の高さを初期値とします。

特定のシート上のセルを選択すると同時に、何かしらの処理を実行するには「シートモジュール」を活用します。


2. 開発準備

シートモジュールを開くには、対象シートのタブの上で右クリックし、[コードの表示]を選択します。

表示された画面がシートモジュールになります。

「Option Explicit」は、VBEの設定次第では表示されません。「Option Explicit」についての解説はこちらでは省略します。

次に、左上のリストから[Worksheet]を選択します。

選択すると「Worksheet_SelectionChange」というイベントプロシージャが表示されます。
万が一、異なるイベントプロシージャが表示された場合は、右上のリストから「SelectionChange」を選択してください。

このイベントプロシージャは、該当するシートのセルの選択位置が変更されると同時に実行されるものになります。


3. コードの記述

以下のコードを記述します。

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    
    Rows.RowHeight = Rows(1).RowHeight
    With Target.Rows(1)
        If .Row <> 1 Then
            .AutoFit
        End If
    End With
    
End Sub

では、コードについて解説していきます。

    Rows.RowHeight = Rows(1).RowHeight

シート上の全ての行の高さを、1行目の高さと同じにしています。

    With Target.Rows(1)
        If .Row <> 1 Then
            .AutoFit
        End If
    End With

選択しているセル(複数セルを選択しているときは先頭のセル)の行番号が1でないときに、その行の高さを自動調整しています。


4. 完成(仮)

以上の手順で、最低限の仕組みは完成です。
1行目以外のセルを選択すると同時に、その行の高さが自動調整されます。

ただ、自動調整された行の高さは、余白が少なく圧迫感があります。
そのため、以下のように余白を設けて調整されるように修正していきます。


5. コードの修正

以下の赤字のコードを追記します。

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    
    Rows.RowHeight = Rows(1).RowHeight
    With Target.Rows(1)
        If .Row <> 1 Then
            .AutoFit
            .RowHeight = .RowHeight + 15
        End If
    End With
    
End Sub

追記したコードについて解説していきます。

            .AutoFit
            .RowHeight = .RowHeight + 15

行の高さを自動調整したあとに、自動調整された行の高さを基準に15ポイント加えています。


6. 完成

以上の手順で、余白設定も完成です。
以下のように、自動調整される行の高さに15ポイントの余白が設けられます。

▼サンプルファイル▼

2026/05/15
【ExcelVBA】ボタンを押すだけで3つの表を瞬時に移動

【ExcelVBA】ボタンを押すだけで3つの表を瞬時に移動

以下の3つの表の「未定」「参加」「不参加」という見出しはボタンになっています。

移動したい値を選択して、移動先の見出しのボタンをクリックするだけで、簡単に値を移動することができます。

※こちらで作成したファイルは、記事の最後にて配布しています。

この見出しに配置したボタンをクリックするだけで、選択している値を移動することができる仕組みを作っていきます。


1. 開発準備

こちらでは、以下のシートを元に作成していきます。

シートの用意ができたら、[開発]タブから[マクロ]を選択し、表示された設定画面に「開発する機能の名前」を入力して[作成]を選択します。
まずは、「参加」の表へ移動する機能から作っていくので、こちらでは「参加」と入力しています。

次に表示される以下の画面の「Sub 参加()」から「End Sub」の間にコードを記述します。
「Option Explicit」は、VBEの設定次第では表示されません。「Option Explicit」についての解説はこちらでは省略します。


2. コードの記述

以下のコードを記述します。

Sub 参加()
    
    Dim r As Range: Set r = ActiveCell
    Dim lRow As Long
    lRow = Cells(Rows.Count, "D").End(xlUp).Row
    
    If r.Row >= 3 And _
        (r.Column = 2 Or r.Column = 4 Or r.Column = 6) Then
        
        Cells(lRow + 1, "D").Value = r.Value
        r.Delete Shift:=xlUp
        
    End If
    
End Sub

では、コードについて解説していきます。

    Dim r As Range: Set r = ActiveCell
    Dim lRow As Long
    lRow = Cells(Rows.Count, "D").End(xlUp).Row

「r」という変数にアクティブセル(選択基準のセル)の情報を割り当てています。
次に、「lRow」という変数に移動先の表の最終行の行番号を格納しています。
行番号は、D列のシート末尾のセルを基準に、「Ctrl+↑」で移動した先のセルの行番号になります。

表の中に値が1件もない場合は、見出しの行番号(2)になります。

    If r.Row >= 3 And _
        (r.Column = 2 Or r.Column = 4 Or r.Column = 6) Then
        
        Cells(lRow + 1, "D").Value = r.Value
        r.Delete Shift:=xlUp
        
    End If

アクティブセルの行番号が3以上かつ、列番号が2、4、6のいずれかの場合、要するに、3つの表のいずれかの中が選択されているときに、アクティブセルの値を「参加」の表の末尾(lRow + 1)に入力し、アクティブセルを削除して上に詰めています。

同じように、「未定」の表へ移動する機能と「不参加」の表へ移動する機能も作成します。
これらは1から作成する必要はなく、「参加」の表へ移動する機能をもとに以下のように作成します。
※「参加」の機能を複製し、赤文字の箇所のみ修正しています。

Sub 未定()
    
    Dim r As Range: Set r = ActiveCell
    Dim lRow As Long
    lRow = Cells(Rows.Count, "B").End(xlUp).Row
    
    If r.Row >= 3 And _
        (r.Column = 2 Or r.Column = 4 Or r.Column = 6) Then
        
        Cells(lRow + 1, "B").Value = r.Value
        r.Delete Shift:=xlUp
        
    End If
    
End Sub
Sub 不参加()
    
    Dim r As Range: Set r = ActiveCell
    Dim lRow As Long
    lRow = Cells(Rows.Count, "F").End(xlUp).Row
    
    If r.Row >= 3 And _
        (r.Column = 2 Or r.Column = 4 Or r.Column = 6) Then
        
        Cells(lRow + 1, "F").Value = r.Value
        r.Delete Shift:=xlUp
        
    End If
    
End Sub

機能名と移動先の列名のみ変更しています。


3. ボタンの作成

最後に実行用のボタンを用意します。
ボタンのデザインを元々の見出しに近づける場合は、[挿入]の[図形]から作成されるのがよいです。
※ボタンの存在が分かりづらくなるので、複数人で扱うファイルの場合は注意が必要です。

「未定」「参加」「不参加」の図形を見出しの位置に用意できたら、図形の上で右クリックし、[マクロの登録]から機能を割り当てます。

3つのボタンに、それぞれの機能を割り当てます。


4. 完成

以上の手順で完成です。
移動したい値を選択して、移動先の表の見出しをクリックすることで、簡単に値を移動することができます。

▼サンプルファイル▼

2026/05/01
【ExcelVBA】日付順にデータを自動追加するフォームを自作

【ExcelVBA】日付順にデータを自動追加するフォームを自作

以下の表は、予定が日付順に並んだ予定表です。

上部に用意されたフォームに「追加したい日付と予定」を入力し、「追加」ボタンを押すだけで、表の中に追加することができます。
このフォームの作成方法について解説していきます。

※こちらで作成したファイルは、記事の最後にて配布しています。


1. 開発準備

こちらでは、以下のシートを元に実現していきます。

シートの用意ができたら、[開発]タブから[マクロ]を選択し、表示された設定画面に「開発する機能の名前」を入力して[作成]を選択します。
こちらでは、「AddSchedule」と入力しています。

次に表示される以下の画面の「Sub AddSchedule()」から「End Sub」の間にコードを記述します。
「Option Explicit」は、VBEの設定次第では表示されません。「Option Explicit」についての解説はこちらでは省略します。


2. コードの記述

以下のコードを記述します。

Sub AddSchedule()
    
    Dim lRow As Long
    lRow = Cells(Rows.Count, "B").End(xlUp).Row + 1
    
    Cells(lRow, "B").Value = Range("C2").Value
    Cells(lRow, "C").Value = Range("C3").Value
    
    Range("C2:C3").ClearContents
    
    Range("B5", Cells(lRow, "C")).Sort _
        Key1:=Range("B5"), _
        Order1:=xlAscending, _
        Header:=xlYes
    
End Sub

では、コードについて解説していきます。

    Dim lRow As Long
    lRow = Cells(Rows.Count, "B").End(xlUp).Row + 1

「lRow」という変数に、予定表の末尾の一つ下の行番号を格納しています。
行番号は、B列の最終行のセルを基準に、「Ctrl+↑」で移動した先のセルの行番号に1を加えた数値としています。

    Cells(lRow, "B").Value = Range("C2").Value
    Cells(lRow, "C").Value = Range("C3").Value
    
    Range("C2:C3").ClearContents

先ほど取得した行番号(lRow)の行のB列にフォームの日付、C列にフォームの予定を入力してから、フォームを空にしています。

    Range("B5", Cells(lRow, "C")).Sort _
        Key1:=Range("B5"), _
        Order1:=xlAscending, _
        Header:=xlYes

セルB5を基準とした表の、セルB5の項目(日付)を基準に昇順「小さい順」に並べ替えています。


3. ボタンの作成

最後に実行用のボタンを用意します。
ボタンは、[開発]タブの[挿入]から作成することができます。
作成したボタンには、開発した機能「AddSchedule」を割り当てます。


4. 完成

以上の手順で完成です。
フォームに「追加したい日付と予定」を入力し、「追加」ボタンを押すだけで、表の中に追加することができます。

▼サンプルファイル▼

2026/04/24
【ExcelVBA】同じメールアドレスの前後のデータに遷移するボタン

【ExcelVBA】同じメールアドレスの前後のデータに遷移するボタン

以下のようにお問い合わせ内容を管理している場合、同じ人のお問い合わせ内容を確認するたびに絞り込みをするのは大変になります。

ということで今回は、「前へ」と「次へ」のボタンを押すだけで、選択行と同じメールアドレスの1つ前(次)の行に移動できる仕組みを作っていきます。

※見出し行はウィンドウ枠を固定しています。
※こちらで作成したファイルは、記事の最後にて配布しています。


1. 開発準備

こちらでは、以下のファイルを元に実現していきます。

新しいお問い合わせ内容が、表の末尾に追加される運用をイメージしています。
必要に応じて、「日付」などの項目を追加してください。

上記のファイルの用意ができたら、[開発]タブから[マクロ]を選択し、表示された設定画面に「開発する機能の名前」を入力して[作成]を選択します。
まずは、1つ前の行を選択する機能から実現していくため、こちらでは「PrevData」と入力しています。

次に表示される以下の画面の「Sub PrevData」から「End Sub」の間にコードを記述します。
「Option Explicit」は、VBEの設定次第では表示されません。「Option Explicit」についての解説はこちらでは省略します。


2. コードの記述

以下のコードを記述します。

Sub PrevData()
    
    Dim r1 As Long: r1 = ActiveCell.Row
    Dim r2 As Long
    For r2 = r1 - 1 To 2 Step -1
        If Cells(r1, "C").Value = Cells(r2, "C").Value Then
            Cells(r2, "A").Activate
            Exit Sub
        End If
    Next r2
    
End Sub

上記のコードを記述できたら、複製して、以下のように一部を修正したコードを追加します。
※異なる箇所を赤色にしています。

Sub NextData()
    
    Dim r1 As Long: r1 = ActiveCell.Row
    Dim r2 As Long
    For r2 = r1 + 1 To Cells(Rows.Count, "C").End(xlUp).Row
        If Cells(r1, "C").Value = Cells(r2, "C").Value Then
            Cells(r2, "A").Activate
            Exit Sub
        End If
    Next r2
    
End Sub

では、コードについて解説していきます。

Sub PrevData()
    
    Dim r1 As Long: r1 = ActiveCell.Row
    Dim r2 As Long
    For r2 = r1 - 1 To 2 Step -1
        '省略
    Next r2
    
End Sub

こちらは、選択している行と同じメールアドレスの1つ前の行に移動する処理になります。
変数「r1」に選択しているセルの行番号を格納し、変数「r2」に「変数「r1」-1」から「2」まで数値を1つずつ減らして「For~Next」の中を繰り返し実行しています。

        If Cells(r1, "C").Value = Cells(r2, "C").Value Then
            Cells(r2, "A").Activate
            Exit Sub
        End If

繰り返し処理の中では、選択している行(「r1」行目)のC列の値(メールアドレス)と比較対象の行(「r2」行目)のC列の値(メールアドレス)が一致しているかどうかを確認しています。
一致している場合は、比較対象の行(「r2」行目)のA列のセルを選択して、処理を終了しています。

Sub NextData()
    
    Dim r1 As Long: r1 = ActiveCell.Row
    Dim r2 As Long
    For r2 = r1 + 1 To Cells(Rows.Count, "C").End(xlUp).Row
        '省略
    Next r2
    
End Sub

こちらは、選択している行と同じメールアドレスの1つ次の行に移動する処理になります。
1つ前の行に移動する処理との大きな違いは、変数「r2」の数値を繰り返す範囲です。
1つ次の行になるので、範囲は「変数「r1」+1」から「表の最終行の行番号」になります。
「表の最終行の行番号」は、C列の末尾のセルを基準に「Ctrl+↑」で移動した先のセルの行番号としています。

他の処理は、1つ前の行に移動する処理と同じになります。


3. ボタンの作成

コードが完成したら、実行用のボタンを用意します。

ボタンは、[開発]タブの中の[挿入]から作成することができます。
ボタンには開発した機能を割り当てます。

・「前へ」ボタン:PrevData
・「次へ」ボタン:NextData

必要に応じて、見出しのウィンドウ枠を固定するとよいです。


4. 完成

以上の手順で完成です。

適当な行を選択して、「前へ」もしくは「次へ」のボタンを選択したときに、選択行と同じメールアドレスのデータが前(次)の行に存在する場合は、その行のA列のセルに遷移します。

▼サンプルファイル▼

2026/04/17
【ExcelVBA】書類に名前を差し込んで100人分のPDFを一括出力

【ExcelVBA】書類に名前を差し込んで100人分のPDFを一括出力

以下のフォーマットの氏名の部分(○○ ○○)に、隣の「名簿」シートの100人分の氏名を1つずつ入力してPDFファイルで出力する必要があるとします。

この作業を1件ずつ行うのは、かなり大変です。

ということで今回は、100人分のPDFファイルを自動で出力する仕組みの実現方法について解説していきます。

※こちらで作成したファイルは、記事の最後にて配布しています。


1. 開発準備

以下の2つのシートを元に作成していきます。

こちらでは、「名簿」シートの各行の氏名を1つずつ、「修了証」シートの「○○ ○○」が入力されたセルに入力して、PDFファイルで保存する流れを自動化します。
出力されるPDFファイルの名前は、「(対象氏名).pdf」とします。

まず初めに、[開発]タブを選択し、[マクロ]を選択します。

表示された以下の画面に開発する機能の名前を入力し、[作成]を選択します。
こちらでは、「一括PDF出力」と入力しています。

次に表示される以下の画面の「Sub 一括PDF出力」から「End Sub」の間にコードを記述します。
「Option Explicit」は、VBEの設定次第では表示されません。「Option Explicit」についての解説はこちらでは省略します。


2. コードの記述

以下のコードを記述します。

Sub 一括PDF出力()

    Dim ws1 As Worksheet
    Dim ws2 As Worksheet
    Set ws1 = Worksheets("修了証")
    Set ws2 = Worksheets("名簿")
    
    Dim i As Long, sPath As String
    For i = 3 To 102
        sPath = "A:\出力\" & ws2.Cells(i, "B").Value & ".pdf"
        ws1.Range("C3").Value = _
            ws2.Cells(i, "B").Value
        ws1.ExportAsFixedFormat _
            Type:=xlTypePDF, _
            Filename:=sPath
    Next i

End Sub

では、コードについて解説していきます。

    Dim ws1 As Worksheet
    Dim ws2 As Worksheet
    Set ws1 = Worksheets("修了証")
    Set ws2 = Worksheets("名簿")

「ws1」という変数に「修了証」シートの情報、「ws2」という変数に「名簿」シートの情報を割り当てています。

    Dim i As Long, sPath As String
    For i = 3 To 102
        '省略
    Next i

「名簿」シートの3行目から102行目の氏名に対し、1つずつPDFファイルを出力する処理を行っています。

        sPath = "A:\出力\" & ws2.Cells(i, "B").Value & ".pdf"

各行の氏名に対し、「sPath」という変数に、保存先の情報とPDFファイルの名前を指定しています。
こちらでは、Aドライブの中の出力フォルダのパスに、「名簿」シートの該当行のB列の氏名を加え、最後に「.pdf」と拡張子を加えています。

保存先を変更する場合は、ここのパスを変更します。

        ws1.Range("C3").Value = _
            ws2.Cells(i, "B").Value
        ws1.ExportAsFixedFormat _
            Type:=xlTypePDF, _
            Filename:=sPath

「修了証」シートのセルC3(セルが結合されている場合は左上のセル)に、「名簿」シートの該当行の氏名を入力しています。

そして、「修了証」シートの印刷範囲をPDFファイルで出力しています。

PDFファイルの出力ではなく印刷したい場合は、以下のように指定します。

ws1.PrintOut

3. 完成

左上のリストから「一括PDF出力」を選択し、実行ボタンを押すことで、100人分のPDFファイルが出力されます。

▼サンプルファイル▼

2026/04/10
【ExcelVBA】複数の書類テンプレートを一元管理

【ExcelVBA】複数の書類テンプレートを一元管理

こちらでは、複数の書類テンプレートを1つのファイルで管理し、かつ上書き保存させずに、指定した書類テンプレートで簡単に新規作成することができる仕組みを作っていきます。

具体的には、以下のように各シートの書類テンプレートの上に、「このテンプレートを使用する」というボタンを配置し、そのボタンを押すことで、そのシートのみが新規ブックにコピーされるという仕組みを実現します。

新規ブックにコピーされるので、誤って上書き保存する心配がありません。

※こちらで作成したファイルは、記事の最後にて配布しています。


1. 開発準備

こちらでは、以下のファイルを元に実現していきます。

こちらのファイルは、複数の書類テンプレートをシートごとで管理したものです。
必要に応じて、シートを追加していただいても問題ございません。

今回は、上記のファイルを活用して、「選択しているシートのみを新規ブックにコピーする」という機能を実装していきます。
ファイルの用意ができたら、[開発]タブから[マクロ]を選択し、表示された設定画面に「開発する機能の名前」を入力して[作成]を選択します。
こちらでは、「CopyTemplateSheet」と入力しています。

次に表示される以下の画面の「Sub ○○」から「End Sub」の間にコードを記述します。
「Option Explicit」は、VBEの設定次第では表示されません。「Option Explicit」についての解説はこちらでは省略します。


2. コードの記述

以下のコードを記述します。

Sub CopyTemplateSheet()

    ActiveSheet.Copy
    
    Dim ws As Worksheet
    Set ws = ActiveSheet
    
    Dim i As Long
    For i = ws.Shapes.Count To 1 Step -1
        If ws.Shapes(i).Type = msoFormControl Then
            If ws.Shapes(i).FormControlType = xlButtonControl Then
                ws.Shapes(i).Delete
            End If
        End If
    Next i
    
End Sub

では、コードについて解説していきます。

    ActiveSheet.Copy
    
    Dim ws As Worksheet
    Set ws = ActiveSheet

選択中のシートを新規ブックにコピーし、そのコピーしたシートの情報を「ws」という変数に割り当てています。

    Dim i As Long
    For i = ws.Shapes.Count To 1 Step -1
        If ws.Shapes(i).Type = msoFormControl Then
            If ws.Shapes(i).FormControlType = xlButtonControl Then
                ws.Shapes(i).Delete
            End If
        End If
    Next i

コピーされたシート上の「図形の末尾の通し番号」から順番に繰り返し、指定した番号の図形がフォームコントロール(msoFormControl)であり、さらにボタン(xlButtonControl)の場合に、その図形を削除しています。

この処理は、最終的に用意する「このテンプレートを使用する」というボタンを、コピーされたシートから削除するためのものです。

末尾の通し番号から順番に繰り返している理由は、図形を削除したときに番号がずれてしまわないようにするためです。


3. ボタンの作成

コードが完成したら、実行用のボタンを用意します。

ボタンは、[開発]タブの中の[挿入]から作成することができます。
ボタンには開発した機能「CopyTemplateSheet」を割り当てます。

ボタンを1つ作成したら、そのボタンをコピーし、他のシートにも貼り付けます。

ご自身で書類テンプレートのシートを追加された際は、同様に同じボタンを貼り付けます。


4. 完成

以上の手順で完成です。
使用したい書類テンプレートのシートを選択して、そのシート上の「このテンプレ-トを使用する」のボタンをクリックするだけで、そのシートが新規ブックにコピーされます。
また、そのコピーされたシートからは「このテンプレートを使用する」のボタンのみが削除されます。

他にもボタン以外の図形が含まれる場合でも、ボタン以外の図形は削除されません。

▼サンプルファイル▼

2026/03/27
【ExcelVBA】入力後に好みのセルに移動する技(入力順を自由に指定)

【ExcelVBA】入力後に好みのセルに移動する技(入力順を自由に指定)

以下は、請求書のフォーマットのサンプルになります。

このフォーマットに以下の順番で値を入力するとき、毎回カーソルを移動するのは面倒になります。

そこで今回は、セルF3に値を入力して確定したらセルF4、セルF4に値を入力して確定したらセルB4と、好みの順番で遷移させる仕組みの実現方法について解説していきます。

※こちらで作成したファイルは、記事の最後にて配布しています。


1. 開発準備

以下のフォーマットを元に作成していきます。

今回は、セルを編集して確定すると同時に、予め指定したセルに遷移させる仕組みを実現します。
そのような、特定のシートのセルを編集すると同時に何かしらの処理を実行するには、「シートモジュール」「イベントプロシージャ」を活用します。
シートモジュールは、対象シートのタブ上で右クリックし、[コードの表示]を選択することで表示できます。

選択すると、以下のエディタ画面(VBE)が表示されます。
また、対象シートのシートモジュールが表示された状態になります。
「Option Explicit」は、VBEの設定次第では表示されません。「Option Explicit」についての解説はこちらでは省略します。

次に、対象シートのセルを編集すると同時に処理が実行される特殊なプロシージャ(イベントプロシージャ)を用意する必要があります。
そのためには、シートモジュールの左上のリストから「Worksheet」を選択します。

「Worksheet」を選択すると、自動で「Worksheet_SelectionChange」というプロシージャが表示されます。
このプロシージャは、対象シートのいずれかのセルが選択されると同時に処理が実行されるイベントプロシージャになります。

ただ、今回使用するイベントプロシージャは、セルを編集すると同時に処理が実行されるものになります。
そのため、右上のリストから「Change」を選択します。

表示された「Worksheet_Change」というプロシージャを活用します。
「Worksheet_SelectionChange」というプロシージャは削除して問題ないです。


2. コードの記述

以下のコードを記述します。

Private Sub Worksheet_Change(ByVal Target As Range)

    Select Case Target.Address(False, False)
        Case "F3"
            Range("F4").Select
        Case "F4"
            Range("B4").Select
        Case "B4"
            Range("C7").Select
        Case "C7"
            Range("C8").Select
        Case "C8"
            Range("C9").Select
        Case "C9"
            Range("B14").Select
    End Select

End Sub

では、コードについて解説していきます。

Private Sub Worksheet_Change(ByVal Target As Range)

    '省略

End Sub

「Worksheet_Change」というプロシージャの引数「Target」に、編集されたセルの情報が渡されます。
複数セルを同時に編集した場合は、複数セルの情報が渡されます。

    Select Case Target.Address(False, False)
        Case "F3"
            Range("F4").Select
        Case "F4"
            Range("B4").Select
        Case "B4"
            Range("C7").Select
        Case "C7"
            Range("C8").Select
        Case "C8"
            Range("C9").Select
        Case "C9"
            Range("B14").Select
    End Select

編集されたセルのアドレスを相対参照(F3やF4など)で取得し、取得されたアドレスに対しての遷移先を指定しています。
セルF3が編集された場合は、「Case “F3″」の中が実行され、セルF4が選択されます。
セルF4が編集された場合は、「Case “F4″」の中が実行され、セルB4が選択されます。
候補にないアドレスの場合は、何も実行されません。


3. 完成

以上の内容で実現できます。
編集されたセルのアドレスが、予め指定したアドレスの場合は、指定したセルに自動で遷移します。

以下の表の中は、標準機能で簡単に移動できます。

表の中の移動については、以下の記事を参考にしてください。
>【Excel】表へのデータ入力を快適にするテクニック

▼サンプルファイル▼

2026/03/20
【ExcelVBA】進捗を「完了」にすると同時に日付を自動入力

【ExcelVBA】進捗を「完了」にすると同時に日付を自動入力

以下は、簡易的なタスク管理表です

このタスク管理表の運用として、項目[進捗]が「完了」になった時に項目[完了日]を毎回入力している場合、少し手間になります。

そこで今回は、こちらのタスク管理表をもとに、項目[進捗]が「完了」になったときに自動で項目[完了日]に本日の日付を入力する仕組みを実現していきます。

※こちらで作成したファイルは、記事の最後にて配布しています。


1. 開発準備

今回は、以下の表をもとに作成していきます。

今回実現する仕組みは、この表の項目[進捗]が「完了」になったときに自動で項目[完了日]に本日の日付を入力するというものです。

このように、特定のシートのセルが編集されると同時に、何かしら処理を実行するには「シートモジュール」「イベントプロシージャ」を活用します。
シートモジュールは、該当するシートのタブ上で右クリックし、[コードの表示]を選択することで表示できます。

選択すると、以下のエディタ画面(VBE)が表示されます。
また、該当するシートのシートモジュールが表示された状態になります。
「Option Explicit」は、VBEの設定次第では表示されません。「Option Explicit」についての解説はこちらでは省略します。

次に、特定のシートのセルが編集されると同時に処理が実行される特殊なプロシージャ(イベントプロシージャ)を用意する必要があります。
そのためには、シートモジュールの左上のリストから「Worksheet」を選択します。

「Worksheet」を選択すると、自動で「Worksheet_SelectionChange」というプロシージャが表示されます。
このプロシージャは、該当するシートのいずれかのセルが選択されると同時に処理が実行されるイベントプロシージャです。

ただ、今回使用するイベントプロシージャは、セルが編集されると同時に処理が実行されるものになります。
そのため、右上のリストから「Change」を選択します。

表示された「Worksheet_Change」というプロシージャを活用します。
「Worksheet_SelectionChange」というプロシージャは削除して問題ないです。


2. コードの記述

以下のコードを記述します。

Private Sub Worksheet_Change(ByVal Target As Range)
    
    Dim t As Range
    
    Application.EnableEvents = False
    
    For Each t In Target
        If t.Row >= 3 And _
            t.Column = 4 And _
            t.Value = "完了" Then
            
            Cells(t.Row, "E").Value = Date
            
        End If
    Next t
    
    Application.EnableEvents = True
    
End Sub

では、コードについて解説していきます。

Private Sub Worksheet_Change(ByVal Target As Range)
    
    Dim t As Range
    
    Application.EnableEvents = False
    
    For Each t In Target
        '省略
    Next t
    
    Application.EnableEvents = True
    
End Sub

「Worksheet_Change」というプロシージャの引数「Target」に、編集されたセルの情報が渡されます。
複数セルを同時に編集した場合は、複数セルの情報が渡されます。

こちらでは、編集された1つ1つのセルの情報を受け取る用の「t」という入れ物(変数)を用意し、その「t」にセルの情報を1つ1つ渡して、繰り返して実行しています。

また、今回の処理の中には「完了日を入力する」という処理が含まれます。
この処理により、セルが編集されて再度プロシージャが実行されてしまうので、処理の開始でイベント実行を無効にし(Application.EnableEvents = False)、処理の終了で有効に戻しています(Application.EnableEvents = True)。

        If t.Row >= 3 And _
            t.Column = 4 And _
            t.Value = "完了" Then
            
            Cells(t.Row, "E").Value = Date
            
        End If

繰り返し処理の中で、対象のセルの行番号が3以上、列番号が4、値が「完了」かどうかを確認しています。
要するに、表の中の項目[進捗]に「完了」が入力されたかどうかを確認し、この条件を満たしたときのみ、Ifの中の処理を実行するように記述しています。

Ifの中の処理では、同じ行のE列(項目[完了日])に本日の日付(Date)を入力しています。


3. 完成

以上の内容で実現できます。
項目[進捗]に「完了」と入力すると、同じ行の項目[完了日]に本日の日付が入力されます。
※以下の例では、項目[進捗]にドロップダウンリストを設定しています。

▼サンプルファイル▼

2026/03/13
【ExcelVBA】データに紐づいた管理フォルダを自動作成

【ExcelVBA】データに紐づいた管理フォルダを自動作成

以下のExcelで作られた表は、その各データとエクスプローラー上のフォルダをハイパーリンクで紐づけています。

このようなハイパーリンクを作成する場合、1つ1つ手動で設定するのは大変です。

そこで今回は、「フォルダ」の項目をダブルクリックするだけで、管理フォルダとハイパーリンクを自動で作成する仕組みを作っていきます。

※こちらで作成したファイルは、記事の最後にて配布しています。


1. 開発準備

以下の表を元に作成していきます。

セルA2には、管理フォルダを自動で作成する位置のパスを入力しています。

今回は、「フォルダ」の項目をダブルクリックすることで、その行のデータと紐づいた管理フォルダとハイパーリンクを作成する仕組みを実現します。

そのような、特定のシートのセルをダブルクリックしたときに何かしら処理を実行するには、「シートモジュール」「イベントプロシージャ」を活用します。
シートモジュールは、該当するシートのタブ上で右クリックし、[コードの表示]を選択することで表示できます。

選択すると、以下のエディタ画面(VBE)が表示されます。
また、該当するシートのシートモジュールが表示された状態になります。
「Option Explicit」は、VBEの設定次第では表示されません。「Option Explicit」についての解説はこちらでは省略します。

次に、該当するシートのセルをダブルクリックしたときに処理が実行される特殊なプロシージャ(イベントプロシージャ)を用意する必要があります。
そのためには、シートモジュールの左上のリストから「Worksheet」を選択します。

「Worksheet」を選択すると、自動で「Worksheet_SelectionChange」というプロシージャが表示されます。
このプロシージャは、該当するシートのいずれかのセルが選択されると同時に処理が実行されるイベントプロシージャです。

ただ、今回使用するイベントプロシージャは、セルをダブルクリックしたときに処理が実行されるものになります。
そのため、右上のリストから「BeforeDoubleClick」を選択します。

表示された「Worksheet_BeforeDoubleClick」というプロシージャを活用します。
「Worksheet_SelectionChange」というプロシージャは削除して問題ないです。


2. コードの記述

以下のコードを記述します。

Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
    
    Dim t As Range: Set t = Target
    Dim fPath As String
    
    If t.Row >= 5 And t.Column = 5 And  _
        t.Value = "" And _
        Cells(t.Row, "A").Value <> "" And _
        Cells(t.Row, "B").Value <> "" Then
        
        Cancel = True
        
        fPath = Range("A2").Value & _
                    "\" & _
                    Cells(t.Row, "A").Value & _
                    "_" & _
                    Cells(t.Row, "B").Value
        
        MkDir fPath
        
        Me.Hyperlinks.Add _
            Anchor:=t, _
            Address:=fPath, _
            TextToDisplay:="開く"
        
    End If
    
End Sub

では、コードについて解説していきます。

Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
    
    Dim t As Range: Set t = Target
    Dim fPath As String
    
    If t.Row >= 5 And t.Column = 5 And  _
        t.Value = "" And _
        Cells(t.Row, "A").Value <> "" And _
        Cells(t.Row, "B").Value <> "" Then
        
        '省略
        
    End If
    
End Sub

「Worksheet_BeforeDoubleClick」というプロシージャの引数「Target」に、ダブルクリックされたセルの情報が渡されます。
そのセルの情報を「t」という名前の入れ物(変数)に格納し、以下の条件を満たしているセルがダブルクリックされたかどうかを確認します。

・行番号が5以上
・列番号が5(E列)
・セルが空
・同じ行のA列が空でない(「ID」の項目)
・同じ行のB列が空でない(「プロジェクト」の項目)

この条件は、管理フォルダを作成する際に必要な条件になります。
すでに管理フォルダが作成されている場合は再度作成する必要はないですし、
今回は管理フォルダを「ID_プロジェクト」という名前で自動作成するので、表の「ID」と「プロジェクト」の項目が空の場合は管理フォルダを作成することができません。
そのため、上記の条件を満たした場合のみに、Ifの中の処理(’省略)を実行するようにしています。

        Cancel = True
        
        fPath = Range("A2").Value & _
                    "\" & _
                    Cells(t.Row, "A").Value & _
                    "_" & _
                    Cells(t.Row, "B").Value
        
        MkDir fPath

条件を満たしたセルがダブルクリックされたときは、セルの編集モードをキャンセルします。

次に、「fPath」という名前の入れ物(変数)に作成するフォルダのパスを格納し、「MkDir」でフォルダを作成します。
「fPath」に格納しているパスは以下になります。

セルA2のパス + 「\」 + 対象行のA列のID + 「_」 + 対象行のB列のプロジェクト
        Me.Hyperlinks.Add _
            Anchor:=t, _
            Address:=fPath, _
            TextToDisplay:="開く"

シートモジュールに対応したシート内に、ダブルクリックされたセル(t)に「管理フォルダ(fPath)を表示するハイパーリンク」を作成します。
セルには「開く」と表示します。


3. 完成

以上の内容で実現できます。
ハイパーリンクが設定されていない「フォルダ」の項目をダブルクリックするだけで、対象データの管理フォルダとハイパーリンクが自動で作成されます。

▼サンプルファイル▼

2026/03/06
【ExcelVBA】チェックしたら行が自動で非表示になる表

【ExcelVBA】チェックしたら行が自動で非表示になる表

以下の表のように、チェックボックスにチェックすると同時に、その行が自動で非表示になる仕組みを実現する方法について解説していきます。

※こちらで作成したファイルは、記事の最後にて配布しています。

今回の仕組みでは、チェックすると同時に自動でフィルター機能が実行され絞り込みされます。
そのため、フィルター機能を解除することで、簡単に再表示することもできます。


1. 開発準備

今回は、以下の表をもとに作成していきます。
あらかじめ、「済」の項目にチェックボックスを用意しています。

チェックボックスが用意されているセルには、TRUE(チェックされている)/FALSE(チェックされていない)の値が入力されます。
今回は、用意したチェックボックスをチェックすると同時に、フィルター機能による絞り込み(「済」がFALSEの行のみを表示)を実行します。

このように特定のシート上のセルが編集されると同時に、何かしら処理を実行するには、「シートモジュール」「イベントプロシージャ」を活用します。
シートモジュールは、該当するシートのタブ上で右クリックし、[コードの表示]を選択することで表示できます。

選択すると、以下のエディタ画面(VBE)が表示されます。
また、該当するシートのシートモジュールが表示された状態になります。
「Option Explicit」は、VBEの設定次第では表示されません。「Option Explicit」についての解説はこちらでは省略します。

次に、特定のシート上のセルが編集されると同時に処理が実行される特殊なプロシージャ(イベントプロシージャ)を用意する必要があります。
そのためには、シートモジュールの左上のリストから「Worksheet」を選択します。

「Worksheet」を選択すると、自動で「Worksheet_SelectionChange」というプロシージャが表示されます。
このプロシージャは、該当するシート上のいずれかのセルが選択されると同時に処理が実行されるイベントプロシージャです。

ただ、今回使用するイベントプロシージャは、セルが編集されると同時に処理が実行されるものになります。
そのため、右上のリストから「Change」を選択します。

表示された「Worksheet_Change」というプロシージャを活用します。
「Worksheet_SelectionChange」というプロシージャは削除して問題ないです。


2. コードの記述

以下のコードを記述します。

Private Sub Worksheet_Change(ByVal Target As Range)
    
    If Target.CountLarge >= 100 Then Exit Sub
    
    Dim t As Range
    For Each t In Target
        If t.Row >= 3 And t.Row <= 15 And _
            t.Column = 2 Then
            
            Range("B2").AutoFilter 1, False
            Exit Sub
            
        End If
    Next t
    
End Sub

では、コードについて解説していきます。

Private Sub Worksheet_Change(ByVal Target As Range)
    
    If Target.CountLarge >= 100 Then Exit Sub
    
    Dim t As Range
    For Each t In Target
        '省略
    Next t
    
End Sub

「Worksheet_Change」というプロシージャの引数「Target」に、編集されたセルの情報が渡されます。
複数セルを同時に編集した場合は、複数セルの情報が渡されます。

こちらでは、編集された1つ1つのセルに対して処理を実行します。
そのため編集されたセルが多い場合は処理が重たくなってしまうため、100セル以上が同時に編集された場合は処理を終了しています。

次に、編集された1つ1つのセルの情報を受け取る用の「t」という入れ物(変数)を用意し、その「t」にセルの情報を1つ1つ渡して、繰り返して実行しています。

        If t.Row >= 3 And t.Row <= 15 And _
            t.Column = 2 Then
            
            Range("B2").AutoFilter 1, False
            Exit Sub
            
        End If

繰り返し処理の中で、対象のセルの行番号が3以上、15未満、列番号が2のとき、要するに、チェックボックスの範囲内が編集されたときに、チェックされていない行のみをフィルター機能で絞り込みしています。

1回絞り込みを行えば、繰り返し行う必要はないので、処理を終了しています。


3. 完成

以上の内容で実現できます。
チェックボックスにチェックするだけで、その行がフィルター機能により非表示になります。

▼サンプルファイル▼

2026/02/27
【ExcelVBA】クリックするだけで別表に集計して追加

【ExcelVBA】クリックするだけで別表に集計して追加

「商品を選んだら別の表に追加し、同じ商品なら数量を加算」
この処理を右クリックだけで実現する方法について解説していきます。

※こちらで作成したファイルは、記事の最後にて配布しています。


1. 開発準備

今回は、以下の表(商品一覧とカート)を元に作成していきます。

特定のセルの上で右クリックすることで何かしら処理を実行するには、「シートモジュール」「イベントプロシージャ」を活用します。
シートモジュールは、該当するシートのタブ上で右クリックし、[コードの表示]を選択することで表示できます。

選択すると、以下のエディタ画面(VBE)が表示されます。
また、該当するシートのシートモジュールが表示された状態になります。
「Option Explicit」は、VBEの設定次第では表示されません。「Option Explicit」についての解説はこちらでは省略します。

次に、該当するシートのセルの上で右クリックすると同時に処理が実行される特殊なプロシージャ(イベントプロシージャ)を用意する必要があります。
そのためには、シートモジュールの左上のリストから「Worksheet」を選択します。

「Worksheet」を選択すると、自動で「Worksheet_SelectionChange」というプロシージャが表示されます。
このプロシージャは、該当するシート上のいずれかのセルが選択されると同時に処理が実行されるイベントプロシージャです。

ただ、今回使用するイベントプロシージャは、セルの上で右クリックすると同時に処理が実行されるものになります。
そのため、右上のリストから「BeforeRightClick」を選択します。

表示された「Worksheet_BeforeRightClick」というプロシージャを活用します。
「Worksheet_SelectionChange」というプロシージャは削除して問題ないです。


2. コードの記述

以下のコードを記述します。

Private Sub Worksheet_BeforeRightClick(ByVal Target As Range, Cancel As Boolean)
    
    Dim t As Range: Set t = Target
    
    If t.Row >= 4 And _
        t.Column >= 2 And t.Column <= 4 And _
        t.CountLarge = 1 And _
        Cells(t.Row, "B").Value <> "" Then
        
        Cancel = True
        
        Dim lRow As Long, r As Long, f As Boolean
        lRow = Cells(Rows.Count, "F").End(xlUp).Row
        f = False
        
        For r = 4 To lRow
            If Cells(r, "F").Value = Cells(t.Row, "B").Value Then
                f = True
                Cells(r, "H").Value = Cells(r, "H").Value + 1
            End If
        Next r
        
        If Not f Then
            Cells(lRow + 1, "F").Value = Cells(t.Row, "B").Value
            Cells(lRow + 1, "G").Value = Cells(t.Row, "C").Value
            Cells(lRow + 1, "H").Value = 1
        End If
        
    End If
    
End Sub

では、コードについて解説していきます。

Private Sub Worksheet_BeforeRightClick(ByVal Target As Range, Cancel As Boolean)
    
    Dim t As Range: Set t = Target
    
    If t.Row >= 4 And _
        t.Column >= 2 And t.Column <= 4 And _
        t.CountLarge = 1 And _
        Cells(t.Row, "B").Value <> "" Then
        
        '省略
        
    End If
    
End Sub

「Worksheet_BeforeRightClick」というプロシージャの引数「Target」に、右クリックされたセルの情報が渡されます。
複数範囲を選択している範囲の上で右クリックした場合は、複数セルの情報が渡されます。

次に、そのセルの情報を「t」という名前の入れ物(変数)に格納し、その「t」を活用して、対象の範囲上で右クリックされたかどうかを確認します。

対象の範囲とは、以下の条件を満たす範囲です。

・行番号が4以上
・列番号が2以上4以下
・単体のセル
・そのセルと同じ行のB列が空でない

要するに、商品一覧の表の中かつ商品が入力されている行の上で、単体のセルが右クリックされた場合に処理を実行するようにしています。

        Cancel = True
        
        Dim lRow As Long, r As Long, f As Boolean
        lRow = Cells(Rows.Count, "F").End(xlUp).Row
        f = False

対象の範囲内で、単体のセルが右クリックされた場合に、右クリック時のメニュー表示を無効にし、「lRow」と「r」という数値専用(Long)の入れ物(変数)、「f」という論理値専用(Boolean:True / Falseのみ)の入れ物(変数)を用意しています。

「lRow」には、カートの表の最終行の行番号を格納しています。
最終行の行番号は以下のように取得しています。

F列の末尾のセルを選択し、「Ctrl+↑」で移動した先のセルの行番号

そのため、カートの表にデータが1件も存在しない場合は、見出しの行である「3」が取得されます。

「r」には何も格納せず、「f」には「False」を格納しています。

        For r = 4 To lRow
            If Cells(r, "F").Value = Cells(t.Row, "B").Value Then
                f = True
                Cells(r, "H").Value = Cells(r, "H").Value + 1
            End If
        Next r

カートの4行目から最終行(lRow)まで繰り返し、右クリックされた商品(B列のID)と一致する商品(F列のID)を探します。
一致する商品が見つかった場合は、「f」を「True」にして、その見つかったカートの行のH列の数量に「1」を加えています。

        If Not f Then
            Cells(lRow + 1, "F").Value = Cells(t.Row, "B").Value
            Cells(lRow + 1, "G").Value = Cells(t.Row, "C").Value
            Cells(lRow + 1, "H").Value = 1
        End If

「f」が「False」の場合、要するに、先ほどの繰り返しで一致する商品が見つからなかった場合に、カートの末尾(lRow + 1)のF列に右クリックされた商品のID(B列)、G列に商品名(C列)、H列に「1」を入力しています。


3. 完成

以上の内容で実現できます。
商品一覧の表の中の、IDが入力された行のいずれかのセルを右クリックすることで、隣の表のカートに、その商品を追加することができます。

▼サンプルファイル▼