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/04/03
【Excel】更新不要!商品ごとの最新価格を数式で自動抽出

【Excel】更新不要!商品ごとの最新価格を数式で自動抽出

以下の表は、商品の価格を管理したものです。
最新の価格を末尾に追加することで、各商品の価格の推移を管理しています。

この表から、数式だけで各商品の最新価格を抽出する方法について解説していきます。

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

今回紹介する数式を使えば、今後の更新も一切不要です。


1. テーブル化

数式を入力する前に、表のデータの増減に簡単に対応するため、対象の表を「テーブル」に変換します。

まずは、表の中にカーソルを移動させ、[挿入]タブから[テーブル]を選択します。

指定されている範囲が正しいことを確認し、表の先頭行が見出し行のため、[先頭行をテーブルの見出しとして使用する]にチェックした状態で確定します。

テーブルに変換すると、以下のようにデザインが変わってしまいます。

デザインは、[テーブルデザイン]タブの[テーブルスタイル]から簡単に変更することができます。
こちらでは、元の書式を生かすため、[テーブルスタイル]を[なし]にします。

フィルターボタンが不要な場合は、フィルターボタンのチェックを外しておきます。

次に、テーブル名を変更します。
テーブル名は[テーブルデザイン]タブから変更できます。
こちらでは「価格一覧」にしています。

以上の手順で、テーブルの完成です。


2. 数式の入力

次は、数式の入力です。
最新価格を表示する用の表の見出しは、数式ではなく直接用意しておきます。

見出しの用意ができたら、数式を入力していきます。

まずは、テーブルの商品名から重複を除いた一覧を数式で作成します。
指定した範囲から重複を除外するには、UNIQUE関数が便利です。

UNIQUE関数を活用する場合、以下のように入力します。

=UNIQUE(価格一覧[商品名])

数式を入力することで、以下のように商品名一覧を抽出できます。

テーブルの範囲は、構造化参照という特殊な参照方法で指定できます。
構造化参照については、以下で詳しく解説しています。
>構造化参照とは

次は、各商品の最新価格を抽出します。
まずは、先頭の「消しゴム」の最新価格のみを抽出していきます。
商品名が指定した値と一致する行の末尾の価格のみを抽出する場合は、XLOOKUP関数が便利です。

XLOOKUP関数を活用する場合、以下のように入力します。

=XLOOKUP(F3,価格一覧[商品名],価格一覧[価格],,,-1)
// F3:検索値
// 価格一覧[商品名]:検索範囲
// 価格一覧[価格]:抽出範囲
// (省略):見つからない場合
// (省略):一致モード(省略時は完全一致)
// -1:検索モード(「-1」は末尾から先頭へ検索)

数式を入力することで、以下のように最新価格を抽出できます。

他の行の商品も一括で抽出する場合は、XLOOKUP関数の検索値に商品名一覧の全体を指定します。
商品名一覧は1つの数式により展開されています。
そのような数式で展開されている範囲は、数式が入力されているセルに「#」を加えることで、全体を指定できます。

=XLOOKUP(F3#,価格一覧[商品名],価格一覧[価格],,,-1)

数式を入力することで、以下のように各商品の最新価格を一括で抽出できます。


3. 完成

以上の手順で完成です。
テーブルにデータを追加すると、自動でテーブルの範囲が拡張されます。
そのため、数式を更新する必要がなく、継続的に活用することができます。

▼サンプルファイル▼

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/23
【便利】複数選択可能な「リストボックス」で値入力

【便利】複数選択可能な「リストボックス」で値入力

#シートモジュール #ユーザーフォーム #Worksheet_BeforeDoubleClick #UserForm_Initialize #If #For #ActiveCell

※サイト内の限定動画です。

複数選択可能なリストボックスで、セルに値を入力することができる仕組みについて解説しています。
複数選択した各要素は、カンマ区切りでセルに入力されます。
また、要素の順番は固定で、「A,B」と「B,A」といった不規則な順番にならないようになっています。

00:00 挨拶
00:44 完成イメージ
01:28 準備
01:37 作成(フォームのデザイン)
04:09 作成(フォームの初期値の設定)
11:53 作成(リストボックスの値を反映)
16:32 作成(リストボックス自動立ち上げ)
19:29 完成
20:43 プログラムの全体

▼準備ファイル▼

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が入力された行のいずれかのセルを右クリックすることで、隣の表のカートに、その商品を追加することができます。

▼サンプルファイル▼

2026/02/20
【Excel】前日から値が変わったら自動で色付け

【Excel】前日から値が変わったら自動で色付け

以下のように何かしらの数値を日々記録している場合、値が変わった場所を見つけるのは若干大変です。

そこで今回は、以下のように「前日と値が変わったセル」と「その日付のセル」を色付けする設定方法について解説していきます。

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


前日と値が変わったセルを色付け

はじめに、前日と値が変わったセルを色付けしていきます。
特定の条件を満たしたセルの書式を自動で変更する場合は、「条件付き書式」を活用します。

まずは、日付を除く色付けする可能性のあるセルを選択します。
こちらでは、2行目のデータに関しては前日のデータが存在しないため、3行目以降のB列からD列のセルを選択します。

次に、[ホーム]タブから[条件付き書式]の[新しいルール]を選択します。

条件付き書式の設定画面が表示されましたら、[ルールの種類]を[指定の値を含むセルだけを書式設定]にして、[セルの値]→[次の値に等しくない]→「=B2」と指定します。

これは選択基準のセルB3を色付けする条件です。
セルB3を色付けするときとは、その一つ上のセルB2の値と異なる場合になるので、上記のように指定しています。
他の選択範囲に関しては、セルが相対的に参照されます。(例:セルC3→「=C2」)

条件の指定ができたら、[書式]から好みの書式を指定します。
こちらでは、[フォント]タブから「赤色」、[塗りつぶし]タブから「黄色」を指定しています。

上記のように書式の設定ができたら、設定内容を確定することで、前日と値が変わったセルを自動で色付けすることができます。


1件でも値が変わった日付のセルを色付け

では次に、1件でも値が変わった日付のセルを色付けしていきます。
先ほどは自分自身のセルに対して、前日と値が変わったかどうかを確認しましたが、今回は自分自身ではなく、他の複数セルを確認する必要があります。
そのため、先ほどより設定内容が複雑になります。

まずは、色付けする可能性のある日付の範囲、3行目以降のA列を選択します。

次に、[ホーム]タブから[条件付き書式]の[新しいルール]を選択します。

条件付き書式の設定画面が表示されましたら、[ルールの種類]を[数式を使用して、書式設定するセルを決定]にし、条件式を直接入力します。

今回の場合の条件は、以下のようになります。

「B列(数量1)が前日の値と異なる」または「C列(数量2)が前日の値と異なる」または「D列(数量3)が前日の値と異なる」場合

このように、「複数条件のいずれかを満たす場合」という条件式はOR関数を活用し、以下のように指定します。

=OR(B2<>B3,C2<>C3,D2<>D3)
// B2<>B3:B2とB3が等しくない
// C2<>C3:C2とC3が等しくない
// D2<>D3:D2とD3が等しくない

条件式の入力ができたら、[書式]から好みの書式を指定します。
こちらでは、 [塗りつぶし]タブから「黄色」を指定しています。

上記のように書式の設定ができたら、設定内容を確定することで、いずれかの項目の値が前日と変わっている日付のセルを自動で色付けすることができます。

▼サンプルファイル▼

2026/02/13
【Excel】FILTER関数による抽出データの元データに遷移するハイパーリンク

【Excel】FILTER関数による抽出データの元データに遷移するハイパーリンク

FILTER関数の登場により、以下のようにフィルター機能を活用した絞り込みをしなくても、簡単にデータを抽出することができるようになりました。

=FILTER(B3:C100,D3:D100="着手中","")

しかし、データの確認ができても、データを更新する際は元の表の対象データを探す必要があります。

更新するたび、毎回元のデータを探すのは大変です。

ということで今回は、元のデータに瞬時に遷移するハイパーリンクを自動で表示させる方法について紹介していきます。

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


対象データの行番号を取得する

まずは、抽出されたそれぞれのデータが、元の表の何行目のデータになるのか、その行番号を取得する数式を入力していきます。

今回の表の場合、「No」の値が一意のデータになるため、抽出された「No」と一致する元の表の「No」の位置情報を取得していきます。

特定の値と一致するセルの位置情報を取得する場合は、MATCH関数が便利です。
以下のように、抽出データの先頭行の隣のセルに数式を入力します。

=MATCH(F3,B1:B100,0)
// F3:検索値
// B1:B100:検索範囲(行番号を取得するため、1行目から表の範囲を大きめに指定)
// 0:検索方法(検索値と完全一致する値が入力されたセルの位置情報を取得)

これで、先頭行に関しては抽出することができました。

次に、この結果をFILTER関数の抽出範囲の全ての行に対して表示する必要があります。
MATCH関数の検索値の範囲(F3)を複数行指定することでも、全体に展開して表示することができますが、データの増減に対応することはできません。

=MATCH(F3:F19,B1:B100,0)

データの増減に対応させるためには、FILTER関数の展開範囲から指定する必要があります。
スピルにより展開された範囲は、数式を入力したセルの後に「#」を加えることで指定することができます。

=F3#

しかし、今回指定すべき範囲は、抽出された表全体ではなく、「No」の範囲のみになります。

そのような時は、INDEX関数を活用します。
INDEX関数で列番号のみを以下のように指定することで、対象範囲の指定した列のみを抽出することができます。

=INDEX(F3#,,1)
// =INDEX(範囲,行番号,列番号)

後は、この数式をMATCH関数の検索値に指定するだけで、データの増減に対応した数式にすることができます。

=MATCH(INDEX(F3#,,1),B1:B100,0)

ハイパーリンクを表示させる

各行番号のD列(「進捗」の項目)に遷移するハイパーリンクにしていきます。
特定のセルに遷移する動的なハイパーリンクを用意するには、HYPERLINK関数を活用します。

特定のセルに遷移するハイパーリンクは、以下のように指定します。

=HYPERLINK("#[遷移先のセルのアドレス] ", "表示するテキスト")

遷移先のセルのアドレスには、以下のような指定をします。

同じシートのセルD3に遷移:”#D3″
別シート(Sheet1)のセルD3に遷移:”#Sheet1!D3″

今回の例では、同じシート上に遷移させます。
また、行番号はMATCH関数で取得した値になるため、以下のように指定します。

=HYPERLINK("#D"&MATCH(INDEX(F3#,,1),B1:B100,0),"●")

これでハイパーリンクの完成です。
ただ、数式を入力したセル以外の書式は、以下のようにハイパーリンクの書式にならないため、列全体をハイパーリンクの書式と似た書式にしておくとよいです。

こちらでは、青文字に下線を設定しています。
直接書式を変更しているため、通常のハイパーリンクのように、クリックした後に色が変わることはありません。

ハイパーリンク自体は完成していますが、このままですと、抽出データが1件も存在しないときに、以下のようなエラーになってしまいます。

そのため、以下のようにIFERROR関数を組み合わせるとよいです。

=IFERROR(HYPERLINK("#D"&MATCH(INDEX(F3#,,1),B1:B100,0),"●"),"")

完成

以上の手順で完成です。

抽出されたデータから元のデータに遷移したい場合、対象行のハイパーリンクをクリックするだけで、簡単に遷移することができます。

▼サンプルファイル▼

2026/02/06
【ExcelVBA】連続した値を一括でセル結合!その逆も可能

【ExcelVBA】連続した値を一括でセル結合!その逆も可能

以下のように、連続した値を含む範囲を選択して、今回紹介する機能を実行するだけで、セルの結合をすることができる、もしくは、その逆をすることもできます。

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

このような、複数範囲に対して、セルの結合(解除)を瞬時に行うことができる機能の作り方を紹介していきます。


1. 開発準備

機能を加えたいファイルを立ち上げ、[開発]タブから[マクロ]を選択します。

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

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

こちらで作成した機能を保存するには、マクロ有効ブック(拡張子「xlsm」)にする必要があります。


2. コードの記述

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

Sub ToggleMerge()
    
    Dim s As Variant: Set s = Selection
    
    If TypeName(s) <> "Range" Then Exit Sub
    If s.Columns.Count <> 1 Then Exit Sub
    If s.Count > 10000 Then Exit Sub
    
    Application.DisplayAlerts = False
    Dim i As Long, r As Range
    For i = 1 To s.Cells.Count
        If s.Cells(i).MergeCells Then
            With s.Cells(i).MergeArea
                .UnMerge
                .Value = s.Cells(i).Value
                i = i + .Count - 1
                Set r = Nothing
            End With
        Else
            If Not r Is Nothing Then
                If r.Value = s.Cells(i).Value Then
                    Range(r, s.Cells(i)).Merge
                Else
                    Set r = s.Cells(i)
                End If
            Else
                Set r = s.Cells(i)
            End If
        End If
    Next i
    Application.DisplayAlerts = True
    
End Sub

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

    Dim s As Variant: Set s = Selection
    
    If TypeName(s) <> "Range" Then Exit Sub
    If s.Columns.Count <> 1 Then Exit Sub
    If s.Count > 10000 Then Exit Sub

選択している範囲の情報を変数(s)に割り当て、その範囲が以下の条件を満たしているときに処理を終了します。(上から順番に確認)

・セル以外(Rangeではない:図形など)
・(セルの場合で)セルが1列以外(複数列)
・(セルが1列の場合で)セルの数が10000より多い

こちらは、処理する範囲が正しくないときにエラーになってしまうことや、範囲が膨大で処理が重たくなってしまうことを防ぐための対策です。

    Application.DisplayAlerts = False
    '省略
    Application.DisplayAlerts = True

セルを結合するときに、以下のような警告メッセージが表示されることがあるため、このような警告メッセージの表示を一時的に無効にしています。

    Dim i As Long, r As Range
    For i = 1 To s.Cells.Count
        If s.Cells(i).MergeCells Then
            '省略
        Else
            '省略
        End If
    Next i

変数(i)は繰り返し処理(For i = 1 … Next i)でセルの位置情報を格納する用、変数(r)は1つ前のセルの情報を格納する用として用意しています。
選択されているセルを先頭から1つずつ確認し、そのセルが「結合されている場合」と「結合されていない場合」で処理を分岐しています。

            With s.Cells(i).MergeArea
                .UnMerge
                .Value = s.Cells(i).Value
                i = i + .Count - 1
                Set r = Nothing
            End With

セルが結合されている場合の処理で、まずは結合されているセルの範囲をWithで指定しています。
その次に、その範囲の結合を解除し、結合されていた範囲全体に、その範囲の先頭のセルの値を入力しています。

そして、セルの位置情報を格納している変数(i)に、結合されていた範囲のセルの数から1を引いた数を加えて、その範囲の末尾のセルの位置情報に上書きしています。

最後に、1つ前のセルの情報を格納する用の変数(r)を未割当にしています。

            If Not r Is Nothing Then
                '省略
            Else
                Set r = s.Cells(i)
            End If

セルが結合されていない場合の処理で、1つ前のセルの情報を格納する用の変数(r)が未割当でない場合と、未割当の場合で処理を分岐しています。

未割当の場合は、現在確認しているセルの情報を変数(r)に割り当てています。

                If r.Value = s.Cells(i).Value Then
                    Range(r, s.Cells(i)).Merge
                Else
                    Set r = s.Cells(i)
                End If

変数(r)が未割当でない場合は、その変数(r)が指すセルの値と現在の値が一致しているかどうかで処理を分岐しています。(1つ前の値と同じかどうか)

一致している場合は、変数(r)が指すセルから現在のセルまでの範囲を結合し、一致していない場合は、変数(r)に現在のセルを割り当てています。


3. ショートカットの割り当て

コードが完成したら、実行用のショートカットを割り当てます。

[開発]タブから[マクロ]を選択し、表示される画面から作成した機能を選択して、[オプション]を選択します。

表示される以下の画面にて、ショートカットを割り当てるキーを指定します。
こちらでは、Merge(結合)の略で「m」と入力し、「Ctrl + M」に機能を割り当てています。

以上の設定で確定して、設定画面を閉じます。


4. 完成

以上の手順で完成です。
セル結合したい、もしくはセル結合を解除したい範囲を選択して、「Ctrl + M」のショートカットを実行することで、以下のように切り替えることができます。

セルの結合を解除するときに、一部の罫線の設定が取り消されることがあります。

▼サンプルファイル▼