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/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」のショートカットを実行することで、以下のように切り替えることができます。

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

▼サンプルファイル▼

2026/01/23
【ExcelVBA】ボタンを押すだけで「データ削除&上詰め」

【ExcelVBA】ボタンを押すだけで「データ削除&上詰め」

こちらでは、削除したいデータのいずれかのセルを選択して、「選択行の削除」ボタンを押すだけで、その行のデータを削除して上に詰めることができる機能の実現方法について紹介していきます。

以下のように、予め指定した列(「名前」と「性別」)のみが削除されます。

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


1. 開発準備

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

今回は、削除対象の項目は「名前」と「性別」とし、「No」は削除されないように実現していきます。

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

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


2. コードの記述

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

Sub DeleteSelectedData()
    
    Dim r As Long
    r = ActiveCell.Row
    
    If r < 3 Or r > 12 Then Exit Sub
    
    With Range(Cells(r, "C"), Cells(r, "D"))
        .ClearContents
        .Cut
    End With
    Range("C13").Insert Shift:=xlDown
    
End Sub

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

    Dim r As Long
    r = ActiveCell.Row

数値を格納する用の変数(r)を用意し、アクティブになっているセルの行番号(ActiveCell.Row)を格納しています。

    If r < 3 Or r > 12 Then Exit Sub

先ほど取得した行番号が、3未満、または12より大きい場合、要するに今回使用する表のデータ行以外がアクティブな場合に、処理を終了(Exit Sub)しています。

「If」は処理を1行で記述できる場合、「End If」を省略することができます。

    With Range(Cells(r, "C"), Cells(r, "D"))
        .ClearContents
        .Cut
    End With
    Range("C13").Insert Shift:=xlDown

アクティブセルの行の削除対象の範囲(r行目のC列からD列)を指定し、値のみを削除(ClearContents)して切り取り(Cut)、そして末尾(セルC13を基準)に挿入(Insert)しています。

単純にセルを削除してしまうと、以下のように罫線が崩れてしまうため、このような手順で実装しています。


3. ボタンの作成

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

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


4. 完成

以上の手順で完成です。
削除したいデータのいずれかのセルを選択して、「選択行の削除」ボタンを押すだけで、その行のデータを削除して上に詰めることができます。

▼サンプルファイル▼

2026/01/02
【ExcelVBA】書類の確認と同時にロックする仕組み

【ExcelVBA】書類の確認と同時にロックする仕組み

以下の営業報告書には、「確認日」という項目とチェックボックスが用意されています。

このチェックボックスをチェックすることで、チェックボックスが「実行時の日付」に置き換わり、シートがロック(保護)され、そのシートの編集ができなくなります。

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

このように、書類の確認と同時にロック(保護)する仕組みの実現方法について紹介していきます。


1. 開発準備

今回は、予め用意したシート内の特定のチェックボックスをチェックすると同時に、そのシートをロック(保護)する仕組みを実現していきます。

チェックボックスは、[挿入]タブの[チェックボックス]を使用しており、チェックボックスが配置されたセルには、「FALSE」という値が入力されています。

チェックボックスをチェックすると、セルの値は「TRUE」に変わります。

このように指定したシートのセルの値が変わると同時に、シートをロック(保護)するなどと何かしらの処理を実行するには、「シートモジュール」「イベントプロシージャ」を活用します。
シートモジュールは、対象シートのタブ上で右クリックし、[コードの表示]を選択することで表示できます。

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

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

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

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

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


2. コードの記述

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

Private Sub Worksheet_Change(ByVal Target As Range)
    
    With Range("E5")
        If .Value = True Then
           .Value = Date
           Me.Protect
        End If
    End With
    
End Sub

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

    With Range("E5")
        '省略
    End With

「With」と「End With」で囲むことで、この中では「With」に指定した「Range(“E5”)」を省略して記述することができます。
省略する際は「.」から記述します。

        If .Value = True Then
           .Value = Date
           Me.Protect
        End If

次に、「If」でセルE5(「With」で指定したセル)が「True(チェックボックスがチェックされた状態)」かどうかを確認し、「True」の場合は、そのセルの値を実行時の日付(Date)にし、シートを保護(Me.Protect)しています。


3. 完成

以上の内容で実現できます。
対象シートのセルE5に配置されたチェックボックスをチェックすると同時に、チェックボックスは実行時の日付に置き換わり、シートがロック(保護)されます。

運用時は、作成したシートをテンプレートとし、シートを複製して活用するとよいです。
シートを複製すると、複製元シートのシートモジュールの内容も、複製したシートに反映されます。

▼サンプルファイル▼

2025/12/19
【ExcelVBA】ボタン1つで完了タスクを別シートに移動

【ExcelVBA】ボタン1つで完了タスクを別シートに移動

以下は、タスク管理表です。

完了したタスクを選択して、「完了」ボタンを押すだけで、そのタスクが「完了」シートに移動します。

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

このような、ボタン1つで完了タスクを別シートに移動する仕組みの実現方法について紹介します。


1. 開発準備

まずは、「未完了」シートと「完了」シートを用意し、「完了」シートには空の表を用意します。

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

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


2. コードの記述

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

Sub MoveTask()
    
    Dim w1 As Worksheet
    Dim w2 As Worksheet
    Set w1 = Worksheets("未完了")
    Set w2 = Worksheets("完了")
    
    Dim r1 As Long
    Dim r2 As Long
    r1 = ActiveCell.Row
    r2 = w2.Cells(w2.Rows.Count, "A").End(xlUp).Row + 1
    
    w2.Range(w2.Cells(r2, "A"), w2.Cells(r2, "C")).Value = _
        w1.Range(w1.Cells(r1, "A"), w1.Cells(r1, "C")).Value
    w1.Rows(r1).Delete
    
End Sub

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

    Dim w1 As Worksheet
    Dim w2 As Worksheet
    Set w1 = Worksheets("未完了")
    Set w2 = Worksheets("完了")

シート情報を割り当てる用の変数(w1とw2)を用意し、それぞれに「未完了」シートと
「完了」シートを割り当てています。

    Dim r1 As Long
    Dim r2 As Long
    r1 = ActiveCell.Row
    r2 = w2.Cells(w2.Rows.Count, "A").End(xlUp).Row + 1

数値を格納する用の変数(r1とr2)を用意し、「r1」にアクティブセル(現在選択している基準のセル)の行番号、「r2」に「完了」シートの表の末尾の行番号を格納しています。

「r2」について詳しく解説すると、「完了」シートのA列の末尾を選択し、Ctrlキーを押しながらカーソルキーの「↑」を押して止まった位置のセルの行番号に1を加えた数値を格納しています。

    w2.Range(w2.Cells(r2, "A"), w2.Cells(r2, "C")).Value = _
        w1.Range(w1.Cells(r1, "A"), w1.Cells(r1, "C")).Value
    w1.Rows(r1).Delete

「完了」シートの表の末尾のA列からC列に、「未完了」シートのアクティブセルの行のA列からC列の値を格納し、「未完了」シートのアクティブセルの行を削除しています。


3. ボタンの作成

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

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


4. 完成

以上の手順で完成です。
完了したタスク(同じ行のいずれかのセル)を選択し、「完了」ボタンを押すことで、その行のタスクが「完了」シートに移動します。

注意点として、今回のコードには、移動対象のタスクの行の範囲を指定していません。
そのため、1行目を選択して「完了」ボタンを押してしまうと、見出しが移動してしまいます。

そのため、必要に応じて、コード内で「行番号が2以上のとき」などといった条件分岐を行うとよいです。

▼サンプルファイル▼

2025/11/21
【ExcelVBA】円グラフでルーレットを実現

【ExcelVBA】円グラフでルーレットを実現

以下のような「円グラフを活用したルーレット」を作成する方法について紹介していきます。

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


1. 準備

以下の円グラフは、上の表(「はずれ」と「あたり」の割合)をもとに作成しています。
また、「▼」は別で作成した図形を重ねています。

上の表の「あたり」の割合は、以下のような数式で求めています。

=1-C3
// 1と「はずれ」の割合の差

そのため、「はずれ」の割合を変更するだけで、「あたり」の割合が自動で設定されます。


2. 実現方法

今回は、円グラフの「グラフの基線位置」を活用して、ルーレットを実現していきます。

円グラフは、「データ系列の書式設定」にある「グラフの基線位置」を変更することで回転させることができます。

こちらの値を、マクロで操作することで実現していきます。


3. コードの記述

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

Option Explicit

Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As LongPtr)

Sub Roulette()
    
    Dim ch As Chart
    Set ch = Worksheets("ルーレット").ChartObjects("グラフ 1").Chart
    
    Dim startN As Long, lastN As Long
    startN = ch.ChartGroups(1).FirstSliceAngle
    lastN = Int((360 + 1) * Rnd) + 360 * 6
    
    Dim n As Long
    n = startN
    Do While n < lastN
        DoEvents
        ch.ChartGroups(1).FirstSliceAngle = n Mod 360
        Sleep 5
        If lastN - n > 360 * 3 Then
            n = n + 10
        Else
            n = n + 10 - Int((n - 360 * 3) / (lastN - 360 * 3) * 10)
        End If
    Loop
    
End Sub

では、コードについて解説していきます。
※複雑なコードのため簡単に解説します。

Option Explicit

変数宣言を強制する際に記述するものです。
変数宣言を省略したい場合は、記述する必要はありません。

Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As LongPtr)

Windows APIにある「Sleep」というプロシージャを使えるようにするための宣言です。

    Dim ch As Chart
    Set ch = Worksheets("ルーレット").ChartObjects("グラフ 1").Chart
    
    Dim startN As Long, lastN As Long
    startN = ch.ChartGroups(1).FirstSliceAngle
    lastN = Int((360 + 1) * Rnd) + 360 * 6

対象のグラフを変数「ch」に割り当てて、そのグラフの基線位置を変数「startN」に格納しています。
変数「lastN」には、6周分の角度に、ランダムな角度を加えた角度を格納しています。
変数「lastN」が、回転を止める位置になります。

    Dim n As Long
    n = startN
    Do While n < lastN
        '省略
    Loop

変数「n」に変数「startN」の値を格納し、その変数「n」の値が変数「lastN」の値より小さい間、「Do」から「Loop」の中を繰り返し実行します。

        DoEvents
        ch.ChartGroups(1).FirstSliceAngle = n Mod 360
        Sleep 5
        If lastN - n > 360 * 3 Then
            n = n + 10
        Else
            n = n + 10 - Int((n - 360 * 3) / (lastN - 360 * 3) * 10)
        End If

繰り返しの中では、変数「n」の値を徐々に増やしています。
処理の流れは、以下になります。

1.変数「n」の値(角度)をグラフの基線位置に反映(0~359の間になるように360で割った余りを活用)
2.5ミリ秒(0.005秒)停止

この次が少しだけややこしくなります。
ルーレットでは、回転が徐々に減速する演出にするために、以下のような処理にしています。

残りの回転角度が3周より多い場合は、変数「n」に10を加算
そうでない場合は、徐々に加算する数を減らす

4. ボタンの作成

記述したプロシージャ(Roulette)を割り当てたボタンを作成します。
こちらでは、立体的な見た目の図形(四角形:角度付き)を挿入して、その図形に割り当てています。


5. 完成

以上の手順で完成です。
作成したボタンをクリックすることで、円グラフが回転します。

▼サンプルファイル▼

2025/11/07
【ExcelVBA】今月のシートのみを瞬時に表示

【ExcelVBA】今月のシートのみを瞬時に表示

以下のように、「表示切替」ボタンを押すことで、複数あるシートから今月のシートのみを表示することができ、再度ボタンを押すことで、すべてのシートを表示することができる仕組みの実現方法について紹介します。

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


1. 開発準備

今回は、以下のように「1月」から「12月」という名前のシートが含まれるブックに対して実現していきます。

また、「設定」シートの「表示切替」ボタンを配置する予定のセルに、「TRUE」もしくは「FALSE」と入力します。

この値は、現在のシートの状態を表しています。
「TRUE」ならば、すべてのシートが表示されている状態、「FALSE」ならば、一部のシートが非表示の状態になります。
※仕組みを実装する前は、シートの状態に関係なく「TRUE」もしくは「FALSE」の値を入力しておきます。

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

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

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


2. コードの記述

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

Sub ToggleSheetView()
    
    Dim ws As Worksheet
    Set ws = Worksheets("設定")
    
    Dim m As Long
    m = Month(Date)
    
    Dim ckRng As Range
    Set ckRng = ws.Range("B3")
    ckRng.Value = Not ckRng.Value
    
    Dim i As Long
    For i = 1 To 12
        On Error Resume Next
        With Worksheets(i & "月")
            If i = m Or ckRng.Value Then
                .Visible = xlSheetVisible
            Else
                .Visible = xlSheetHidden
            End If
        End With
        On Error GoTo 0
    Next i
    
    ws.Activate
    
End Sub

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

    Dim ws As Worksheet
    Set ws = Worksheets("設定")
    
    Dim m As Long
    m = Month(Date)

シート情報を割り当てる用の変数(ws)を用意し、ボタンを配置する予定の「設定」シートを割り当てています。
次に、現在の月を格納する用の変数(m)を用意し、現在の月を格納しています。

    Dim ckRng As Range
    Set ckRng = ws.Range("B3")
    ckRng.Value = Not ckRng.Value

シートの表示非表示の状態を表す値が入力されたセルの情報を割り当てる用の変数(ckRng)を用意し、対象のセル(「設定」シート(ws)のセルB3)を割り当てています。
そして、その対象のセルの現在の値を、「TRUEならばFALSE」、「FALSEならばTRUE」と反転させています。

    Dim i As Long
    For i = 1 To 12
        On Error Resume Next
        With Worksheets(i & "月")
            '省略
        End With
        On Error GoTo 0
    Next i

繰り返し処理で使う用の変数(i)を用意し、Forで「1」から「12」まで1つずつ繰り返しています。
「For~Next」の中では、「1月」から「12月」のシートを1つずつ繰り返しています。

「Worksheets(i & “月”)」と直接シート名で指定しているため、対象のシート名のシートが存在しないときにエラーになってしまいます。
その対策として、「On Error Resume Next」と「On Error GoTo 0」を記述しています。
「On Error Resume Next」で、それ以降でエラーになった際に、エラーを飛ばして処理を実行することができます。
「On Error GoTo 0」で、「On Error Resume Next」の設定を解除しています。

            If i = m Or ckRng.Value Then
                .Visible = xlSheetVisible
            Else
                .Visible = xlSheetHidden
            End If

Withの中で、「繰り返された対象の月と実行したときの月が同じ場合」、もしくは、「シートの表示非表示の状態を表すセルの値がTRUEの場合」は、繰り返された対象の月のシートを表示しています。
それ以外の場合は、繰り返された対象の月のシートを非表示にしています。

※「With」から「End With」で囲まれている範囲内は、「With」で指定した情報を省略して「.」から記述することができます。

    ws.Activate

シートの表示非表示を切り替える処理で、選択されているシートが変わってしまうことがあるため、最後に「設定」シートを選択しています。


3. ボタンの作成

コードが完成したら、実行用のボタンを用意します。
ボタンは、[開発]タブの中の[挿入]から作成することができます。


4. 完成

以上の手順で完成です。
「設定」シートに配置した「表示切替」ボタンを押すことで、シートの表示非表示を切り替えることができます。

▼サンプルファイル▼

2025/10/31
【ExcelVBA】セルの変更履歴表を自動作成

【ExcelVBA】セルの変更履歴表を自動作成

以下の左側のシートに用意された表の値を変更すると、「変更履歴」シートの変更履歴表に変更内容が自動で記録されます。

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

このような、予め指定した範囲内のセルの値を変更した際に、変更履歴表に自動で記録する仕組みの実現方法について解説していきます。


1. 開発準備

今回は、予め指定した範囲内のセルの値を変更すると同時に、変更履歴表に自動で記録する仕組みを作っていきます。

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

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

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

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

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

表示された「Worksheet_Change」というプロシージャを活用します。
「Worksheet_SelectionChange」というプロシージャに関しても、今回は使用するため残しておきます。


2. コードの記述

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

Dim oldValue As Variant

Private Sub Worksheet_Change(ByVal Target As Range)
    
    If Target.CountLarge = 1 And _
        Target.Row >= 2 And _
        Target.Column <= 3 Then
        
        With Worksheets("変更履歴")
            .Rows(2).Insert CopyOrigin:=xlFormatFromRightOrBelow
            .Range("A2").Value = Now
            .Range("B2").Value = Target.Address(False, False)
            .Range("C2").Value = oldValue
            .Range("D2").Value = Target.Value
        End With
        
    End If
    
End Sub

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    
    If Target.CountLarge = 1 Then
        oldValue = Target.Value
    End If
    
End Sub

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

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

「Worksheet_Change」というプロシージャの引数の「Target」に、編集されたセルの情報が渡されます。
そのセルの情報を用いて、「変更履歴」シートに記録していくのですが、引数の「Target」から取得できる情報は、編集されたセルの情報のみのため、変更前のセルの値を取得することができません。
そのため、変更前のセルの情報を次の処理で、予め取得して保持しておく必要があります。

Dim oldValue As Variant

'省略

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    
    If Target.CountLarge = 1 Then
        oldValue = Target.Value
    End If
    
End Sub

「Worksheet_SelectionChange」というプロシージャの引数の「Target」に、選択されたセルの情報が渡されます。
セルの値を変更する前にセルを選択するという動作があります。
そのため、「Worksheet_SelectionChange」のプロシージャが実行された時点では、変更前のセルの情報(Target)を取得することができます。
そのセルの情報(Target)から、変数「oldValue」に変更前のセルの値を格納しています。

変数「oldValue」は、「Worksheet_SelectionChange」のプロシージャだけでなく、「Worksheet_Change」のプロシージャからでも参照できるようにする必要があります。
そのため、プロシージャの外に変数を宣言しています。
セルの値を格納する用の変数のため、数値や日付など色んな型を格納できるようにVariant型で宣言しています。

プロシージャの外に宣言した変数(モジュールレベルの変数)に格納した値は、プロシージャの処理が終了した後でも保持されます。
そのため、常に変更前のセルの値を保持することができます。

今回の場合は、単体のセルが変更されたときのみに変更履歴を記録するようにしているため、選択されているセルが1つであることを「If Target.CountLarge = 1 Then」で確認しています。

Private Sub Worksheet_Change(ByVal Target As Range)
    
    If Target.CountLarge = 1 And _
        Target.Row >= 2 And _
        Target.Column <= 3 Then
        
        '省略
        
    End If
    
End Sub

「Worksheet_Change」のプロシージャでは、変更履歴を記録する処理を行います。
そのため、変更履歴を記録する対象の範囲内が変更されたかどうかを確認しています。

今回の場合は、変更されたセルが1つであり、行番号が2以上、列番号が3以下であることを前提としています。
これは、「商品管理」シートに用意された表のデータの範囲になります。

この条件を満たしたときに、Ifの中の処理を実行します。

        With Worksheets("変更履歴")
            .Rows(2).Insert CopyOrigin:=xlFormatFromRightOrBelow
            .Range("A2").Value = Now
            .Range("B2").Value = Target.Address(False, False)
            .Range("C2").Value = oldValue
            .Range("D2").Value = Target.Value
        End With

先ほどのIfの中の処理です。
こちらは、「変更履歴」シートの変更履歴表の先頭行に、変更履歴を記録する内容になっています。
そのため、「With」で「変更履歴」シートを指定して囲み、「With」から「End With」までの範囲内では、「変更履歴」シートの情報を省略して記述できるようにしています。

「.Rows(2).Insert CopyOrigin:=xlFormatFromRightOrBelow」で、「変更履歴」シートの2行目に行を挿入し、下の行(3行目)の書式を引き継いでいます。
そして、挿入した2行目の個々のセルに、以下の値を入力しています。

・セルA2:Now // 現在日時
・セルB2:Target.Address(False, False) // 更新されたセルの相対参照のアドレス
・セルC2:oldValue // 変更前のセルの値
・セルD2:Target.Value // 変更後のセルの値


3. 完成

以上の内容で実現できます。
予め指定した範囲内のセルの値を変更すると、「変更履歴」シートの変更履歴表に変更内容が自動で記録されます。
また、最後に変更した内容が、変更履歴表の先頭に記録されるようになっています。

▼サンプルファイル▼

2025/10/24
【ExcelVBA】予定表を1週間単位で表示

【ExcelVBA】予定表を1週間単位で表示

以下の予定表は、セルC2に配置されたスピンボタンを押すことで、1週間単位で表示する日付を切り替えることができます。

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

こちらは、実際の値が置き換わっている訳ではなく、対象の週以外の列が非表示になっています。

そのため、表示されているセルに直接値を入力しても問題ございません。

今回は、上記のように、スピンボタンで表示する列を一定間隔で切り替える仕組みを実現していきます。


1. スピンボタンの用意

今回は、以下のすべての列が表示されている予定表から作成していきます。

まずは、スピンボタンを用意します。
スピンボタンは、[開発]タブの中の[挿入]から[スピンボタン]を選択することで、好みの位置に配置することができます。

スピンボタンの用意ができたら、スピンボタンの上で右クリックし、[コントロールの書式設定]を選択します。

[コントロールの書式設定]にて、以下のように設定します。

スピンボタンで指定した数値が、予定表の表示する週になります。
[最大値]を50にすると、最大50週目までしか表示できなくなります。
そのため、必要に応じて[最大値]は修正してください。

[リンクするセル]は、スピンボタンの現在値を表示させるセルになります。
こちらでは、スピンボタンの隣のセルB2を指定しています。


2. 開発準備

次は、スピンボタンをクリックすると同時に、予定表の週の表示を切り替える仕組みを実現します。
そのためには、VBAを活用します。

スピンボタンに連動する機能を開発する必要があるため、スピンボタンの上で右クリックし、[マクロの登録]を選択します。

[マクロの登録]の画面にて、開発する機能の名前を入力し、[新規作成]を選択します。
こちらでは、「表示切替」と入力しています。

次に表示される以下の画面の「Sub ○○」から「End Sub」の間にコードを記述します。


3. コードの記述(列の表示切り替え)

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

Sub 表示切替()

    Dim no As Long
    no = Range("B2").Value
    
    Columns("D:MY").Hidden = True
    Range( _
        Columns(no * 7 - 3), _
        Columns(no * 7 + 3)).Hidden = False
        
End Sub

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

    Dim no As Long
    no = Range("B2").Value

「no」という整数(Long)専用の変数(入れ物)を用意し、その「no」にセルB2の値(表示する週を表す数値)を格納しています。

    Columns("D:MY").Hidden = True

予定表の日付の列全体を非表示にしています。

    Range( _
        Columns(no * 7 - 3), _
        Columns(no * 7 + 3)).Hidden = False

「no」の値から対象の週を指定し、対象の週の列を表示しています。

「no」が1のときは、1週目である4列目から10列目を表示し、
「no」が2のときは、2週目である11列目から17列目を表示します。
この関係性を「no」を用いた数式で表すと、「no * 7 – 3」列目から「no * 7 + 3」列目になります。

そのため、「Range」で「Columns(no * 7 – 3)」から「Columns(no * 7 + 3)」と対象の列の範囲を指定しています。


4. 完成

以上の手順で完成です。
スピンボタンを押すことで、対象の週のみが表示されるようになります。

▼サンプルファイル▼

2025/10/17
【ExcelVBA】複数フォルダを一括作成

【ExcelVBA】複数フォルダを一括作成

シート上の表の内容をもとに、データ数分のフォルダを一括で作成する仕組みを実現していきます。

こちらでは、以下のように、生徒一覧表の内容をもとに「No_氏名」という名前のフォルダを一括で作成する仕組みを実現していきます。

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


1. 開発準備

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

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

次に表示される以下の画面の「Sub ○○」から「End Sub」の間にコードを記述します。


2. コードの記述(フォルダ一括作成)

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

Sub GenerateFolders()
    
    Dim i As Long
    For i = 3 To 32
        '保存先のフォルダのパスを貼り付けて「\」を追加
        MkDir "A:\出力\" & _
            Cells(i, "B").Value & "_" & _
            Cells(i, "C").Value
    Next i
    
End Sub

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

    Dim i As Long
    For i = 3 To 32
        '省略
    Next i

表の1行1行を繰り返す際に使用する変数(i)を用意し、「For」で変数(i)を3~32までを繰り返して実行します。

3~32という数値は、フォルダを作成する対象のデータが入力されている行の範囲になります。

        '保存先のフォルダのパスを貼り付けて「\」を追加
        MkDir "A:\出力\" & _
            Cells(i, "B").Value & "_" & _
            Cells(i, "C").Value

「MkDir」の後に作成したいフォルダのパスを指定することで、フォルダを作成できます。

今回作成するフォルダの位置は、「Aドライブの中の出力フォルダの中」になるので、先頭に「”A:\出力\”」とパスを指定しています。

その後には、作成するフォルダの名前をセルの値を用いて指定しています。
「Cells(i, “B”).Value」で繰り返し処理で使用している変数(i)の値の行にあるB列の値(No)を取得し、「& “_”」で「_」を加え、「& Cells(i, “C”).Value」で変数(i)の値の行にあるC列の値(氏名)を加えています。
※「 _」は1つのコードを改行するときに指定します。


3. 完成

以上の手順で完成です。
作成したコードを指定して実行することで、瞬時にフォルダが作成されます。


4. 補足(Noを「0埋め2桁表記」にする)

作成するフォルダ名の先頭のNoを「0埋めの2桁表記」にしたい場合は、以下のように、「Format」を活用することで実現できます。

        MkDir "A:\出力\" & _
            Format(Cells(i, "B").Value, "00") & "_" & _
            Cells(i, "C").Value

「Format」についての詳しい解説は省略しますが、ワークシート上の「TEXT関数」とほぼ同じようなものです。

上記の内容に書き換えて実行すると、以下のように、Noを「0埋め2桁表記」で作成できます。

▼サンプルファイル▼

2025/10/10
【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)
    
    Application.EnableEvents = False
    
    Select Case Target.Address(False, False)
        Case "F3"
            Range("D14").Value = Target.Value
        Case "F4"
            Range("D15").Value = Target.Value
        Case "B4"
            Range("D16").Value = Target.Value
        Case "D6"
            Range("D17").Value = Target.Value
        Case "C7"
            Range("D18").Value = Target.Value
        Case "D14"
            Range("F3").Value = Target.Value
        Case  "D15"
            Range("F4").Value = Target.Value
        Case "D16"
            Range("B4").Value = Target.Value
        Case "D17"
            Range("D6").Value = Target.Value
        Case "D18"
            Range("C7").Value = Target.Value
    End Select
    
    Application.EnableEvents = True
    
End Sub

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

Private Sub Worksheet_Change(ByVal Target As Range)
    
    Application.EnableEvents = False
    
    '省略
    
    Application.EnableEvents = True
    
End Sub

「Worksheet_Change」というプロシージャの引数の「Target」に、編集されたセルの情報が渡されます。
そのセルの情報を用いて、双方向での入力を実現するのですが、処理の中で別のセルの値を編集してしまうと、再度「Worksheet_Change」が実行されてしまい無限ループになってしまいます。
そのため、処理の前後に、イベントを無効化する処理(Application.EnableEvents = False ~ Application.EnableEvents = True)を記述しています。

    Select Case Target.Address(False, False)
        Case "F3"
            Range("D14").Value = Target.Value
        Case "F4"
            Range("D15").Value = Target.Value
        Case "B4"
            Range("D16").Value = Target.Value
        Case "D6"
            Range("D17").Value = Target.Value
        Case "C7"
            Range("D18").Value = Target.Value
        Case "D14"
            Range("F3").Value = Target.Value
        Case  "D15"
            Range("F4").Value = Target.Value
        Case "D16"
            Range("B4").Value = Target.Value
        Case "D17"
            Range("D6").Value = Target.Value
        Case "D18"
            Range("C7").Value = Target.Value
    End Select

編集されたセルのアドレスから、双方向の入力をする対象のセルかどうかを判断し、対象のセルの場合は、紐づいているセルにも同じ値を入力しています。

「Target.Address(False, False)」で編集されたセルのアドレスを相対参照の形式で取得し、そのアドレスが「F3」の場合は、セルD14にも同じ値を入力、「F4」の場合は、セルD15にも同じ値を入力と、必要な組み合わせ分記述しています。


3. 完成

以上の内容で実現できます。
予め指定したセルに関しては、値を入力すると同時に、紐づいたセルにも同じ値が入力されます。

▼サンプルファイル▼

今回は、1つ1つのセルごとに割り当てましたが、表などで双方向の入力を実現する場合は、以下のように記述した方がよいです。

(例)以下の表①に入力したら表②にも反映、表②に入力したら表①にも反映させる

Private Sub Worksheet_Change(ByVal Target As Range)
    
    Application.EnableEvents = False
    
    If Target.Row >= 3 And Target.Row <= 10 Then
        
        If Target.Column >= 2 And Target.Column <= 3 Then
            Cells(Target.Row, Target.Column + 3).Value = Target.Value
        End If
        
        If Target.Column >= 5 And Target.Column <= 6 Then
            Cells(Target.Row, Target.Column - 3).Value = Target.Value
        End If
        
    End If

    Application.EnableEvents = True
    
End Sub

こちらのコードについての詳しい解説は省略します。