2025/04/04
【ExcelVBA】シートの「表示・非表示」を瞬時に切り替える

【ExcelVBA】シートの「表示・非表示」を瞬時に切り替える

以下のようにシートの数が増えすぎると、シートの移動が面倒になりますよね。

シートの一覧を表示して対象のシートを選択するということもできますが、毎回一覧を表示するというのも面倒になります。

そのような時は、不要なシートを非表示にすると思いますが、このシートを非表示にしたり再表示にしたりする作業も地味に面倒ですよね。

ということで今回は、シート名の一覧シートを用意し、そのシートで対象のシート名をダブルクリックするだけでシートの「表示・非表示」を切り替えることができる仕組みを実現していきます。

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


1. 開発準備

まず初めに、シート名の一覧シートを用意します。
こちらでは、以下のようなシート名と表示の有無(●なら表示)を管理した表を、シートを追加して用意しています。

次は、用意したシートの「表示」の項目をダブルクリックすることで、対象シートの「表示・非表示」を切り替える仕組みを実現していきます。

「特定のセルをダブルクリックすると同時に、何かしら処理を実行する」という仕組みは、該当するシートモジュールイベントプロシージャを活用することで実現できます。

シートモジュールは、該当するシートのタブ上で右クリックし、[コードの表示]を選択することで表示することができます。

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

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

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

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

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

ExcelVBAレベル確認

2. コードの記述

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

Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
    
    If Target.Row >= 3 And _
        Target.Column = 3 Then
        
        Cancel = True
        
        Dim wsName As String
        wsName = Cells(Target.Row, "B").Value
        
        On Error Resume Next
        If Target.Value = "" Then
            Target.Value = "●"
            Worksheets(wsName).Visible = True
        Else
            Target.ClearContents
            Worksheets(wsName).Visible = False
        End If
        
    End If
    
End Sub

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

Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
    
    If Target.Row >= 3 And _
        Target.Column = 3 Then
        
        '省略
        
    End If
    
End Sub

「Worksheet_BeforeDoubleClick」というプロシージャの引数の「Target」に、ダブルクリックされたセルの情報が渡されるため、そのセルの情報から、表の対象の範囲内がダブルクリックされたかどうかを確認しています。
こちらでは、「3行目以上、尚且つ、3列目のセル」と「表示」のセルの範囲内がダブルクリックされたかどうかを確認しています。

この条件を満たした場合に関してのみ、Ifの中の処理を実行します。

        Cancel = True
        
        Dim wsName As String
        wsName = Cells(Target.Row, "B").Value

セルをダブルクリックすると、通常、セルが編集モードになるのですが、引数の「Cancel」をTrueにすることで、編集モードにならなくなります。
その次に、ダブルクリックされた行と同じ行のB列の値(シート名)を変数(wsName)に格納しています。

        On Error Resume Next
        If Target.Value = "" Then
            Target.Value = "●"
            Worksheets(wsName).Visible = True
        Else
            Target.ClearContents
            Worksheets(wsName).Visible = False
        End If

次に、ダブルクリックされたセルの値の有無を確認しています。
値が空の場合は、ダブルクリックされたセルに「●」を入力し、先ほど取得したシート名(wsName)のシートを表示しています。
値が空でない場合は、ダブルクリックされたセルの値をクリアし、先ほど取得したシート名(wsName)のシートを非表示にしています。

先頭の「On Error Resume Next」はエラー対策です。
変数(wsName)に格納されているシート名のシートが存在しない場合に、エラーにならないように、エラーの場合は無視をして続行するという記述になります。


3. 完成

以上の内容で実現できます。
シートの「表示・非表示」を切り替えたい対象のシート名が入力されている行のC列のセルをダブルクリックすることで、そのシートの「表示・非表示」を切り替えることができます。

▼サンプルファイル▼

2025/03/28
【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)
    
    If Target.Row >= 3 And _
       Target.Column >= 4 And _
       Target.Column <= 5 Then
        
        Range("B2").AutoFilter _
            Field:=4, _
            Criteria1:=""
        
        Range("B2").Sort _
            Key1:=Range("D2"), _
            Order1:=xlAscending, _
            Header:=xlYes
        
    End If
    
End Sub

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

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

「Worksheet_Change」というプロシージャの引数の「Target」に、編集されたセルの情報が渡されるため、そのセルの情報から、表の対象のセルが編集されたかどうかを確認しています。
こちらでは、Targetの行番号が3以上、尚且つ、列番号が4以上、5以下の時、要するに「着手日」もしくは「完了日」の項目が編集されたかどうかを判定しています。

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

        Range("B2").AutoFilter _
            Field:=4, _
            Criteria1:=""

まずは、絞り込みです。
セルB2を含む表の先頭から4列目の項目「完了日」に対し、空白のセルで絞り込みをしています。

        Range("B2").Sort _
            Key1:=Range("D2"), _
            Order1:=xlAscending, _
            Header:=xlYes

次に、並べ替えです。
セルB2を含む表を、セルD2の列の項目「着手日」を基準に昇順(xlAscending)にしています。
表には見出し(項目名)が含まれるため、「Header:=xlYes」と指定しています。


3. 完成

以上の内容で実現できます。

「完了日」に値を入力すると同時に、そのタスクが非表示になります。

また、「着手日」を入力すると同時に、「着手日」を基準に昇順で並べ替えられます。

▼サンプルファイル▼

2025/03/14
【ExcelVBA】不要なシートの見出しの色を自動変更

【ExcelVBA】不要なシートの見出しの色を自動変更

使わなくなったシートの管理方法として、シート名の先頭に「_」を加えて、シート見出しの色をグレーにすることがあります。

毎月のように、この作業を行う場合、地味に面倒ですよね。

そこで今回は、シート名の先頭に_を加えるだけで、自動でシート見出しの色をグレーにする仕組みの実現方法について解説していきます。
※こちらで開発したファイルは記事の最後にて配布しています。


1. 開発準備

今回は、シート名の先頭に「_」を加えてから、他のシートに切り替えた時に、自動で対象のシート見出しの色をグレーにする仕組みを実現します。

そのような、シートが切り替わったタイミングに処理を自動で実行するには、「ブックモジュール」の「イベントプロシージャ」を活用します。
「ブックモジュール」は、[開発]タブから[Visual Basic]を選択し、[プロジェクトエクスプローラー]から[ThisWorkbook]をダブルクリックすることで表示することができます。

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

次に、シートが切り替わったタイミングに処理が自動で実行される特殊なプロシージャ(イベントプロシージャ)を用意する必要があります。
そのためには、ブックモジュールの左上のリストから「Workbook」を選択します。

「Workbook」を選択すると、自動で「Workbook_Open」というプロシージャが表示されます。
このプロシージャは、ワークブック(ファイル)を立ち上げた時に処理が実行されるイベントプロシージャになります。

ただ、今回使用するイベントプロシージャは、シートが切り替わったタイミングに処理が実行されるものになります。
そのため、右上のリストから「SheetDeactivate」を選択します。

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


2. コードの記述

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

Private Sub Workbook_SheetDeactivate(ByVal Sh As Object)
    
    If Left(Sh.Name, 1) = "_" Then
        Sh.Tab.Color = RGB(180, 180, 180)
    End If
    
End Sub

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

Private Sub Workbook_SheetDeactivate(ByVal Sh As Object)
    
    '省略
    
End Sub

「Workbook_SheetDeactivate」というプロシージャの引数の「Sh」に、アクティブでなくなったシートの情報が渡されます。

    If Left(Sh.Name, 1) = "_" Then
        Sh.Tab.Color = RGB(180, 180, 180)
    End If

対象のシート(Sh)の名前の先頭に「_」がある場合に、対象シートの見出しの色(Sh.Tab.Color)をグレー(RGB(180, 180, 180))にしています。

ExcelVBAレベル確認

3. 完成

以上の内容で実現できます。
シート名の先頭に「_」を加えて他のシートを選択するだけで、シート見出しの色が自動でグレーになります。

▼サンプルファイル▼

2025/03/07
【ExcelVBA】選択データの全項目を一括表示

【ExcelVBA】選択データの全項目を一括表示

以下のように、項目数の多い表の場合、対象データの内容を確認するのが大変だったりします。

そこで今回は、「対象データのいずれかのセルを選択してボタンを押すことで、全項目の値をメッセージボックスで表示することができる機能」の開発方法について解説していきます。

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


1. 開発準備

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

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

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


2. コードの記述

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

Sub 一覧表示()
    
    Dim r As Long
    r = ActiveCell.Row
    
    Dim c As Long, msgStr As String
    For c = 1 To 18
        msgStr = msgStr & _
            Cells(1, c).Value & ":" & _
            Cells(r, c).Text & vbCrLf
    Next c
    
    MsgBox msgStr
    
End Sub

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

    Dim r As Long
    r = ActiveCell.Row

こちらで、選択されているセル(アクティブになっているセル)の行番号を取得して、変数rに代入しています。

    Dim c As Long, msgStr As String
    For c = 1 To 18
        msgStr = msgStr & _
            Cells(1, c).Value & ":" & _
            Cells(r, c).Text & vbCrLf
    Next c

表の先頭列(A列:1列目)から表の最終列(R列:18列目)までを1列ずつ繰り返し、変数msgStrに、「対象列の項目名:1行目のc列目」と「:」、「対象列の対象データ:r行目のc列目」、「改行コード」を加えています。
項目名は「.Value」に対し、データの値は「.Text」を使用しています。
通常、セルの値の取得は「.Value」で問題ないのですが、データの値に関しては表示形式が設定された見た目のままの文字列を取得するために「.Text」を使用しています。

【注意】

「.Text」はセルに表示されたままのテキストを取得します。
そのため、日付や金額のセルなどで列幅が狭く「####」と表示されている場合は、「####」のままで取得されてしまいます。

    MsgBox msgStr

最後に、繰り返し処理で作成した文字列(変数msgStr)をメッセージボックスで表示しています。


3. ボタンの作成

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


4. 完成

以上の手順で完成です。
表示したいデータのいずれかのセルを選択して、作成したボタンを押すだけで、全項目の値をメッセージボックスで表示することができます。

▼サンプルファイル▼

2025/02/21
【ExcelVBA】相関性を保ったまま重複のない番号を自動入力

【ExcelVBA】相関性を保ったまま重複のない番号を自動入力

「No」や「ID」の項目などで重複のない番号を自動入力する際に、以下のようにROW関数を活用して入力することがあります。

しかし、ROW関数を活用して入力していると、表を並べ替えた時に番号が更新されてしまい、番号と他の項目との相関性がなくなってしまいます。

ということで今回は、相関性を保ったまま重複のない番号を自動入力する仕組みの実現方法について解説します。
※こちらで開発したファイルは記事の最後にて配布しています。

ExcelVBAレベル確認

1. 開発準備

今回は、以下の表の「Name」の項目に値が入力されると同時に、「No」の項目に重複のない番号を入力するという仕組みを実現します。

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

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

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

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

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

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

ExcelVBAレベル確認

2. コードの記述

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

Private Sub Worksheet_Change(ByVal Target As Range)
    
    If Target.Row >= 3 And _
        Target.Column = 3 Then
        
        If Cells(Target.Row, "B").Value = "" Then
            Cells(Target.Row, "B").Value = _
                WorksheetFunction.Max(Columns("B")) + 1
        End If
        
    End If
    
End Sub

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

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

「Worksheet_Change」というプロシージャの引数の「Target」に、編集されたセルの情報が渡されるため、そのセルの情報から、表の対象のセルが編集されたかどうかを確認しています。
こちらでは、Targetの行番号が3以上、尚且つ、列番号が3の時、要するに「Name」の項目が編集されたかどうかを判定しています。

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

        If Cells(Target.Row, "B").Value = "" Then
            Cells(Target.Row, "B").Value = _
                WorksheetFunction.Max(Columns("B")) + 1
        End If

先ほどの条件を満たしたときに、編集されたセルと同じ行のB列、即ち「No」の項目が空かどうかを確認しています。
「No」の項目が空の場合に、その項目に、B列に入力されている数値の最大値に1を加えた数値を入力しています。

ExcelVBAレベル確認

3. 完成

以上の内容で実現できます。

「Name」の項目に値を入力した時、尚且つ、その行の「No」の項目が空の場合に、今までの番号の最大値に1を加えた数値が自動で入力されます。

また、数式ではなく直接数値が入力されているため、並べ替えた際に他の項目との相関性がなくなってしまうことはありません。

▼サンプルファイル▼

2025/02/07
【ExcelVBA】表の絞り込みと並べ替えを一瞬でリセット

【ExcelVBA】表の絞り込みと並べ替えを一瞬でリセット

以下のように、並べ替えたり絞り込みしたりした表を毎回元の形に戻すのは手間になります。

そこで、こちらの記事では、並べ替えと絞り込みを一瞬でリセットする「リセット機能」の開発方法について解説します。

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

ExcelVBAレベル確認

1. 開発準備

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

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

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

ExcelVBAレベル確認

2. コードの記述

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

Sub リセット()
    
    With ActiveSheet.ListObjects("従業員管理表")
        .AutoFilter.ShowAllData
        Dim keyR As Range
        Set keyR = .ListColumns("社員ID").DataBodyRange
        With .Sort
            .SortFields.Clear
            .SortFields.Add key:=keyR
            .Apply
        End With
    End With
    
End Sub

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

    With ActiveSheet.ListObjects("従業員管理表")
        '省略
    End With

対象のテーブルを指定します。
今回の場合、操作を行う表を予めテーブルにしています。
そのテーブル名(従業員管理表)を指定します。

        .AutoFilter.ShowAllData

次に、対象のテーブルの絞り込みを解除しています。

        Dim keyR As Range
        Set keyR = .ListColumns("社員ID").DataBodyRange

次に、対象のテーブルの[社員ID]の範囲を変数(keyR)に割り当てています。

        With .Sort
            .SortFields.Clear
            .SortFields.Add key:=keyR
            .Apply
        End With

最後に、テーブルの既存の並べ替えの設定を解除し、テーブルの[社員ID]の範囲(keyR)を基準に並べ替える設定を適用しています。


3. ボタンの作成

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


4. 完成

以上の手順で、機能が完成します。
リセット機能を実行することで、以下のように表の絞り込みが解除され、[社員ID]を基準に並べ替えられます。

▼サンプルファイル▼

2025/01/31
【ExcelVBA】削除したデータを別シートに記録

【ExcelVBA】削除したデータを別シートに記録

以下の表の中の不要なデータ行のいずれかのセルを選択し、[選択行削除]ボタンを押すだけで、該当するデータを別シート(「削除済み」シート)の表の末尾に移動する機能の開発方法について解説してきます。

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


手順1: 開発準備

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

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

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


手順2: コードの記述

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

Sub deleteData()
    
    Dim ws1 As Worksheet, ws2 As Worksheet
    Set ws1 = Worksheets("商品一覧")
    Set ws2 = Worksheets("削除済み")
    
    Dim lastRow As Long
    lastRow = ws2.Cells(ws2.Rows.Count, "B").End(xlUp).Row + 1
    
    Dim rng As Range
    Set rng = ActiveCell
    
    If ActiveSheet.Name = ws1.Name And rng.Row >= 3 Then
        ws2.Rows(lastRow).Value = ws1.Rows(rng.Row).Value
        ws1.Rows(rng.Row).Delete
    End If
    
End Sub

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

    Dim ws1 As Worksheet, ws2 As Worksheet
    Set ws1 = Worksheets("商品一覧")
    Set ws2 = Worksheets("削除済み")

移動元、移動先のシート情報を変数「ws1、ws2」に割り当てています。

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

移動先のシート(「削除済み」シート)のデータを追加する行の行番号を取得し、変数「lastRow」に割り当てています。
移動先のシート(「削除済み」シート)のB列の最終行のセルを基準に、「Ctrl+↑」で移動した先のセルの行番号に1を加えた番号を取得しています。

    Dim rng As Range
    Set rng = ActiveCell

実行時に選択されているセル(複数選択の場合は選択基準のセル)の情報を、変数「rng」に割り当てています。

    If ActiveSheet.Name = ws1.Name And rng.Row >= 3 Then
        ws2.Rows(lastRow).Value = ws1.Rows(rng.Row).Value
        ws1.Rows(rng.Row).Delete
    End If

実行時に選択されているシートが移動元のシート(「商品一覧」シート)であり、尚且つ、実行時に選択されているセルの行番号が3以上の場合にIfの中の処理を実行します。
Ifの中の処理では、移動元のシート(「商品一覧」シート)の選択されている行全体の値を、移動先のシート(「削除済み」シート)の表の末尾(lastRow)に入力しています。
入力後、移動元のシート(「商品一覧」シート)の選択されている行全体を削除しています。

以上の内容で、実行時に選択されているセルのデータを「削除済み」シートに移動することができます。


手順3: ボタンの作成

コードが完成しましたら、「商品一覧」シートに実行用のボタンを用意します。

ボタンは、[開発]タブの中の[挿入]から作成することができます。


完成

以上の手順で、機能が完成します。
実行することで、以下のように、実行時に選択しているセルの行のデータを「削除済み」シートの表の末尾に移動することができます。

▼サンプルファイル▼

2025/01/17
【ExcelVBA】自動で書類の発行日とお支払い期限を設定

【ExcelVBA】自動で書類の発行日とお支払い期限を設定

以下の請求書の書類フォーマットに関して、セルB7の件名を入力すると同時に、セルG4の発行日とセルC12のお支払い期限を自動入力する仕組みの実現方法について解説していきます。

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

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)
    
    If Target.Address = "$B$7" Then
        
        Dim d1 As Date
        Dim d2 As Date
        d1 = Date
        d2 = DateSerial(Year(d1), Month(d1) + 2, 0)
        
        Range("G4").Value = d1
        Range("C12").Value = d2
        
    End If
    
End Sub

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

Private Sub Worksheet_Change(ByVal Target As Range)
    
    If Target.Address = "$B$7" Then
        '省略
    End If
    
End Sub

「Worksheet_Change」というプロシージャの引数の「Target」に、編集されたセルの情報が渡されるため、そのセルの情報から、表の対象のセルが編集されたのかどうかを確認しています。
こちらでは、件名を入力するセルB7が編集されたかどうかを判定しています。

この条件を満たした場合に関してのみ、Ifの中の処理を実行します。

        Dim d1 As Date
        Dim d2 As Date
        d1 = Date
        d2 = DateSerial(Year(d1), Month(d1) + 2, 0)
        
        Range("G4").Value = d1
        Range("C12").Value = d2

先ほどの条件を満たしたときに、発行日(セルG4)とお支払い期限(セルC12)のセルに日付を入力します。
こちらでは、発行日に本日の日付、お支払い期限に翌月末の日付を入力しています。
本日の日付はDateで取得することができ、翌月末はDateSerialを活用して、翌々月の0日、即ち、翌々月の1日の1日前で翌月末の日付を取得しています。

以上の内容で実現できます。
セルB7の件名を入力することで、発行日とお支払い期限が入力されます。

※実行日は2025/1/8になります。

▼サンプルファイル▼

2025/01/10
【ExcelVBA】データ変更と同時にピボットテーブルを自動更新

【ExcelVBA】データ変更と同時にピボットテーブルを自動更新

通常、ピボットテーブルは、元の表を更新したら、ピボットテーブル自体を更新しなければ反映されません。
そのため、元の表のデータを高頻度で変更する場合、毎回ピボットテーブルを更新するのは、少し手間になります。
そこで、こちらでは、元の表のデータの変更と同時に、ピボットテーブルを自動で更新する仕組みの実現方法について解説していきます。

※こちらで仕組みを取り入れたファイルは、記事の最後にて配布しています。


事前準備

仕組みを実現する前に、ピボットテーブルが用意されているシート名とピボットテーブルの名前を確認します。
ピボットテーブルの名前は、対象のピボットテーブルを選択した時に表示される[ピボットテーブル分析]タブから確認することができます。

こちらでは、「ピボットテーブル1」という作成時の名前をそのまま活用していきますが、必要に応じて分かりやすい名前に変更した方が良いです。


開発準備

今回の仕組みは、「対象の表を編集すると同時に、対象のピボットテーブルを更新する」というものです。
このように、「特定のセルが編集されると同時に、何かしらの処理を実行する」という仕組みは、該当するシートモジュールイベントプロシージャを活用することで実現できます。

シートモジュールは、該当するシートのタブ上で右クリックし、[コードの表示]を選択することで表示することができます。

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

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

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

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

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


コードの記述

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

Private Sub Worksheet_Change(ByVal Target As Range)
    
    If Target.Row >= 2 And _
        Target.Column >= 1 And _
        Target.Column <= 4 Then
        
        Worksheets("売上一覧") _
            .PivotTables("ピボットテーブル1") _
            .PivotCache.Refresh
        
    End If
    
End Sub

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

Private Sub Worksheet_Change(ByVal Target As Range)
    
    If Target.Row >= 2 And _
        Target.Column >= 1 And _
        Target.Column <= 4 Then
        
        '処理
        
    End If
    
End Sub

「Worksheet_Change」というプロシージャの引数の「Target」に、編集されたセルの情報が渡されるため、そのセルの情報から、対象の表が編集されたかどうかを確認しています。
※今回のコードでは、複数のセルが同時に編集される場合を考慮していません。

こちらでは、「2行目以上、尚且つ、1列目から4列目の間のセル」と対象の表のデータ範囲が編集されたかどうかを確認しています。

この条件を満たした場合に関してのみ、Ifの中の処理を実行します。

        Worksheets("売上一覧") _
            .PivotTables("ピボットテーブル1") _
            .PivotCache.Refresh

こちらで、「売上一覧」シートにある「ピボットテーブル1」という名前のピボットテーブルを更新しています。

以上の内容で実現できます。
元の表のデータの変更と同時に、ピボットテーブルが自動で更新されることが確認できます。

▼サンプルファイル▼

2024/12/27
【ExcelVBA】複数シートの表を1つにまとめる

【ExcelVBA】複数シートの表を1つにまとめる

以下のように、複数シートの表(従業員別の1日の予定表)を、ボタンを押すだけで1つの表にまとめる機能の開発方法について解説していきます。

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

ExcelVBAレベル確認

開発準備

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

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

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

ExcelVBAレベル確認

コードの記述

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

Sub getSchedule()
    
    Dim mWs As Worksheet
    Set mWs = Worksheets("全員")
    
    Dim ws As Worksheet
    Dim i As Long
    
    mWs.Range("B4:B33").ClearContents
    
    For i = 4 To 33
        For Each ws In Worksheets
            If ws.Name <> mWs.Name Then
                If ws.Cells(i, "B").Value <> "" Then
                    mWs.Cells(i, "B").Value = _
                        mWs.Cells(i, "B").Value & _
                        ws.Name & ":" & ws.Cells(i, "B").Value & vbLf
                End If
            End If
        Next ws
    Next i
    
End Sub

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

    Dim mWs As Worksheet
    Set mWs = Worksheets("全員")

集約するシート情報を変数「mWs」に割り当てています。

    Dim ws As Worksheet
    Dim i As Long

繰り返し処理で扱う変数を定義しています。
変数「ws」は各シートを繰り返す際に活用し、変数「i」は各行を繰り返す際に活用します。

    For i = 4 To 33
        '処理
    Next i

Forでの予定表の先頭行から最終行までを繰り返しています。

        For Each ws In Worksheets
            If ws.Name <> mWs.Name Then
                '処理
            End If
        Next ws

繰り返し処理の内側のFor Eachでは、ブックに存在するシート1つ1つの情報を順番に変数「ws」に割り当てて、「全員」シート以外の場合に内側の処理を実行するように記述しています。

                If ws.Cells(i, "B").Value <> "" Then
                    mWs.Cells(i, "B").Value = _
                        mWs.Cells(i, "B").Value & _
                        ws.Name & ":" & ws.Cells(i, "B").Value & vbLf
                End If

最深部では、「全員」シート以外の各シートに対し、対象行(i)の予定の有無を確認しています。
先頭のIfで予定が存在しているかどうかを確認し、予定が存在している場合に、「全員」シートに追加するように記述しています。
「全員」シートに、元々の予定に加え、対象シート(ws)の対象行(i)の予定と改行(vbLf)を加えるように記述しています。

ExcelVBAレベル確認

ボタンの作成

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

ExcelVBAレベル確認

完成

以上の手順で、機能が完成します。
実行することで、以下のように、複数シートの予定の内容を「全員」シートにまとめて表示することができます。

▼サンプルファイル▼

2024/12/20
【ExcelVBA】簡単なマウス操作のみで販売数を入力

【ExcelVBA】簡単なマウス操作のみで販売数を入力

野外イベントなどで販売数を管理しながら受付業務を行う際、商品が購入される度、販売数の数値を直接入力するのは大変です。
そのため、こちらでは、特定の商品の販売数のセルをダブルクリックするだけで、その販売数に1を加えることができる機能を開発していきます。
また、何かしらの原因でデータが紛失しないように、販売数を加算する度、自動で保存される機能も加えていきます。

こちらでは、以下の商品ごとの販売数を管理した表を活用して開発していきます。

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


開発準備

「特定のセルをダブルクリックすると同時に、何かしら処理を実行する」という仕組みは、該当するシートモジュールイベントプロシージャを活用することで実現できます。

シートモジュールは、該当するシートのタブ上で右クリックし、[コードの表示]を選択することで表示することができます。

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

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

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

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

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


コードの記述

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

Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
    
    If Target.Column = 3 And _
        Target.Row >= 3 And _
        Target.Row <= 20 Then
        
        Cancel = True
        Target.Value = Target.Value + 1
        ThisWorkbook.Save
        
    End If
    
End Sub

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

Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
    
    If Target.Column = 3 And _
        Target.Row >= 3 And _
        Target.Row <= 20 Then

        '省略

    End If
    
End Sub

「Worksheet_BeforeDoubleClick」というプロシージャの引数の「Target」に、ダブルクリックされたセルの情報が渡されるため、そのセルの情報から、表の対象の範囲内がダブルクリックされたのかどうかを確認しています。
こちらでは、「3列目、尚且つ、3~20行目の間のセル」と販売数のセルの範囲内がダブルクリックされたかどうかを確認しています。

この条件を満たした場合に関してのみ、Ifの中の処理を実行します。

        Cancel = True
        Target.Value = Target.Value + 1
        ThisWorkbook.Save

セルをダブルクリックすると、通常、セルが編集モードになるのですが、引数の「Cancel」をTrueにすることで、編集モードにならなくなります。
その後、ダブルクリックされたセルの値に1を加えて、ブックを保存しています。

以上の内容で実現できます。
販売数のセルをダブルクリックすることで、ダブルクリックされたセルの値に1を加えて、ブックが保存されます。

▼サンプルファイル▼

2024/12/13
【ExcelVBA】データを入力する度に自動で並べ替え

【ExcelVBA】データを入力する度に自動で並べ替え

以下の表では、氏名を入力した後にクラスを入力するだけで、自動で該当するクラスの位置に移動するようになっています。

このような、特定の項目に値を入力すると同時に、その項目を基準に自動で並べ替えするという機能の開発方法について解説していきます。
※こちらで開発したファイルは記事の最後にて配布しています。

ExcelVBAレベル確認

開発準備

「特定のセルに値を入力すると同時に、何かしら処理を実行する」という仕組みは、該当するシートモジュールイベントプロシージャを活用することで実現できます。

シートモジュールは、該当するシートのタブ上で右クリックし、[コードの表示]を選択することで表示することができます。

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

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

次に、隣のリストから「Change」を選択します。

「Change」を選択すると表示される「Worksheet_Change」というプロシージャ内にコードを記述します。
他のプロシージャに関して、使用していない場合は削除して問題ないです。

ExcelVBAレベル確認

コードの記述

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

Private Sub Worksheet_Change(ByVal Target As Range)
    
    Dim rng As Range
    For Each rng In Target
        If rng.Column = 2 Then
            Range("B2").Sort _
                Key1:=Range("B2"), _
                Order1:=xlAscending, _
                Header:=xlYes
        End If
    Next rng
    
End Sub

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

Private Sub Worksheet_Change(ByVal Target As Range)

「Worksheet_Change」というプロシージャは、該当するシートのセルが編集されると同時に実行されます。
その際、編集されたセルの情報が引数の「Target」に渡されます。
引数の「Target」を活用して、今回の場合は、クラスの項目(列)が編集されたかどうかを判断し、編集された場合に、その項目(列)を基準に昇順に並べ替えを行います。

    Dim rng As Range
    For Each rng In Target
        If rng.Column = 2 Then
            '省略
        End If
    Next rng

今回の場合、同時に編集されたセルは1つであることが多いかと思いますが、複数セルが同時に編集することもあります。(コピー&ペーストやCtrlキーを押しながらの同時入力など)
複数セルを同時に編集した場合は、引数の「Target」に複数セルの情報が渡されます。
そのため、複数セルの同時入力を考慮し、「Target」のセルの情報をFor Eachで1つずつを変数「rng」に渡して確認しています。

次に、変数「rng」の列番号が2、即ち、B列のクラスの項目の位置であることを確認しています。B列の場合のみに次の処理を実行します。
※必要に応じて「行番号が3以上の場合」などといった条件を加えても良いです。

            Range("B2").Sort _
                Key1:=Range("B2"), _
                Order1:=xlAscending, _
                Header:=xlYes

こちらで、セルB2が含まれる表に対し、「Sort」で並べ替えを行っています。
「Key1:= Range(“B2”)」でセルB2の属する列を並べ替えの基準の列として指定し、「Order1:=xlAscending」で昇順を指定、「Header:=xlYes」で項目名を含む範囲ということを指定しています。

以上の内容で実現できます。
クラスの項目に値を入力すると同時に、自動で並べ替えられます。

▼サンプルファイル▼