2024/11/25
【Excel】予定表から労働時間を色んな形式で求める

【Excel】予定表から労働時間を色んな形式で求める

今回は、以下の予定表(30分刻みで予定が入力されている表)から労働時間を求める方法について解説していきます。

※こちらの予定表は8:00から20:00までを30分刻みにした表になります。


予定の数を求める

こちらでは、以下の3通りで労働時間を求めていきます。

・時刻形式「(例)9:30」
・分形式「(例)570」
・時間形式「(例)9.5」

労働時間を求めるにあたり、予定表の[予定]の項目で予定が入力されているセルの数を求める必要があります。
以下の表の場合は、セルC5からC29の範囲内で、空白でないセルの数が予定の数になります。

特定の範囲で空白でないセルの数を求めるには、COUNTA関数を活用します。
この関数の使い方は、以下になります。

=COUNTA(値1, [値2], [値3], …)
// 値:対象のセル(2以降は省略可能)

実際に活用して求める場合、以下のような数式になります。

=COUNTA(C5:C29)

では、この予定の数から色んな形式で労働時間を求めていきます。


時刻形式「(例)9:30」

まずは、時刻形式で求めていきます。

今回の予定表は30分刻みになります。
そのため、「予定の数×30分」で時刻を求めることができます。

ただ、「9:30」というような時刻形式はシリアル値(時間を管理している番号)で計算する必要があります。

>シリアル値とは

シリアル値の30分を掛ける場合は、以下のような数式になります。

=COUNTA(C5:C29)*"0:30"

計算結果はシリアル値で表示されてしまうため、表示形式を時刻形式にする必要があります。
こちらでは、[ホーム]タブの[その他の表示形式]より、[時刻]の[h:mm]形式を指定します。

表示形式を時刻形式にすることによって、以下のように「9:30」と労働時間を表示することができます。

ExcelVBAレベル確認

分形式「(例)570」

次は、分形式で求めていきます。

今回の予定表は30分刻みのため、分形式で求める場合は、単純に「予定の数×30」で求めることができます。
実際に求める場合は、以下のような数式になります。

=COUNTA(C5:C29)*30

※表示形式は「標準」にしています。


時間形式「(例)9.5」

最後に、時間形式で求めていきます。

今回の予定表は30分刻みのため、分形式を求める場合と同様に、「予定の数×30」で分を求め、1時間は60分のため、「予定の数×30÷60」で求めることができます。
実際に求める場合は、以下のような数式になります。

=COUNTA(C5:C29)*30/60

※表示形式は「標準」にしています。

2024/11/23
【業務】予定表から週単位で抽出

【業務】予定表から週単位で抽出

#TEXTJOIN #CHAR #FILTER #表示形式 #スピンボタン

YouTubeで開く

予定表から予定を1週間単位で抽出する方法について解説しています。
予定表に同じ日付の予定が複数件含まれる場合にも対応しています。
他にも、色んな小技を組み合わせて実現しています。

00:00 挨拶
00:55 完成イメージ
02:36 準備
03:02 作成(1週間分の日付表示)
04:13 作成(予定の抽出)
09:19 作成(曜日の表示)
11:14 作成(改行して曜日を表示)
13:18 作成(ウィンドウ枠の固定)
13:51 作成(スピンボタンで日付変更)
18:07 完成
19:08 プレゼントについて

▼準備ファイル▼

2024/11/22
【ExcelVBA】カテゴリー単位でセルを自動結合

【ExcelVBA】カテゴリー単位でセルを自動結合

以下の表のカテゴリーの項目のように同じ値が複数行に続く場合、それらの同じ値のセルを瞬時に結合する機能の開発方法について解説していきます。

こちらで開発する機能は、どんな表にも適用できるようしています。
そのため、既存の表をプレゼン用や配布用として用意する際に活用すると便利です。
※こちらで開発したファイルは、記事の最後にて配布しています。


開発準備

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

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

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


コードの記述

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

Sub 自動結合()

    Dim colNo As Long
    colNo = ActiveCell.Column
    Dim lastRow As Long
    lastRow = Cells(Rows.Count, colNo).End(xlUp).Row
    
    Dim sRow As Long
    sRow = 1
    Dim i As Long
    Application.DisplayAlerts = False
    For i = 1 To lastRow
        If Cells(i, colNo).Value <> Cells(i + 1, colNo).Value Then
            Range(Cells(sRow, colNo), Cells(i, colNo)).Merge
            sRow = i + 1
        End If
    Next i
    Application.DisplayAlerts = True
    
End Sub

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

    Dim colNo As Long
    colNo = ActiveCell.Column

今回の機能は、選択しているセルの列に対して、同じ値が連続するセルを結合していきます。
そのため、基準となる列番号を格納する用の「colNo」という変数を用意し、アクティブセル(ActiveCell)の情報から列番号(Column)を取得しています。

    Dim lastRow As Long
    lastRow = Cells(Rows.Count, colNo).End(xlUp).Row

先頭行から1行ずつ、同じ値が連続していないかどうかを確認していきます。
そのため、繰り返し終える位置である最終行の行番号を格納する用の「lastRow」という変数を用意し、「colNo」の列を基準に最終行の行番号を取得しています。
取得される行番号は、「colNo」の列の、シート上の一番下のセル(Cells(Rows.Count, colNo))を選択している状態で、「Ctrl+↑」(End(xlUp))で移動した先のセルの行番号(Row)になります。

    Dim sRow As Long
    sRow = 1

こちらに関しては、結合する際の開始の行番号を格納する用の「sRow」という変数を用意しています。
また、初期値として「1」を設定しています。

    Dim i As Long
    Application.DisplayAlerts = False
    For i = 1 To lastRow
        …
    Next i
    Application.DisplayAlerts = True

次に、先頭行から最終行までを繰り返す時に使用する「i」という変数を用意し、繰り返し処理(For)の前に、結合時の以下の警告を無視する設定(Application.DisplayAlerts = False)を行っています。

繰り返し処理(For)を終えた後には、警告を無視する設定を解除するコード(Application.DisplayAlerts = True)を記述しています。

    For i = 1 To lastRow
        If Cells(i, colNo).Value <> Cells(i + 1, colNo).Value Then
            Range(Cells(sRow, colNo), Cells(i, colNo)).Merge
            sRow = i + 1
        End If
    Next i

では最後、繰り返し処理(For)の内容です。
繰り返し処理(For)では、先頭行から最終行(lastRow)まで1行ずつ繰り返し、内側の条件分岐(If)で、「繰り返し処理の該当行(i)の該当列(colNo)の値と、その次の行(i + 1)の値が一致しない場合」という条件の確認を行っています。
一致しない場合に関しては、該当列(colNo)の開始の行(sRow)から繰り返し処理の該当行(i)までの範囲のセルを結合(Merge)しています。
結合後は、次の結合時の開始の行番号(sRow)を繰り返し処理の該当行(i)の次の行番号(i + 1)に変更しています。

上記のコードを実行することによって、選択しているセルの列に対して、同じ値が連続するセルを結合することができます。

以下のコードに関しては、単体のセル範囲では結合されません。

Range(Cells(sRow, colNo), Cells(i, colNo)).Merge

そのため、今回のようなコードの内容で実現することができます。

▼サンプルファイル▼

2024/11/20
【Excel】クイック分析の活用

【Excel】クイック分析の活用

簡単な集計を行う場合、「クイック分析」という機能が便利です。
こちらでは、以下の表に対し、各行の数値全体に対する比率を「クイック分析」を活用して求めていきます。


比率を求める

まずは、比率を求める際に元となる数値の範囲を選択します。

選択した範囲付近にカーソルを移動すると、クイック分析のアイコンが右下に表示されます。
そのアイコンを選択し、以下のメニューを表示します。
※「Ctrl+Q」でも表示することができます。

比率などを求めたい場合は、メニューの中の[合計]を選択します。

[合計]の中に表示された青色を含むアイコンに関しては、選択範囲の下に数式を入力するという機能になります。
今回の場合は、選択範囲の右隣りに比率を求める数式を入力したいので、オレンジ色を含むアイコンの中から「合計(%)」を選択します。
※アイコンの上にカーソルを重ねるだけで、どのような値が表示されるのかを確認することができます。

アイコンを選択することで、以下のように、自動で比率を求める数式を入力することができます。

ExcelVBAレベル確認

注意点

クイック分析を活用して数式を入力すると、既存の値は上書きされてしまいます。

そのため、活用する際は、予め表示する範囲に空の列(行)を追加しておく必要があります。

ちなみに、上書きする可能性がある場合は、以下のような警告が表示されます。

クイック分析のアイコンにカーソルを重ねるだけでも、集計結果を表示して確認することができるので、実際に数式を入力せずに確認した場合などは、空の列(行)を用意していなくても問題ございません。


補足

クイック分析では、数式を入力する機能以外にも、「条件付き書式の設定、グラフの作成、テーブルの作成、スパークラインの設定」などと多くの機能が用意されています。
また、これらの機能に関しても、アイコンにカーソルを重ねるだけで、プレビューを表示して確認することができます。

2024/11/18
【Excel】いずれかの条件を満たすデータの集計

【Excel】いずれかの条件を満たすデータの集計

以下の売上管理表を元に、商品名が「A」もしくは「B」などと、複数指定した商品の売り上げを合計する方法について解説していきます。
こちらでは、2つの商品を指定して、その2つの商品の売り上げの合計を求めていきます。

※集計の対象行を色付けしています。


スピルを使わない場合

まずは、スピルを使わずに求める方法について解説していきます。

スピルを使わない場合は、SUMIF関数を使います。
SUMIF関数では、指定した条件を満たしたデータのみを集計することができます。
この関数の使い方は、以下になります。

=SUMIF(範囲, 検索条件,  [合計範囲])
// 範囲:対象を絞り込むためのデータ範囲
// 検索条件:「範囲」に指定したデータ範囲から絞り込む条件
// [合計範囲]:合計を求めたいデータ範囲(省略時は「範囲」と同じになる)

実際に、以下の表のセルF3の値と一致する商品名の売上を求める場合、以下のような数式になります。

=SUMIF(C:C,F3,D:D)

後は、同様にもう片方(セルF4)の商品名の売上を求め、以下のように加算することで、複数の商品の売り上げの合計を求めることができます。

=SUMIF(C:C,F3,D:D)+SUMIF(C:C,F4,D:D)

複数条件を満たすデータのみを集計するSUMIFS関数というものもありますが、この関数の場合は、「いずれかを満たす」という条件を指定することができません。
そのため、上記のように、SUMIF関数で1つ1つの合計を求めてから加算しています。

この方法の注意点としては、加算するそれぞれの合計の中に重複したデータが含まれていた場合は、正しく集計できないという点です。

例えば、以下のような表で、「「商品1」が「A」もしくは「商品2」が「B」」の商品を集計する場合、加算する方法では正しく求められない可能性があります。
以下の例の場合は、赤色の枠で囲まれたデータが重複して加算されてしまっています。

=SUMIF(C:C,H3,E:E)+SUMIF(D:D,H4,E:E)

そのため、データが重複する際は、重複分を引く数式を更に加える必要があります。
(こちらでは解説を省略)

上記の注意点を踏まえると、スピルを活用した次の方法がオススメになります。


スピルを使う場合

次に、スピルを使って求める方法について解説していきます。

スピルが使える環境(Excel2021以降、もしくは365)では、FILTER関数が活用できます。
FILTER関数では、指定した条件を満たしたデータのみを抽出することができます。
この関数の使い方は、以下になります。

=FILTER(配列, 含む, [空の場合])
// 配列:抽出対象のデータ範囲
// 含む:抽出する条件
// [空の場合]:抽出対象が存在しない時に表示する値(省略時はエラーになる)

実際に、以下の表のセルF3とF4の値を含む商品名の売上を抽出する場合、以下のような数式になります。

=FILTER(D:D,(C:C=F3)+(C:C=F4))
// 「または」という条件は、条件式を「+」で繋げる必要がある
// 「空の場合」は、こちらでは省略する

後は、この抽出された売上の合計を求めていきます。
その際は、以下のように、全体をSUM関数で囲むことで求めることができます。

=SUM(FILTER(D:D,(C:C=F3)+(C:C=F4)))

FILTER関数を活用することで、データが重複して抽出される心配がなくなります。
例えば、以下のような表で、「「商品1」が「A」もしくは「商品2」が「B」」の商品を集計する場合、以下のような数式で求めることができます。

=SUM(FILTER(E:E,(C:C=H3)+(D:D=H4)))
2024/11/16
【番外-045】数式で指定年月のデータを抽出

【番外-045】数式で指定年月のデータを抽出

#FILTER #DATE

YouTubeで開く

表の中の指定した年月のデータを抽出する方法について解説しています。

00:00 挨拶
00:25 準備
00:58 FILTER関数の使い方
03:19 FILTER関数で指定年月を抽出
08:31 プレゼントについて

▼準備ファイル▼

2024/11/15
【Excel】複数シートの表を数式で1つにまとめる

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

以下のように、数式で複数のシートに用意された表を1つのシートにまとめて表示する方法について解説していきます。


複数の表を縦方向に繋げる

複数の表を縦方向に繋げるには、VSTACK関数を活用します。
この関数の使い方は、以下になります。

=VSTACK(配列1, [配列2], [配列3], …)
// 配列:対象の表(必要な数分、カンマ区切りで指定する)

実際に、各シートの表を指定して表を繋げる場合、以下のような数式になります。

=VSTACK('2024年1月'!A2:C10,'2024年2月'!A2:C10,'2024年3月'!A2:C11,'2024年4月'!A2:C11,'2024年5月'!A2:C11)
// それぞれのシートの表を1つ1つ指定

VSTACK関数を使うことで、上記のように表を繋げることができました。
しかし、この数式のままですと、「シートの数が増えた時」や「表にデータが追加された時」に対応するのが大変になります。
そこで、複数のシートの表を一括で指定する数式に変更していきます。


複数の表を一括で指定する

複数のシートの範囲を一括で指定する場合、「=VSTACK(」と入力した後に、「対象の先頭のシート」を選択した後に、Shiftキーを押しながら、「対象の末尾のシート」を選択します。
この時、対象のシートの間に対象でないシートが含まれていると、その対象でないシート自体も参照されてしまいます。
対象の末尾のシートを選択することができましたら、アクティブになっているシートの表の範囲を大きめに指定します。
実際に上記の手順で指定すると、以下のような数式になります。

=VSTACK('2024年1月:2024年5月'!A2:C100)
// 今後データが追加されることを考慮して100行目まで指定

上記の数式を入力すると、空の範囲が「0」として抽出されてしまいます。
ただ、全シートの表を繋げることができました。

「0」を除外する方法については、後で解説していきます。

こちらで参照しているシートは、対象のシートの先頭から末尾のシートになります。
次から追加するシートに関しては、指定した先頭と末尾のシートの間に移動することで、数式を修正する必要がなく、まとめた表に加えることができるようになります。

そのため、先頭と末尾のシートに関しては「空の表」にし、シートの開始と終了が分かりやすいようなシート名にしておくと良いです。
実際に、修正した例が以下になります。

=VSTACK(S:G!A2:C100)

先頭と末尾のシートに関しては、以下のように空の表にしています。

以上の手順で、複数のシートの表を一括で指定し、抽出することができました。
ただ、空(「0」)のデータが表示されている状態では、見た目が良くないので、空(「0」)のデータを除外して抽出する数式に変更する必要があります。


空(「0」)のデータを除外する

抽出した表から、更に絞って抽出するには、FILTER関数を活用します。
この関数の使い方は、以下になります。

=FILTER(配列, 含む, [空の場合])
// 配列:抽出対象の表
// 含む:配列に指定した表から抽出する条件
// [空の場合]:条件を満たしたデータが存在しない場合に表示する値

先ほどの数式にFILTER関数を組み合わせると、以下のような数式になります。

=FILTER(VSTACK(S:G!A2:C100),VSTACK(S:G!A2:A100)<>"","")
// VSTACK(S:G!A2:C100):抽出対象の表
// VSTACK(S:G!A2:A100)<>"":抽出条件
// → 抽出対象の範囲のA列の値(日付の項目)が空でない場合
// "":データが存在しない場合は空を表示

上記のように、FILTER関数を組み合わせて抽出条件を加えることで、先頭列(日付の項目)が空のデータを除外して抽出することができます。
また、各シートの表へのデータの追加にも対応することができます。

2024/11/13
【Excel】期限が3日以内の未完了タスクを色付け

【Excel】期限が3日以内の未完了タスクを色付け

以下のタスク管理表で、本日の日付を基準に、期限が3日以内の未完了タスクの行全体を自動で色付けする方法について解説していきます。
※こちらでは、「本日を含めずに3日後以内の期限のタスク」を「期限が3日以内のタスク」としています。

※記事の最後に、解説に使用したファイルを配布しています。


条件式の作成

まずは、色付けする条件式を作成していきます。
例えば、以下のタスク管理表の先頭のタスク(5行)に関して、色付けするかどうかを判定する条件について考えていきます。

先頭のタスクを色付けする時の条件は、以下になります。

①タスク名(B列)に値が入力されているの場合
②期限(C列)が本日より3日以内の場合
③済(D列)が未入力の場合

条件①を数式で表すと、以下になります。

=B5<>""
// セルB5が空でない場合

条件②を数式で表すと、以下になります。

=C5<=TODAY()+3
// TODAY関数で本日の日付を取得し、セルC5が本日の日付に3を加えた日付以下の場合

条件③を数式で表すと、以下になります。

=D5=""
// セルD5が空の場合

これらの条件を組み合わせると、以下になります。

=AND(B5<>"",C5<=TODAY()+3,D5="")
// AND関数を用いて「尚且つ」という条件式にする

この数式を他のセルにコピーしても反映できるように、「$」を加えて一部の参照を固定します。
今回の表の場合、タスク名がB列、期限がC列、済がD列というのは固定になります。
そのため、以下のように列を固定します。

=AND($B5<>"",$C5<=TODAY()+3,$D5="")

この数式を、試しに表の隣のセルに入力し、行方向列方向にコピーしても、行単位で正しく反映されていることを確認します。

行単位で正しく反映できていることが確認できましたら、入力した数式は削除します。

以下のような条件式を作成することができましたら、後は条件付き書式で設定してきます。

=AND($B5<>"",$C5<=TODAY()+3,$D5="")
ExcelVBAレベル確認

条件付き書式の設定

まずは、色付けする可能性のある対象の範囲を全選択します。

先ほど作成した条件式は、5行目のタスクに対しての条件式であったため、選択基準のセル(アクティブセル)を5行目のセルB5にしています。

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

条件付き書式の設定画面にて、[ルールの種類]を[数式を使用して、書式設定するセルを決定]にし、表示されたテキストボックス内に、先ほど作成した条件式を入力します。
※アクティブセルに対する条件式を入力します。

条件式の入力ができましたら、[書式]を選択し、好みの書式を設定します。
こちらでは、書式設定の画面にて、[塗りつぶし]から黄色を設定します。

上記のように設定して確定することで、以下のように、「タスク名が入力されていて、尚且つ、期限が本日より3日以内の未完了タスク」の行全体を自動で色付けすることができます。

※こちらの数式の場合、本日を含めずに3日後以内としています。本日を含める場合は、「+3」ではなく「+2」とする必要があります。

▼サンプルファイル▼

2024/11/11
【Excel】複数シートの表から検索して値を抽出

【Excel】複数シートの表から検索して値を抽出

複数のシートに表が用意されており、シート名を指定することで、該当するシートの表から検索し、該当する値を抽出する方法について解説していきます。

こちらでは、商品価格表が支店ごとで別々のシートに用意されているファイルから、支店名(シート名)と商品名を指定するだけで、該当する支店の表から商品を検索し、その商品の価格を抽出する仕組みを実現していきます。


特定のシートから検索し抽出する

まずは、特定のシートの表から検索し値を抽出する数式を作成していきます。
表から値を抽出する関数には色んな関数がありますが、こちらでは、VLOOKUP関数で抽出していきます。
この関数の使い方は、以下になります。

=VLOOKUP(検索値, 範囲, 列番号, [検索方法])
// 検索値:検索する値
// 範囲:検索する表の範囲(検索する対象の項目を先頭とした範囲)
// 列番号:範囲の先頭から抽出したい項目の位置
// [検索方法]:TRUE(近似一致)もしくは、FALSE(完全一致)を指定
※[検索方法]を省略した場合は、近似一致で検索される

実際に活用してみると、以下のような数式になります。

=VLOOKUP(B5,東京!B:C,2,FALSE)

商品名の項目に入力した値で検索し、「東京」シートの表から該当する商品の価格を抽出しています。


複数のシートから検索し抽出する

では次に、複数のシートから検索できるように修正していきます。
先ほど作成した数式は、以下になります。

=VLOOKUP(B5,東京!B:C,2,FALSE)

今回のファイルは、支店名がシート名になります。

そのため、数式の中のシート名の部分(東京!)が支店名に指定した文字に切り替わるようにすることで、指定した支店のシートから検索し抽出することができるようになります。

ただ、シート名の部分を、以下のように直接、支店名のセルの値を結合した数式にしても、正しく抽出することができません。

=VLOOKUP(B5,B3&!B:C,2,FALSE)

その理由は、「東京!B:C」というのは、抽出対象の範囲を表す文字であって、ただの文字列ではないからです。
ただの文字列ではないので、「&」を使用することができません。

「&」を使用するために、範囲を表す文字を、一度「”」で囲み、ただの文字列にする必要があります。
ただ、「”」で囲った文字列は、範囲を表す文字ではなくなってしまいます。
そのため、「”」で囲った文字列を、再度、範囲を表す文字として認識させる必要があります。
その際は、INDIRECT関数を活用します。
この関数の使い方は、以下になります。

=INDIRECT(参照文字列)
// 参照文字列:参照先の情報

実際に活用してみると、以下のような数式になります。

=VLOOKUP(B5,INDIRECT(B3&"!B:C"),2,FALSE)

このようにして、指定した支店名のシートの表から、指定した商品名を検索し、その商品名と一致する商品の価格を抽出することができます。

2024/11/09
【業務】表を瞬時に絞り込む機能

【業務】表を瞬時に絞り込む機能

#テーブル #フィルター #ショートカット #AutoFilter #If #ListObject #ShowAllData

YouTubeで開く

フィルターでの絞り込み操作を、より快適にする機能の開発になります。

具体的には、絞り込みたい文言を含むセルを選択して、開発した機能を実行することで、そのセルの文言が自動入力されたインプットボックスが表示されます。
そのインプットボックスに表示された文言を必要に応じて修正して、確定することで、選択した項目に対し、その文言を含むセルのみを絞り込むことができます。

また、ショートカットキーで機能を実行することができるため、通常のフィルター機能よりも、高速に絞り込み操作を行うことができます。

00:00 挨拶
00:27 完成イメージ
02:37 準備
03:00 作成(テーブル)
04:16 作成(絞り込み機能)
11:29 作成(絞り込み解除機能)
15:24 作成(ショートカット)
16:53 完成
18:24 プログラムの全体
20:56 プレゼントについて

▼準備ファイル▼

2024/11/08
【ExcelVBA】項目名をクリックするだけで並べ替え

【ExcelVBA】項目名をクリックするだけで並べ替え

以下の表に対し、「項目名(見出し)をクリックするだけで、その項目を基準に並べ替えを行う」という機能の開発方法について解説していきます。

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

ExcelVBAレベル確認

開発準備

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

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

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

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

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

まずは、表示された「Worksheet_SelectionChange」というプロシージャ内にコードを記述していきますが、他のイベントプロシージャを表示したい場合は、右上のリストから表示することができます。

左上のリストで「Worksheet」を選択すると、右上のリストに関しては、自動で「SelectionChange」が選択され、「Worksheet_SelectionChange」というプロシージャが表示されます。


項目名をクリックするだけで昇順にする

では、項目名をクリックするだけで、その項目を基準に表を昇順にする機能を開発していきます。

まずは、以下のコードを「Worksheet_SelectionChange」というプロシージャ内に記述します。

Private Sub Worksheet_SelectionChange(ByVal Target As Range)

    If Target.Row = 2 And _
        Target.Column >= 2 And Target.Column <= 5 Then
        
        Dim rng As Range
        Set rng = Range("B2").CurrentRegion
        rng.Sort _
            Key1:=Target, _
            Order1:=xlAscending, _
            Header:=xlYes
        
    End If
    
End Sub

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

    If Target.Row = 2 And _
        Target.Column >= 2 And Target.Column <= 5 Then  End If

「Worksheet_SelectionChange」プロシージャの引数「Target」に、トリガーとなったセルの情報が渡されます。
そのTargetを活用し、そのTargetの情報が「行番号が2、尚且つ、列番号が2以上、5以下」であるかどうかを確認しています。
その条件を満たしている時、要するに、以下の項目名の範囲内が選択された時に、Ifの中の処理が実行されます。

        Dim rng As Range
        Set rng = Range("B2").CurrentRegion
        rng.Sort _
            Key1:=Target, _
            Order1:=xlAscending, _
            Header:=xlYes

こちらで「rng」というRange型の変数を用意し、その変数に対象の表の範囲を割り当てています。
「Range(“B2”).CurrentRegion」で、セルB2周囲に連続しているデータ範囲全体を指定しています。

その「rng」に対し「Sort」で並べ替えを行っています。
「Key1:=Target」でTargetの属する列を並べ替えの基準の列として指定し、「Order1:=xlAscending」で昇順を指定、「Header:=xlYes」でrngが項目名を含む範囲ということを指定しています。

以上の内容で実現できます。
該当する項目名を選択することで、以下のように並べ替えを行うことができます。


項目名を右クリックするだけで降順にする

では次に、項目名を右クリックすることで、その項目を基準に表を降順にする機能を開発していきます。

先ほどと同様に、シートモジュール上にコードを記述していきます。
ただ、先ほどとは別のイベントプロシージャを使用する必要があります。

そのプロシージャとは、該当するシート上のいずれかのセルの上で右クリックした時に処理が実行されるというイベントプロシージャです。
シートモジュールの右上のリストから「BeforeRightClick」を選択することで表示することができます。

表示された「Worksheet_BeforeRightClick」というプロシージャ内にコードを記述していきます。

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

Private Sub Worksheet_BeforeRightClick(ByVal Target As Range, Cancel As Boolean)
    
    If Target.Row = 2 And _
        Target.Column >= 2 And Target.Column <= 5 Then
        
        Cancel = True
        Dim rng As Range
        Set rng = Range("B2").CurrentRegion
        rng.Sort _
            Key1:=Target, _
            Order1:=xlDescending, _
            Header:=xlYes
        
    End If
    
End Sub

コードの内容は、先ほどの内容とほぼ同じになります。
そのため、異なる点のみを解説します。

        Cancel = True

「Cancel」に対し、Trueを指定することで、右クリック時にメニューが表示されないようにすることができます。

        rng.Sort _
            Key1:=Target, _
            Order1:=xlDescending, _
            Header:=xlYes

先ほどの内容とは異なり、こちらでは「Order1:=xlDescending」として降順にしています。

以上の内容で実現できます。
該当する項目名の上で右クリックすることで、以下のように並べ替えを行うことができます。

▼サンプルファイル▼