2025/12/09
【Excel】オンライン会議で使える拡大機能

【Excel】オンライン会議で使える拡大機能

オンライン会議などでExcel画面を共有しているときに、「文字が小さくて見えません」と言われたことはありませんか?
だからと言って、拡大しながら画面を操作するのは大変ですよね。

今回は、見せたい範囲を瞬時に拡大(ズーム)することができる機能を紹介します。


選択範囲に合わせて拡大/縮小

見せたい範囲を瞬時に拡大するときに便利な機能、それは「選択範囲に合わせて拡大/縮小」です。

まずは、見せたい範囲を以下のように選択します。

特定の項目のみを見せたいときは、その列全体を選択すると良いです。

次に、[表示]タブから[選択範囲に合わせて拡大/縮小]を選択します。

そうすることで、以下のように選択がすべて収まる最大のサイズに調整されます。

他の範囲に移る際は、隣の[100%]を選択して、表示倍率を100%に戻すとよいです。

2025/12/05
【Excel】表の順番をローテーション

【Excel】表の順番をローテーション

以下のように、特定の項目の、要素の順番を回転させる方法について、2通りで解説していきます。

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


方法1

1つ目は、末尾のデータを切り取りして、先頭に挿入するという方法です。

まずは、末尾のデータを選択します。

次に、緑の枠の上にカーソルを移動させ、Shiftを押しながら先頭までドラッグすることで、簡単に切り取りと挿入を行うことができます。

しかし、この方法の場合、行数が多い表や複数項目を回転させる必要がある場合に、若干面倒になります。
そんな時は、次の方法が便利です。

ExcelVBAレベル確認

方法2

2つ目は、並べ替え用の数値が入力された項目を用意し、その列を基準に並べ替えるという方法です。
具体的には以下のように、各行の行番号を常に表示し、末尾のみ「1」と表示されるような項目を数式で用意して、対象の項目のみを並べ替えます。

そのような特殊な項目は、以下の数式を入力することで実現できます。

=IF(ROW()=COUNTA($C$3:$C$17)+2,1,ROW())
// ROW()=COUNTA(…)+2:「数式を入力したセルの行番号」と「データの件数+2」が等しい
// 1:先ほどの条件を満たしたときに「1」を表示
// ROW():先ほどの条件を満たさない時に「数式を入力したセルの行番号」を表示

この数式を表の末尾までコピーすることで、各行の行番号、末尾のみ「1」と表示させることができます。

最後に、並べ替える対象の範囲(見出しを含む)のみを選択し、フィルターを設定します。

以上で、準備完了です。
番号が入力された列を基準に、フィルターボタンから昇順にすることで、データを回転することができます。

番号以外の項目に罫線を設定すると、表が見やすくなります。

▼サンプルファイル▼


方法2の注意点

フィルターを設定せずに、[データ]タブから並べ替えしてしまうと、以下のように、先頭列も並べ替えられてしまいます。

2025/12/02
【Excel】図形の幅ギリギリまでテキストを表示

【Excel】図形の幅ギリギリまでテキストを表示

図形にテキストを入力すると、以下のように、「余白が広すぎて全体が表示されない」といったことがあります。

実は、ある設定を行うことで、図形の幅ギリギリまでテキストを表示することができるようになります。
今回は、その方法について紹介していきます。


設定手順

まずは、対象の図形の書式設定を開きます。

次に、[サイズとプロパティ]の[テキストボックス]を展開して、[テキストを図形からはみ出して表示する]にチェックし、[図形内でテキストを折り返す]のチェックを外します。

そして最後に、テキストを中央揃えにします。

以上で、設定完了です。
手動で改行する必要はありますが、図形の幅ギリギリまでテキストを表示することができます。

2025/11/28
【Excel】予定表から「次回の予定」を抽出(XLOOKUP)

【Excel】予定表から「次回の予定」を抽出(XLOOKUP)

以下のように、予定表から「次回の予定」と「次回の予定までの日数」をXLOOKUP関数で抽出する方法について紹介していきます。

※上記の「2025/11/17」は基準の日付になります。
※こちらで作成したファイルは、記事の最後にて配布しています。


1. 次回の予定の抽出

まずは、次回の予定を抽出します。
そのために、次回の予定の基準となる日付(本日の日付)をTODAY関数で表示しておきます。

=TODAY()

では、表示した日付を基準に、次回の予定を抽出していきます。

抽出対象の予定は、基準の日付以上で最も近い日付の予定になります。
その内容を、以下のようにXLOOKUP関数で指定します。
※以下の数式では、抽出した予定に「まで」という文字列を加えています。

=XLOOKUP(B2,予定表!A:A,予定表!B:B,"",1)&"まで"
// B2:検索値(日付のセル)
// 予定表!A:A:予定表の日付の列
// 予定表!B:B:予定表の予定の列
// "":対象の予定が見つからない時に表示する値(空)
// 1:一致モード(完全一致または次に大きい項目)
// &"まで":抽出された予定に「まで」という文字列を加える

このように抽出することができます。
基準の日付をセルに表示したくない場合は、検索値の「B2」に直接TODAY関数を指定してもよいです。

=XLOOKUP(TODAY(),予定表!A:A,予定表!B:B,"",1)&"まで"

2. 次回の予定までの日数

次に、次回の予定までの日数を抽出します。
しかし、予定表の中には、次回の予定までの日数が表示されていないため、少し計算が必要です。

そのため、まずは、以下のように次回の予定の日付を抽出します。

=XLOOKUP(B2,予定表!A:A,予定表!A:A,"",1)
// 予定表!A:A:検索範囲と戻り範囲を同じにする

また、上記のように、日付ではなくシリアル値として表示します。
日付が表示された場合は、表示形式を「標準」に戻すことでシリアル値になります。

次回の予定までの日数は、抽出されたシリアル値から基準の日付のシリアル値を引いた数になります。
そのため、先ほどの抽出された数値からセルB2の日付を引きます。
※以下の数式では、求めた日数の前後に「残り」と「日」という文字列を加えています。

="残り"&XLOOKUP(B2,予定表!A:A,予定表!A:A,"",1)-B2&"日"
// "残り"&:求めた日数の先頭に「まで」という文字列を加える
// XLOOKUP(…)-B2:次回の予定までの日数
// &"日":求めた日数の末尾に「日」という文字列を加える

このように、求めることができます。
基準の日付をセルに表示しない場合は、「B2」を引くのではなく直接TODAY関数を引いてもよいです。

="残り"&XLOOKUP(B2,予定表!A:A,予定表!A:A,"",1)-TODAY()&"日"
ExcelVBAレベル確認

まとめ

以上の手順で、予定表から「次回の予定」と「次回の予定までの日数」を抽出することができます。

▼サンプルファイル▼

2025/11/25
【Excel】XLOOKUPがVLOOKUPより便利な点(3選)

【Excel】XLOOKUPがVLOOKUPより便利な点(3選)

Excel2021以降で使用できるXLOOKUP関数は、VLOOKUP関数の欠点を解消しています。
その中で、特にVLOOKUP関数よりも便利に感じた点を3つ紹介していきます。


便利に感じた点①

1つ目は、検索値の項目の位置が自由になったという点です。
VLOOKUP関数では、必ず検索値の項目が指定した表の一番左側にある必要がありました。
しかし、XLOOKUP関数では、検索値の項目と抽出する項目を別々で指定するため、表の一番左側にある必要がなくなりました。

ExcelVBAレベル確認

便利に感じた点②

2つ目は、抽出する項目の位置を列番号で指定する必要がなくなったという点です。
VLOOKUP関数では、抽出する項目の位置を、指定した表の先頭からの列番号で指定する必要がありました。
しかし、XLOOKUP関数では、抽出する項目を直接指定するだけでよくなりました。

ExcelVBAレベル確認

便利に感じた点③

3つ目は、IFERROR関数などでエラー対策をする必要がないという点です。
VLOOKUP関数では、検索条件に合う抽出対象が存在しない時は「#N/A」というエラーになってしまいました。
そのため、エラーではなく「なし」のような別の文字を指定するには、IFERROR関数などを組み合わせて実現していたかと思います。
しかし、XLOOKUP関数には、「見つからない場合」という引数が追加され、IFERROR関数などを組み合わせる必要がなくなりました。


まとめ

今回紹介した3つ以外にも、XLOOKUP関数には多くの魅力があります。
XLOOKUP関数が使える環境の方で使ったことがない方は、ぜひ使ってみてください。

動画でも解説しています。

>今後主流の「XLOOKUP関数」の魅力とは

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を加算
そうでない場合は、徐々に加算する数を減らす
ExcelVBAレベル確認

4. ボタンの作成

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

ExcelVBAレベル確認

5. 完成

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

▼サンプルファイル▼

2025/11/18
【Excel】タスク管理表から完了日順に抽出

【Excel】タスク管理表から完了日順に抽出

以下のようなタスク管理表から、直近に完了したタスクをすぐに確認したいとき、ぱっと見では分かりづらいです。

とはいえ、毎回並べ替えするのも面倒…

ということで今回は、数式で完了したタスクのみを完了日順に抽出する方法について紹介していきます。


1. 完了したタスクを抽出する

今回の場合、以下の表の、完了日の項目に値が入力されているタスクが「完了したタスク」になります。

そのため、完了日に何かしら値が入力されている行のみを「FILTER関数」で抽出します。

タスク管理表(見出し行を除く)が3行目から27行目まで用意されている場合の数式は、以下になります。

=FILTER(B3:E27,E3:E27<>"","")
// B3:E27:抽出対象の項目の範囲(タスク管理表のデータの範囲)
// E3:E27<>"":抽出条件(完了日の項目が空でない)
// "":対象が見つからない場合に表示する値(何も表示しない)

上記の数式で、完了したタスクのみを抽出することができます。


2. 完了日を基準に降順にする

次に、先ほど抽出した「完了したタスク」を、「SORT関数」で完了日を基準に降順にします。

その数式は、以下になります。

=SORT(FILTER(B3:E27,E3:E27<>"",""),4,-1)
// FILTER(B3:E27,E3:E27<>"",""):並べ替え対象の表(FILTER関数で抽出した表)
// 4:並べ替える基準の列(完了日の項目は先頭から4列目)
// -1:順序(降順)

上記の数式で、完了日を基準に降順にすることができます。

2025/11/14
【Excel】抽出データの増減に合わせて罫線を自動設定

【Excel】抽出データの増減に合わせて罫線を自動設定

以下のように、FILTER関数などを用いた数式でデータを抽出し、その抽出された表のサイズに合わせて罫線を設定してしまうと、抽出されるデータの件数が変わった時に罫線が合わなくなってしまいます。

そこで今回は、数式でデータを抽出する際に、その抽出されたデータの件数に合わせて罫線を自動で設定する方法について紹介していきます。

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


1. データの間の罫線を点線にする

こちらでは、以下のように、データの間の罫線を点線に、末尾の罫線を実線にしていきます。

まずは、データの間の罫線を点線していきます。

データの増減に合わせて罫線などの書式を自動で変更するには、「条件付き書式」を活用します。

はじめに、見出し以外の罫線が設定されていない状態にし、今後データが追加されることを考慮したデータの範囲のみを選択します。

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

表示された以下の設定画面で、[ルールの種類]を[数式を使用して、書式設定するセルを決定]にします。

次に、表示されたテキストボックスに、点線の罫線を設定する条件式を入力します。

今回の表では、「No」の値の有無で判断していきます。
点線の罫線を設定するときとは、「No」が表示されているときになります。
そのため、以下の条件式を入力します。

=$A5<>""
// A5は選択基準のセル
// 他の選択範囲に反映する際に、A列を固定するため、Aに「$」を指定

次に、[書式]を選択し、[罫線]タブから下側の罫線を点線にします。

上記の内容で確定することで、データが存在する行の下側に点線の罫線を設定することができます。

ExcelVBAレベル確認

2. データの末尾の罫線を実線にする

次は、データの末尾の罫線を実線にしていきます。

初めに、先ほどと同じ範囲を選択し、条件付き書式の設定画面を開きます。

次は、罫線を実線にする条件式を入力します。

こちらも先ほどと同様に、「No」の値の有無で判断していきます。
実線の罫線を設定するときとは、「No」が表示されていて、かつ、その次の行の「No」が表示されていないときになります。
そのため、以下の条件式を入力します。

=AND($A5<>"",$A6="")
// A5は選択基準のセル
// A6は選択基準の下のセル
// 他の選択範囲に反映する際に、A列を固定するため、Aに「$」を指定

次に、[書式]を選択し、[罫線]タブから下側の罫線を実線にします。

上記の内容で確定することで、表の末尾に実線の罫線を設定することができます。


3. 完成

以上の内容で完成です。
数式によって抽出されたデータの増減に合わせて、罫線が自動で設定されます。

▼サンプルファイル▼

2025/11/11
【Excel】新機能『TRIM参照』が便利すぎた

【Excel】新機能『TRIM参照』が便利すぎた

以下の表の「合否」の項目には、数式が入力されています。

この数式の場合、表示する行全体(C3~C9)に、数式をコピーする必要があります。

そこで今回は、数式をコピーする必要のない、新機能『TRIM参照』を活用した方法について紹介していきます。


スピルの活用

まずは、スピルを活用した数式に修正します。
スピルとは、数式を入力したセルから、結果を展開して表示する機能です。

>スピルについての詳しい解説はこちら

以下の表の場合、結果を9行目まで表示させる必要があります。

そのため、「合否」の先頭のセルに、以下のスピルを活用した数式を入力します。

=IF(B3:B9>=60,"合格","不合格")

ただ、このままだと、10行目以降にデータが追加された際に、毎回手動で数式を更新する必要があります。
とはいえ、以下のように、予め大きめの範囲を指定すると、データがない行まで計算処理が行われてしまいます。

=IF(B3:B100>=60,"合格","不合格")

無駄な行まで計算処理が行われると、ファイルの計算処理が重たくなってしまう原因にも繋がりかねません。


TIRM参照の活用

そこで、新機能の「TRIM参照」を活用します。
TRIM参照とは、指定した範囲の先頭や末尾から空白を除外した範囲を参照する参照方法です。

>TRIM参照についての詳しい解説はこちら

以下のように、「:」の後に「.」を加えます。

=IF(B3:.B100>=60,"合格","不合格")

たったこれだけで、以下のように、「B3~B100」の末尾の空白セルを除外した範囲のみを指定して計算することができます。

TRIM参照を活用することで、データの追加にも対応することができます。

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

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

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

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

ExcelVBAレベル確認

1. 開発準備

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

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

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

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

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

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

ExcelVBAレベル確認

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. ボタンの作成

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

ExcelVBAレベル確認

4. 完成

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

▼サンプルファイル▼

2025/11/04
【Excel】各フォルダへのハイパーリンクを瞬時に作成

【Excel】各フォルダへのハイパーリンクを瞬時に作成

表の各データに対応したフォルダへのハイパーリンクを作成する際、1つ1つ、「ハイパーリンクの挿入」画面から割り当てるのは大変です。

各データに対応したフォルダの位置に、以下のような法則性がある場合は、瞬時にハイパーリンクを作成する方法があります。

『すべてのフォルダは同じ配下に配置されており、フォルダ名は「No_氏名」の構成になっている

ということで今回は、各データに対応したフォルダの位置に法則性がある場合、その各フォルダを表示するハイパーリンクを瞬時に作成する方法について紹介していきます。

ExcelVBAレベル確認

セルの値を活用してハイパーリンクを作成する

各データに対応したフォルダを作成する場合は、HYPERLINK関数が便利です。
この関数なら、セルの値を活用したハイパーリンクを作成することができます。

まずは、先頭のデータに対応したフォルダのパスを確認します。
こちらの場合は、「A:\生徒管理\1_渡辺 紬」になります。

次に、対象のフォルダの上で右クリックし、パスをコピーします。
OSのバージョンによっては、Shiftキーを押しながら右クリックする必要があります。

次に、以下の数式を先頭行に入力します。

=HYPERLINK("A:\生徒管理\1_渡辺 紬","開く")
// フォルダのパスの部分(赤)は、コピーしたパスを貼り付ける

これで、先頭のデータに対応したフォルダを開くハイパーリンクを作成することができます。

他のデータに関しては、先ほどのフォルダのパスの一部を変更する必要があります。
こちらの場合は、「No_氏名」がフォルダの名前になるため、以下のように、セルの値を参照した数式に書き換えます。

=HYPERLINK("A:\生徒管理\"&B3&"_"&C3,"開く")
// 「&」で「No_氏名」となるように繋げる

最後に、入力した数式を表の末尾までコピーするだけで完成です。

これで、該当行のハイパーリンクをクリックするだけで、対象のフォルダを開くことができます。

※以下のような警告が表示される場合は、「はい」を選択することで、フォルダを表示できます。

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. 完成

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

▼サンプルファイル▼