祝日を返すマクロ [Excel VBA]

はてブ数 2024/03/26 05:56 OS別::Windowsその他::技術情報
Excel VBA で、毎年祝祭日リストを更新しなくても祝日を自動計算して返すマクロができないか見ていたら、なんとできそうでした。

使うためには、fnWeekday 関数(Public 関数)を Excel のセルに記述して利用してください。
少なくとも、2023年~2025年は問題なさそうです。
(2023.6.25 2025年の「敬老の日」が祝日にならない問題を修正)
(2024.3.2 Date 関数の戻り値が日付型と判定できない問題を修正)

最終的に挙動を確認した Excel バージョンは、次の通りです。
Microsoft® Excel® for Microsoft 365 MSO (バージョン 2401 ビルド 16.0.17231.20236) 64 ビット

仕様

モジュール

モジュール内の関数を Excel のセルで利用します。
主に利用する関数は fnWeekday です。

セルには =fnWeekday(シリアル値) を指定することで戻り値を得ることができます。

fnWeekday 実行サンプル
fnWeekday 実行サンプル

また、=fnWeekday(シリアル値, 1) のように第2引数に 1 を指定すると、平日と休日、祝日の名称のいずれかを得ることができます。
これが 2 の場合は「祝日の趣旨」(画像における D 列)を得ます。

fnWeekday オプションを指定時の実行サンプル
fnWeekday オプションを指定時の実行サンプル

出力利用例
セル内の記述例出力例備考
=fnWeekday(DATE(2024,5,5))8祝日を示す 8 を表示する
=fnWeekday(DATE(2024,5,5),1)こどもの日平日/休日/(祝日の名称)の、いずれかを表示する
=fnWeekday(DATE(2024,5,5),2)こどもの人格を重んじ、こどもの幸福をはかるとともに、母に感謝する。祝日の趣旨を表示する
fnWeekday 以外の関数は、内部で細かい計算をするために使われます。
(もちろん、セル内で利用することも可能です)

戻り値

戻り値は、第2引数の指定で変化します。
上述したように、デフォルトで weekday 関数とほぼ同じ*1ですが、追加で 8=祝日としています。

以下、第2引数を明記した場合の挙動を記載します。
0の場合:数値(デフォルト)
第2引数に 0 を指定した(もしくは指定しない)場合に出力される番号です。
デフォルト
番号内部変数意味備考
1vbSunday日曜日
2vbMonday月曜日
3vbTuesday火曜日
4vbWednesday水曜日
5vbThursday木曜日
6vbFriday金曜日
7vbSaturday土曜日
8-祝日
1 の場合:名称
第2引数に 1 を指定した場合に出力される文字列です。
名称を返す
文字列意味備考
休日土日どちらか
平日土日祝以外の平日(実際は月~金曜日)
(各祝日名)祝日
祝日の名称は、国民の祝日に関する法律に準拠しています。
2 の場合:趣旨
第2引数に 2 を指定した場合に出力される文字列です。
趣旨を返す
趣旨意味備考
(Nothing)平日/休日であり、祝日ではない日
(各祝日の趣旨)法律などで定義される趣旨
(Nothing) については、表示しないように(Null 表示に)するかもしれません。

*1 : weekday 関数のデフォルトの戻り値は 1=日, 2=月, 3=火, 4=水, 5=木, 6=金, 7=土になっています。

関数

作成したモジュールは、つぎの五つの関数から成り立っています。

fnWeekday(Serial, [Switch])

このモジュールの本丸で、公式の weekday 関数のように使います。
戻り値として曜日(vbMonday から vbSaturday)だけでなく、追加で Holiday を意味する 8 も返します。

オプションには、シリアル値が必要です。
戻り値の内容を変えるために、Switch 番号も指定可能です。

第2引数を指定した際に、セルに表示される内容は、次の通りです。
Switch意味備考
0曜日と祝日を意味する 1~8 の数字を返すSwitch を省略した場合のデフォルト
1平日/休日/祝日の名称を返す
2祝日の趣旨を返す

fnDate(Year, Month, Day)

Excel 関数 date コマンドを模したものです。
オプションには、年・月・日の、三つが必要です。

Excel VBA の場合、DateValue コマンドを使えばいいのですが、年月日を文字列で指定しなければならないため、コードがかなり読みにくくなっていました。
可読性を目的に関数化しています。

fnHappyMonday(Year, Month, Weeks)

ハッピーマンデー制度でシリアル値を取得するのに必要な、x年x月の第x月曜日、という指定でシリアル値を取得するための関数です。
オプションには、年・月・第x週の、三つが必要です。

考え方としては、月の1日が何曜日なのかを見て、そこから月曜日が何日なのかを割り出します。
あとは、7日に第x週のx-1 を掛けたものを足してあげれば、シリアル値を取得できます。

fnVernalEquinox(Year)

春分の日を割り出し、シリアル値を取得するための関数です。
オプションには、年の指定が必要です。

1行しかない、かなり短いコードですが関数化しています。
計算で出力した日付ではない場合、ここで出力情報を調整する予定です。

fnAutumnalEquinox(Year)

秋分の日を割り出し、シリアル値を取得するための関数です。
オプションには、年の指定が必要です。

1行しかない、かなり短いコードですが関数化しています。
計算で出力した日付ではない場合、ここで出力情報を調整する予定です。

ソースコード

Option Explicit

Public Function fnWeekday(Serial As Date, Optional Switch As Byte = 0)
' #########################################################################
' #
' # 呼び出されると、引数の Serial から曜日/祝日情報を返すマクロ
' # デフォルトの戻り値は、以下の通り
' #
' # 戻り値の定義
' #  0 = 平日(月曜~金曜)
' #  1 = 日曜日(vbSunday)
' #  2 = 曜日月(vbMonday)
' #  3 = 火曜日(vbTuesday)
' #  4 = 水曜日(vbWednesday)
' #  5 = 木曜日(vbThursday)
' #  6 = 金曜日(vbFriday)
' #  7 = 土曜日(vbSaturday)
' #  8 = 祝日
' #
' #########################################################################

' ### 変数定義 #########################

Dim DEFpDayName     As String
Dim DEFpDayMeaning  As String
Dim pDayName        As String
Dim pDayMeaning     As String
Dim pRV             As Byte
Dim pYYYY           As Integer
Dim fSubstitute     As Boolean

' ### 変数設定 #########################

DEFpDayName = "平日"
DEFpDayMeaning = "(Nothing)"

pDayName = DEFpDayName
pDayMeaning = DEFpDayMeaning

pYYYY = Year(Serial)

' ### メイン処理 #######################

' serial に指定された年月日と、該当する年の祝日に相当するシリアル値を比較する。
' 該当の祝日であれば、第2引数通りに変数を設定する。
' もし該当の祝日名があれば、戻り値 8 を指定する。

Select Case Serial
    ' 日付が固定されているもの
    Case fnDate(pYYYY, 1, 1)
        pDayName = "元旦"
        pDayMeaning = "年のはじめを祝う。"
    Case fnDate(pYYYY, 1, 15)
        If pYYYY <= 1999 Then
            pDayName = "成人の日"
            pDayMeaning = "おとなになったことを自覚し、みずから生き抜こうとする青年を祝い、励ます。"
        End If
    Case fnDate(pYYYY, 2, 11)
        pDayName = "建国記念の日"
        pDayMeaning = "建国をしのび、国を愛する心を養う。"
    Case fnDate(pYYYY, 2, 23)
        If 2019 < pYYYY Then
            pDayName = "天皇誕生日"
            pDayMeaning = "天皇の誕生日を祝う。"
        End If
    Case fnDate(pYYYY, 4, 29)
        If 2007 <= pYYYY Then
            pDayName = "昭和の日"
            pDayMeaning = "激動の日々を経て、復興を遂げた昭和の時代を顧み、国の将来に思いをいたす。"
        ElseIf 1989 <= pYYYY Then
            pDayName = "みどりの日"
            pDayMeaning = "自然の恩恵に感謝する"
        ElseIf 1948 <= pYYYY Then
            pDayName = "天皇誕生日"
            pDayMeaning = "天皇の誕生を祝う(昭和天皇)"
        ElseIf 1927 <= pYYYY Then
            pDayName = "天長節"
            pDayMeaning = "天地が永久であるように天皇の治世も続くように"
        End If
    Case fnDate(pYYYY, 5, 3)
        pDayName = "憲法記念日"
        pDayMeaning = "日本国憲法の施行を記念し、国の成長を期する。"
    Case fnDate(pYYYY, 5, 4)
        If 2007 <= pYYYY Then
            pDayName = "みどりの日"
            pDayMeaning = "自然に親しむとともにその恩恵に感謝し、豊かな心をはぐくむ。"
        End If
    Case fnDate(pYYYY, 5, 5)
        pDayName = "こどもの日"
        pDayMeaning = "こどもの人格を重んじ、こどもの幸福をはかるとともに、母に感謝する。"
    Case fnDate(pYYYY, 7, 20)
        If pYYYY <= 2002 Then
            pDayName = "海の日"
            pDayMeaning = "海の恩恵に感謝するとともに、海洋国日本の繁栄を願う。"
        End If
    Case fnDate(pYYYY, 8, 11)
        ' 2014年制定、2016年より施工
        If 2016 <= pYYYY Then
            pDayName = "山の日"
            pDayMeaning = "山に親しむ機会を得て、山の恩恵に感謝する。"
        End If
    Case fnDate(pYYYY, 9, 15)
        If pYYYY <= 2002 Then
            pDayName = "敬老の日"
            pDayMeaning = "多年にわたり社会につくしてきた老人を敬愛し、長寿を祝う。"
        End If
    Case fnDate(pYYYY, 11, 3)
        pDayName = "文化の日"
        pDayMeaning = "自由と平和を愛し、文化をすすめる。"
    Case fnDate(pYYYY, 11, 23)
        pDayName = "勤労感謝の日"
        pDayMeaning = "勤労をたっとび、生産を祝い、国民たがいに感謝しあう。"
    Case fnDate(pYYYY, 12, 23)
        If pYYYY < 2019 Then
            ' 以降、上皇陛下
            pDayName = "天皇誕生日"
            pDayMeaning = "天皇の誕生日を祝う。"
        End If
End Select

Select Case Serial
    ' ハッピーマンデー
    Case fnHappyMonday(pYYYY, 1, 2)
        ' 2000 年より適用
        If 2000 <= pYYYY Then
            pDayName = "成人の日"
            pDayMeaning = "おとなになったことを自覚し、みずから生き抜こうとする青年を祝いはげます。"
        End If
    Case fnHappyMonday(pYYYY, 7, 3)
        If 2003 <= pYYYY Then
            ' 2003 年より適用
            pDayName = "海の日"
            pDayMeaning = "海の恩恵に感謝するとともに、海洋国日本の繁栄を願う。"
        End If
    Case fnHappyMonday(pYYYY, 9, 3)
        If 2003 <= pYYYY Then
            pDayName = "敬老の日"
            pDayMeaning = "多年にわたり社会につくしてきた老人を敬愛し、長寿を祝う。"
        End If
    Case fnHappyMonday(pYYYY, 10, 2)
        ' 2000 年より適用。2020 年より名称変更
        If 2020 <= pYYYY Then
            pDayName = "スポーツの日"
            pDayMeaning = "スポーツを楽しみ、他者を尊重する精神を培うとともに、健康で活力ある社会の実現を願う。"
        ElseIf 2000 <= pYYYY Then
            pDayName = "体育の日"
            pDayMeaning = "スポーツにしたしみ、健康な心身をつちかう日"
        End If

    ' 春分/秋分の日
    Case fnVernalEquinox(pYYYY)
        pDayName = "春分の日"
        pDayMeaning = "自然をたたえ、生物をいつくしむ。"
    Case fnAutumnalEquinox(pYYYY)
        pDayName = "秋分の日"
        pDayMeaning = "祖先をうやまい、なくなった人々をしのぶ。"
End Select

' 天皇の即位の日及び即位礼正殿の儀の行われる日を休日とする法律
Select Case Serial
    Case fnDate(2019, 5, 1)
        pDayName = "天皇の即位の日"
    Case fnDate(2019, 5, 2)
        pDayName = "国民の休日"
    Case fnDate(2019, 10, 22)
        pDayName = "即位礼正殿の儀の行われる日"
End Select

' 振替休日
Select Case Serial
    Case fnDate(pYYYY, 1, 1) + 1
        If Weekday(Serial) = vbMonday Then fSubstitute = True
    Case fnDate(pYYYY, 2, 11) + 1
        If Weekday(Serial) = vbMonday Then fSubstitute = True
    Case fnDate(pYYYY, 2, 23) + 1
        If 2019 < pYYYY Then
            If Weekday(Serial) = vbMonday Then fSubstitute = True
        End If
    Case fnDate(pYYYY, 4, 29) + 1
        If Weekday(Serial) = vbMonday Then fSubstitute = True
    Case fnDate(pYYYY, 5, 5) + 1
        ' 5月5日が日曜~火曜日だったら、5/6 が振替休日
        If vbSunday <= Weekday(fnDate(pYYYY, 5, 5)) And Weekday(fnDate(pYYYY, 5, 5)) <= vbTuesday Then
            fSubstitute = True
        End If
    Case fnDate(pYYYY, 8, 11) + 1
        If Weekday(Serial) = vbMonday Then fSubstitute = True
    Case fnDate(pYYYY, 11, 3) + 1
        If Weekday(Serial) = vbMonday Then fSubstitute = True
    Case fnDate(pYYYY, 11, 23) + 1
        If Weekday(Serial) = vbMonday Then fSubstitute = True
    Case fnDate(pYYYY, 12, 23) + 1
        If pYYYY < 2019 Then
            ' 以降、上皇陛下
            If Weekday(Serial) = vbMonday Then fSubstitute = True
        End If
        
    ' ハッピーマンデー
    Case fnHappyMonday(pYYYY, 1, 2) + 1
        If Weekday(Serial) = vbMonday Then fSubstitute = True
    Case fnHappyMonday(pYYYY, 7, 3) + 1
        If Weekday(Serial) = vbMonday Then fSubstitute = True
    Case fnHappyMonday(pYYYY, 9, 3) + 1
        ' シルバーウィーク対応
        ' もし、敬老の日の2日後が秋分の日なら、国民の休日にする。
        If fnHappyMonday(pYYYY, 9, 3) + 2 = fnAutumnalEquinox(pYYYY) Then
            pDayName = "国民の休日"
        ElseIf Weekday(Serial) = vbMonday Then
            fSubstitute = True
        End If
        
    Case fnHappyMonday(pYYYY, 10, 2) + 1
        If Weekday(Serial) = vbMonday Then fSubstitute = True

    ' 春分/秋分の日
    Case fnVernalEquinox(pYYYY) + 1
        If Weekday(Serial) = vbMonday Then fSubstitute = True
    Case fnAutumnalEquinox(pYYYY) + 1
        If Weekday(Serial) = vbMonday Then fSubstitute = True
    'Case DateValue("2020/9/22")
    '    DayName = "秋分の日"

End Select

If fSubstitute = True Then pDayName = "振替休日"

' -----------------------------------------------------------
' 令和 2 年(2020年)及び令和 3 年(2021年)に限り、
' 東京オリンピック・パラリンピック競技大会の開催にあわせ、
' 「海の日」、「スポーツの日」及び「山の日」が移動している。
' -----------------------------------------------------------

' 令和2年 (2020) & 令和3年 (2021)
Select Case Serial
    ' 海の日
    Case fnHappyMonday(2020, 7, 3), fnHappyMonday(2021, 7, 3)
        pDayName = DEFpDayName
        pDayMeaning = DEFpDayMeaning
    Case fnDate(2020, 7, 23)
        pDayName = "海の日"
        pDayMeaning = "海の恩恵に感謝するとともに、海洋国日本の繁栄を願う。"
    Case fnDate(2021, 7, 22)
        pDayName = "海の日"
        pDayMeaning = "海の恩恵に感謝するとともに、海洋国日本の繁栄を願う。"

    ' スポーツの日
    Case fnHappyMonday(2020, 10, 2), fnHappyMonday(2021, 10, 2)
        pDayName = DEFpDayName
        pDayMeaning = DEFpDayMeaning
    Case fnDate(2020, 7, 24)
        pDayName = "スポーツの日"
        pDayMeaning = "スポーツを楽しみ、他者を尊重する精神を培うとともに、健康で活力ある社会の実現を願う。"
    Case fnDate(2021, 7, 23)
        pDayName = "スポーツの日"
        pDayMeaning = "スポーツを楽しみ、他者を尊重する精神を培うとともに、健康で活力ある社会の実現を願う。"

    ' 山の日
    Case fnDate(2020, 8, 11), fnDate(2021, 8, 11)
        pDayName = DEFpDayName
        pDayMeaning = DEFpDayMeaning
    Case fnDate(2020, 8, 10)
        pDayName = "山の日"
        pDayMeaning = "山に親しむ機会を得て、山の恩恵に感謝する。"
    Case fnDate(2021, 8, 8)
        pDayName = "山の日"
        pDayMeaning = "山に親しむ機会を得て、山の恩恵に感謝する。"
End Select

' 祝日値判定
If pDayName = DEFpDayName Then
    ' 平日/休日であれば、戻り値を 1~7 で指定する。
    ' ## 曜日選択 #####
    If IsDate(Serial) Then
        Select Case Weekday(Serial)
            Case vbSunday
                pRV = vbSunday
                pDayName = "休日"
            Case vbMonday
                pRV = vbMonday
            Case vbTuesday
                pRV = vbTuesday
            Case vbWednesday
                pRV = vbWednesday
            Case vbThursday
                pRV = vbThursday
            Case vbFriday
                pRV = vbFriday
            Case vbSaturday
                pRV = vbSaturday
                pDayName = "休日"
        End Select
    Else
        ' IsDate の判定内容にエラーがある場合
        fnWeekday = "祝日値判定エラー"
        Exit Function
    End If
Else
    ' 平日でなければ、戻り値を 8 で指定する。
    pRV = 8
End If

' ### 終了処理 #########################

' オプションの内容で、戻り値を変更する。
Select Case Switch
    Case 0
        fnWeekday = pRV
    Case 1
        fnWeekday = pDayName
    Case 2
        fnWeekday = pDayMeaning
End Select

' ######################################

End Function

Public Function fnDate(Year, Month, Day)
' #########################################################################
' #
' # VBA の date 関数は、Excel sheet の date 関数と異なり、文字列を指定する。
' # この関数は、セルで利用する date 関数と同じ使い勝手を実現するもの。
' #
' #########################################################################

fnDate = DateValue(Year & "/" & Month & "/" & Day)

End Function

Public Function fnHappyMonday(Year, Month, Weeks)
' #########################################################################
' #
' # ハッピーマンデー用のシリアル値を返す。
' # 指定された、Year 年 Month 月の第 Weeks 週の月曜日(シリアル値)を返す。
' #
' # 参考資料
' # http://www.relief.jp/itnote/archives/003241.php
' #########################################################################

Dim pMondayDate     As Byte
Dim pFirstMonDay    As Date

' ## 第1週目の月曜日を求める。

' 先に指定月の1日が何曜日なのかを見て、次の月曜日が何日なのかを指定する。
Select Case Weekday(fnDate(Year, Month, 1))
    Case vbSunday       ' 1
        ' x月1日が日曜日なら、月曜日は翌日の 2 日
        pMondayDate = 2
    Case vbMonday       ' 2
        ' x月1日が月曜日なので、そのまま 1 日
        pMondayDate = 1
    Case vbTuesday      ' 3
        ' x月1日が火曜日なので、月曜日は 6 日後の 7 日
        pMondayDate = 7
    Case vbWednesday    ' 4
        ' x月1日が水曜日なので、月曜日は 5 日後の 6 日
        pMondayDate = 6
    Case vbThursday     ' 5
        pMondayDate = 5
    Case vbFriday       ' 6
        pMondayDate = 4
    Case vbSaturday     ' 7
        pMondayDate = 3
End Select

' 第1週目の月曜日から何週間後なのか、必要な日数を足してシリアル値を返す。
fnHappyMonday = fnDate(Year, Month, pMondayDate) + (7 * (Weeks - 1))

End Function

Public Function fnVernalEquinox(Year)
' #########################################################################
' #
' # 呼び出されると、引数の Year から算出した 春分の日 情報を返すマクロ
' #
' # 参考 URL http://www.wanichan.com/pc/excel/2010/5/page07.html
' #########################################################################
fnVernalEquinox = fnDate(Year, 3, Int(20.8431 + 0.242194 * (Year - 1980) - Int((Year - 1980) / 4)))

End Function

Public Function fnAutumnalEquinox(Year)
' #########################################################################
' #
' # 呼び出されると、引数の Year から算出した 秋分の日 情報を返すマクロ
' #
' # 参考 URL http://www.wanichan.com/pc/excel/2010/5/page07.html
' #########################################################################
fnAutumnalEquinox = fnDate(Year, 9, Int(23.2488 + 0.242194 * (Year - 1980) - Int((Year - 1980) / 4)))

End Function

その他

zip ファイル

コピペより、インポート可能なファイルが良いという方向け。
現在バージョン
過去バージョン

更新履歴

  • 2023.3.5 細かい表現と、マクロの微修正を行った。
  • 2023.6.25 敬老の日に関するご指摘をいただき、ハッピーマンデーの扱いを修正*2 した。
  • 2024.3.2 オプションに Date を指定した場合 0 が返ってくる現象についてご指摘をいただき、IsDate 関数で判断する値を CVDate 関数で日付型へ事前に変換*3するようにした。
  • 2024.3.2 IsDate 関数で判断する Serial について、fnWeekday 関数にオプションとして入力する時点で Date 型であることを強制した。

*2 : シリアル値で祝日を判断するフローで、固定されていた敬老の日(2002年以前)を分岐させたあとにハッピーマンデーの分岐が来ており、ハッピーマンデー対象である敬老の日が分岐済みの扱いになってチェックされない流れになっていた。

*3 : VBA の IsDate 関数が、Date 関数で取得した値そのままだと、数値を日付と判断できない。

参考サイト様

Windows 11

はてブ数 2024/04/11 13:36 OS別::Windows

Windows 11



Windows 11 を使うにあたり、自身が使いやすいように行う初期セットアップ内容を記載したものです。
主に自身の備忘用であるため、内容については不足分があります。

アプリ

インストールアプリ(私物 PC)

プロプライエタリソフトウェア
プロプライエタリソフトウェア
アプリケーション種別備考
Adobe Photoshop Elements 2022写真編集オンラインコード版
Adobe Premiere Elements 2022動画編集オンラインコード版
Evernoteメモアプリ乗り換え検討中
Microsoft Office 365 Soloオフィスソフトサブスクリプション
Notron Internet Securityアンチウィルスサブスクリプション
シェアウェア
シェアウェア
アプリケーション種別備考
EmEditorテキストエディタ永久ライセンス
Becky! Ver2メールクライアント
Explzhアーカイバ元シェアウェア(登録済み)
フリーウェア
フリーウェア
アプリケーション種別備考
Tera Term Proターミナルソフト
Google Chromeブラウザ
LogiOptionsデバイスドライバLogicool デバイス用
Wiresharkトラフィックアナライザ
PIXUS MP560 MP Driverプリンタドライバ
各種ドライバBIOS/NIC/グラボ等
ISC BINDDNS ユーティリティdig コマンドを利用

アプリ設定

EmEditor

ライセンス登録
別途保管している、レジストリファイルからインポート。
設定の定義
シェルスクリプト(拡張子 .sh のファイル)に対する設定。

サクラエディタ

設定の定義
サクラエディタのマクロ - ダブルクリックした単語を自動検索 : arigayas の 雑記帳
マクロ
次の2行を記載したマクロを highlight.mac というファイルで保存。
S_SelectWord(0);
S_SearchClearMark(0);
保存先は、C:¥Program Files (x86)¥sakura¥macro¥ のようなデフォルトで。

設定→共通設定→「マクロ」タブで該当マクロを指定し、設定ボタンで設定。

次に、設定→共通設定→「キーの割り当て」で、種別「外部マクロ」から、ダブルクリックをマクロに割付。

以後、ダブルクリックすると、選択された内容が検索され、すべて色が変わる。

その他

更新履歴

日付内容
2022.10.29初版
2024.4.11更新履歴を追加
表現を微修正

Excel VBA

はてブ数 2021/05/22 21:45 OS別::Windowsその他::技術情報

Excel VBA


Excel のバージョン情報

このページを作成する際に使った、Microsoft Excel 情報です。

バージョン 2104 (ビルド 13929.20372)
Excel バージョン情報
Excel バージョン情報

Microsoft 365 のサブスクリプションを契約しており、基本的には最新版*1を利用しています。
メールアドレスなど、アカウント系の情報は消しています。

Excel VBA とは

現在発売されている Microsoft Excel は、標準でマクロ機能が存在します。

いくつか Tera Term と連携するネタがあるので、それを記載したいと思います。
その前に、VBA を利用できる環境にするための設定から。

VBA の有効化

Excel オプションを開く
Excel VBA は、オプションからリボンを有効化することで簡単に利用することができるようになります。

まず、メニューバーから「ファイル」を選択します。

Excel 起動
Excel 起動

左ペインから「オプション」を選択します。

オプション選択
オプション選択
マクロを利用する設定
Excel のオプションが表示されるので、左ペインから「トラスト センター」を選択します。
ここで、右ペインに「トラスト センターの設定」が表示されていることが確認できます。

トラスト センターの設定
トラスト センターの設定

メッセージバー
トラスト センターでは、メッセージ バーが表示されると思います。

「ActiveX コントロールやマクロなどのアクティブ コンテンツがブロックされた場合、すべてのアプリケーションにメッセージ バーを表示する」にチェックが入っていることを確認します。

メッセージ バーの表示
xxxx

何かの拍子にブロックされても分かりませんので、入っていなければいれておきましょう。
マクロの設定
左ペインから「マクロの設定」を選択します。

ここでは、右ペインに出てくるマクロの設定から「すべてのマクロを有効にする(推奨しません。危険なコードが実行される可能性があります)」のチェックボックスを有効にします。

自分がいつ、どのように作った VBA マクロなのかは分かると思いますので、有効にしても問題ないという理屈です。

思い当たらないファイルは、基本的に開かなければ問題になりません。

マクロの設定
マクロの設定

「警告を表示してすべてのマクロを無効にする」を選択しても良いでしょう。
VBA マクロが入っている Excel ファイルを開いたときに、画面上部に薄い黄色で「セキュリティの警告 マクロが無効にされました。[コンテンツの有効化]」がでます。

この場合、そのファイルは「コンテンツの有効化」を押して実行を許可しなければ動きません。
逆に言うとマクロを動かすために許可すればよいので、確認するという観点では推奨できるものと思います。


このページの趣旨からは外れるため解説はしませんが、安全にマクロを利用する場合はデジタル署名を行うことが可能です。
デジタル署名を行うと、誰が VBA マクロを含むファイルを作成したかがシステム的に分かるため、安全になります。


「OK」を選択して、Excel のオプション画面に戻ります。

マクロを開発する設定
Excel のオプションが表示されたら、左ペインから「リボンのユーザー設定」を選択します。
ここで、右ペインに「□開発」が表示されていることが確認できます。

開発 有効化ボタン
開発 有効化ボタン

「開発」にチェックをつけて「OK」を押します。

開発 有効化状態
開発 有効化状態

Excel の通常画面に戻ります。
この時、メニューバーに「開発」が表示されていれば、設定できています。

メニューバーの開発
メニューバーの開発

VBA 標準モジュールの追加

開発メニューを選択すると、リボンが表示されます。
VBA でコードを書きたいときは、ここで「Visual Basic」を選択します。

開発リボンの内容
開発リボンの内容

「VBAProject(Book 1)」でも「Microsoft Excel Object」でも構わないのですが、右クリックして「挿入」→「標準モジュール」と進みます。

標準モジュールの追加
標準モジュールの追加

Excel VBA として、標準モジュールが追加されました。

追加した標準モジュールの内容
追加した標準モジュールの内容
VBA マクロのある Excel ファイルの保存
標準モジュールを追懐したファイルは、拡張子「.xlsm」で保存します。
VBA マクロが有効なファイルはサイバー攻撃に利用されることが多いので、注意する必要があるためです。

VBA 有効ファイルの保存
VBA 有効ファイルの保存

VBA が動作する Excel ファイルは、作成日付といったプロパティや、誰が作ったものなのかといった信頼できる情報をもとに開くようにしましょう。

*1 : 更新タイミングによっては、少し古いバージョンだったりもします。

Text Editor

はてブ数 2021/05/06 10:13 Macro::macro 作成OS別::Windows

テキストエディタ

マクロを作成する際に欠かせないテキストエディタを紹介します。

メモ帳 (notepad)

提供形態:Windows 標準アプリ
Windows 10 May Update 2019 から UTF-8 に対応した、Windows 標準のテキストエディタです。

非常にシンプルで、今はともかく昔は Ctrl + S でさえ使えなかった、Windows に標準インストールされていなかったら誰が使うのか分からないと思ったくらいのテキストエディタでした。

今でも、Undo/Redo ができない(Ctrl + Z で1回限り)、行番号やルーラー表示がない、禁則処理がないなど、テキストエディタとしては最低限にも程がある。

でも、偏執的な愛用者がいるのも事実。

EmEditor

提供形態:シェアウェア(フリーウェア版あり)
https://jp.emeditor.com/

クセの少ない、非常に使いやすいテキストエディタです。

私は永久ライセンスを購入しているので常に最新版の EmEditor を使っていますが、CSV 等も直感的に扱えるようになっており、手放せません。
ただ、メジャーリリースごとにライセンス料金が必要なので、オススメはしかねます。
使いやすい環境には課金も辞さないなら Free 版が復活したようなので、そちらで体験してもよいかと。

そうそう、矩形選択にも早い時期に対応していました。
この矩形選択とマクロを目当てにライセンス購入したものです。
UNIX や Linux といった CUI では、縦に並んだ文字列を切り出して使うことが非常に多いのですよね。

私がマクロを使うといった小技を覚えたのも、このアプリでした。
(この機能がなければ Tera Term でもマクロは覚えなかったでしょうね)

サクラエディタ

提供形態:フリーウェア
https://sakura-editor.github.io/

クセは強いけれど、高機能で無料なテキストエディタです。

シェアウェアを嫌う企業のパソコンには、大概インストールされているようです。
矩形選択も、当然のように行えます。

画面を分割して表示したいときに F12 を使うとか、置換したいときは Ctrl + R を使うとかいったクセの強さがなければと思うと、非常に残念です。

F12 は「名前を付けて保存」が多いかな。MS-Office はそうなっていますし。
置換したいなら Ctrl + H ですよね。

リストの重複行を削除する機能の実装は、EmEditor より速かった記憶があります。
Ctrl + A (全選択)→ Alt + A (ソート)→ Alt + M (マージ)のコンボは、今でも勝手に指が動きます。

秀丸エディタ

提供形態:シェアウェア(Microsoft Store版あり)
https://hide.maruo.co.jp/

優秀なテキストエディタです。

テキストエディタに課金しようと思った当時、矩形選択が使えていたら使っていたかもしれません。
課金したことないにもかかわらず、なぜか SE はライセンスキーを知っている人が多かった印象があります。

そういえば、いまの価格はいくらなんだろう?

TeraPad

提供形態:フリーウェア
https://tera-net.com/

Ctrl + S が使えてプログラミング言語にも対応している、シンプルなテキストエディタです。
サクラエディタが普及する前は、よく見かけるテキストエディタでした。

寺尾 進さんが作成されているので TeraPad とのこと*1


Ctrl + S が使えるのは、不安定な OS で長文を扱う必要のある SE にとって必須機能で、それさえも使えなかったメモ帳がいかに機能不足だったことか。

Visual Studio Code

提供形態:フリーウェア
https://azure.microsoft.com/ja-jp/products/visual-studio-code/

一般に VSCode と呼ばれる、高機能エディタです。
Linux や Mac でも利用できます。

*1 : Tera Term は寺西 高さん

マクロ生成

なにもマクロファイルを作れるのはテキストエディタだけではありません。

Microsoft Excel

提供形態:パッケージでの売り切り/サブスクリプション方式
主目的は表計算ソフトですが、方眼紙的な扱いから派生してマクロを組む際に重宝します。
あるコマンドで Excel でリストされているものを利用したいとかは、よくあるシーンです。

コマンドの加工がメインで、出来上がったものはテキストエディタにコピペします。
道具は使い勝手の良いものを、適切に選択しましょう。

Microsoft Excel for VBA

提供形態:Microsoft Excelに同梱
コマンドの加工に飽き足らず、マクロそのものを作りたいとなると VBA を利用する意義が生まれます。

Excel でも txt 形式で保存すればマクロファイルを作ることができますが、そこから拡張子を変更したりする必要があります。
ADO 等を利用すれば、マクロを作れます。

exec を利用すれば、Excel に記載した IP アドレスから直接 Tera Term を起動することさえ可能です。

Tera Term Pro

Tera Term 自身でも、マクロを駆使することでマクロを生成することができます。

MS-Office のない環境で大量にマクロを組まなければならないなら、有効かもしれません。
あとは、マクロ自体の勉強目的くらいしか用途が思い浮かびません。