【Excel VBA 再利用コード集】シフト表ヘッダ部に祝日を反映する処理(配列利用)

アフィリエイト広告を利用しています。

シフト表(担務表)シートのヘッダ部に対して、祝日シートの内容をもとに祝日情報を反映する VBA コードです。

祝日シートから日付と祝日名を配列として取得し、担務表ヘッダの日付と照合して一致した場合に祝日名を書き込みます。

シート同士を直接参照せず配列で処理し、更新後に一括で書き戻すことで、セル操作を最小限に抑え、処理全体を高速化しています。

コピー利用や、AI による再生成・参考用途を想定しています。


Information

配列
複数の値を、順序を保ったまままとめて扱うためのデータ構造です。Excel では、セルを 1 件ずつ操作するよりも高速に処理できるため、処理の高速化を目的としてよく使われます。

シフト表ヘッダ部に祝日を反映する処理(配列利用)

シート構成

ThisWorkbook内に、以下のシートが構成されています。

【担務表(シフト表)】

【祝日】

祝日シートから祝日情報を取得し、担務表シートの3行目(祝日行)に祝日を追加していきます。

なお、祝日シートは、内閣府が公開している祝日一覧の CSV を使用しています。(出典: 国民の祝日について - 内閣府

コード

依存関係ツリー

各プロシージャーの依存関係は以下のようになっています。

Dom_CreateCalendar
└─ AddShukujisuToTanmuWs(担務表ヘッダに祝日情報を反映して書き戻す)
  ├─ GetShukujitsuTbl(祝日シートを配列で取得)
  │ └─ Util_GetArray
  │   ├─ GetUsedRangeArray(使用範囲を配列で取得)
  │   └─ DebugPrintArraySize(配列サイズをデバッグ出力)
  │
  └─ AddShukujitsuToTanmuHeaderTbl(担務表ヘッダ配列へ祝日名を反映)

各プロシージャのコード

次に、各プロシージャーのコードを示します。

【モジュール: Dom_CreateTanmuWs】

Option Explicit


Public Sub AddShukujisuToTanmuWs()

    ' Description
    '   担務表ヘッダ配列に祝日情報を反映し、シートへ書き戻す。
    '
    ' Arguments
    '   (none)
    '
    ' Returns
    '   (none)


    ' 担務表シート取得
    Dim tanmu_ws As Worksheet
    Set tanmu_ws = ThisWorkbook.Worksheets("担務表")

    ' 担務表ヘッダー配列取得
    Dim tanmu_header_tbl As Variant
    tanmu_header_tbl = tanmu_ws.Range("A1:AL4").Value
    
    ' 祝日配列取得
    Dim shukujitsu_tbl As Variant
    shukujitsu_tbl = GetShukujitsuTbl()

    ' ガード(空配列など)
    If IsEmpty(tanmu_header_tbl) Or (Not IsArray(tanmu_header_tbl)) Then
        MsgBox "tanmu_header_tbl が取得できません。", vbExclamation
        Exit Sub
    End If

    If IsEmpty(shukujitsu_tbl) Or (Not IsArray(shukujitsu_tbl)) Then
        MsgBox "shukujitsu_tbl が取得できません。", vbExclamation
        Exit Sub
    End If

    ' 祝日反映(配列更新)
    Call AddShukujitsuToTanmuHeaderTbl(tanmu_header_tbl, shukujitsu_tbl)

    ' シートへ書き戻し
    tanmu_ws.Range( _
        tanmu_ws.Cells(1, 1), _
        tanmu_ws.Cells( _
            UBound(tanmu_header_tbl, 1), _
            UBound(tanmu_header_tbl, 2) _
        ) _
    ).Value2 = tanmu_header_tbl

End Sub

Private Function GetShukujitsuTbl() As Variant

    ' Description
    '   「祝日」シートの「A1:B最終行」までを、配列として取得する

    ' 祝日シートを取得
    Dim ws As Worksheet            ' 祝日シート
    Set ws = ThisWorkbook.Worksheets("祝日")

    ' 対象ワークシートの使用範囲を配列で取得(Util_GetArray 呼び出し)
    Dim shukujitsu_tbl As Variant     ' 祝日を格納する配列
    shukujitsu_tbl = GetUsedRangeArray(ws)
    Call DebugPrintArraySize(shukujitsu_tbl, "祝日シート配列")

    ' Return: 配列を返却
    GetShukujitsuTbl = shukujitsu_tbl

End Function

Private Sub AddShukujitsuToTanmuHeaderTbl( _
    ByRef tanmu_header_tbl As Variant, _
    ByVal shukujitsu_tbl As Variant _
)

    ' Description
    '   祝日配列(shukujitsu_tbl)に一致する日付が担務表ヘッダ配列(tanmu_header_tbl)の
    '   カレンダー範囲に存在した場合、該当列の祝日行セルを更新する。
    '
    ' Arguments
    '   tanmu_header_tbl : 担務表ヘッダを格納した2次元配列(更新対象)
    '   shukujitsu_tbl   : 祝日シートを格納した2次元配列(参照のみ)
    '
    ' Returns
    '   (none)
    
    
    ' ガード(空配列など)
    If IsEmpty(tanmu_header_tbl) Or (Not IsArray(tanmu_header_tbl)) Then
        MsgBox "tanmu_header_tbl が Empty / 配列ではありません。", vbExclamation
        Exit Sub
    End If

    If IsEmpty(shukujitsu_tbl) Or (Not IsArray(shukujitsu_tbl)) Then
        MsgBox "shukujitsu_tbl が Empty / 配列ではありません。", vbExclamation
        Exit Sub
    End If


    ' 固定仕様(担務表ヘッダ)
    Const DATE_ROW As Long = 1                ' 日付行(担務表ヘッダ内)
    Const SHUKUJITSU_ROW As Long = 3          ' 祝日書き込み行
    Const CALENDAR_START_COL As Long = 2      ' B
    Const CALENDAR_END_COL As Long = 32       ' AF

    ' 祝日配列の最終行を取得
    Dim shukujitsu_last_row As Long
    shukujitsu_last_row = UBound(shukujitsu_tbl, 1)

    ' 祝日配列を走査(2行目~最終行:1行目はヘッダ)
    Dim row As Long
    For row = 2 To shukujitsu_last_row
    
        ' 祝日日付を取得(空行・日付以外はスキップ)
        If Not IsDate(shukujitsu_tbl(row, 1)) Then GoTo ContinueShukujitsuRow
        Dim shukujitsu_date As Date
        shukujitsu_date = shukujitsu_tbl(row, 1)
    
        ' 祝日名を取得(空行はスキップ)
        Dim shukujitsu_name As String
        shukujitsu_name = CStr(shukujitsu_tbl(row, 2))
        If Len(shukujitsu_name) = 0 Then GoTo ContinueShukujitsuRow
    
        ' 担務表ヘッダの日付行を走査
        Dim col As Long
        For col = CALENDAR_START_COL To CALENDAR_END_COL
    
            ' 日付が一致した列に祝日名をセット
            If tanmu_header_tbl(DATE_ROW, col) = shukujitsu_date Then
                tanmu_header_tbl(SHUKUJITSU_ROW, col) = _
                    Left(shukujitsu_name, 2)
                Exit For
            End If
    
        Next col
    
ContinueShukujitsuRow:
    Next row

End Sub

【モジュール: Util_GetArray】

Option Explicit


' 配列操作関連プロシージャ
'------------------------------------------------------------------------------

Sub DebugPrintArraySize(ByVal arr As Variant, ByVal label As String)

    ' Description
    ' 配列の行要素数・列要素数をイミディエイトウィンドウに出力する
    '
    ' Arguments
    ' arr   : 行列構造を持つ配列
    ' label : デバッグ出力用の識別子(シート名など)


    ' 配列が Empty の場合処理を中断する
    If IsEmpty(arr) Then
        Debug.Print label & " : 配列が Empty です"
        Exit Sub
    End If

    ' 配列の行要素数・列要素数を出力
    Debug.Print label & _
                " 行要素数=" & (UBound(arr, 1) - LBound(arr, 1) + 1) & _
                " 列要素数=" & (UBound(arr, 2) - LBound(arr, 2) + 1)

End Sub


Function GetUsedRangeArray(ByVal ws As Worksheet) As Variant
    
    ' Description
    '   指定されたワークシートの使用範囲を判定し、
    '   Cells(1,1) から最終行・最終列までを配列として返す
    '
    ' Arguments
    '   ws  : 対象となるワークシート
    '
    ' Returns
    '   Variant
    '     ・使用範囲が存在する場合:
    '         Cells(1,1) ~ 最終行・最終列 を格納した 2 次元配列
    '     ・シートにデータが存在しない場合:
    '         Empty
    

    ' シートにデータが存在しない場合は Empty を返す
    If ws.Cells.Find("*") Is Nothing Then
        GetUsedRangeArray = Empty
        MsgBox "シートにデータが存在しません。", vbExclamation
        Exit Function
    End If


    ' 最終行・最終列の取得
    Dim last_row As Long
    Dim last_col As Long

    With ws
        last_row = .Cells.Find( _
                        "*", _
                        SearchOrder:=xlByRows, _
                        SearchDirection:=xlPrevious _
                    ).row

        last_col = .Cells.Find( _
                        "*", _
                        SearchOrder:=xlByColumns, _
                        SearchDirection:=xlPrevious _
                    ).Column
    End With


    ' Return:使用範囲を配列として返す
    GetUsedRangeArray = _
        ws.Range( _
            ws.Cells(1, 1), _
            ws.Cells(last_row, last_col) _
        ).Value

End Function

使いかた

シフト表作成VBAアプリケーションに組み込んで使用する想定です。

コード実行結果

AddShukujisuToTanmuWs を実行すると、以下のような結果が返ります。3行目に祝日が追加されていることが、確認できます。

【実行前】

【実行後】

Information

ちょっとしたコツ
祝日名を正式名称のままセルに入力すると、文字がはみ出してしまうため、左から 2 文字か 3 文字 を取り出して入力するとよいでしょう。

運営者・ポテ

以上で解説は終わりです。

VBAスキルアップの参考情報

近年は、ChatGPTをはじめとするAIの登場によって、学習のスタイルが大きく変わりました。

分からないことがあれば、AIに尋ねれば答えがすぐに見つかる時代です。

とはいえ、AIを使いこなすには、自分自身の基本的な知識や理解力が欠かせません。

全体像をつかむためには、やはり書籍などで体系的に学んでおくことが今でも有効です。

そのうえでAIを活用すれば、自分の理解度に合わせた的確な解説や、応用のヒントを得ることができます。

「学んで基礎を築く → AIで補い発展させる」──このサイクルを重ねることで、VBAスキルは着実に高まっていくでしょう。

VBAのスキルアップ

VBAを学び始めるなら

入門書は、どれを選んでも大きな差はないように感じます。

どれを選ぶかに悩むことに時間をかけるよりも、まずは手頃な一冊を手に取って進めてみるのがおすすめです。

もし迷ったときには、私はインプレス社の「いちばんやさしい」シリーズを選ぶことが多いです。

基礎を超えて力をつけたいなら

私は上級者を目指していましたので、入門書にとどまらず、このような内容の濃い一冊を選んで学んでいました。

今は誰でもAIを活用できる時代になりましたが、上級者を目指す方にとっては、AIをより上手に活用するという意味でも、こうした本は今なお価値があります。

このレベルの本を一冊持っておくことに、損はないでしょう。


資格で能力を証明したいなら

VBAのプログラミング能力を客観的に示したい場合には「VBAエキスパート試験」があります。

特に「スタンダード」の方は上級者向けです。

あなたが社内業務の改善を行う立場であっても、VBAで作成したシステムをお客様に納める立場であっても、この資格は信頼や安心につながるでしょう。

以下の公式テキストが販売されています。



プログラミングの一般教養

「独学プログラマー」というプログラミングの魅力を解説した書籍があります。

これはVBAではなくPythonを題材としていますが、プログラミングの基本的な知識や思考法、仕事の進め方まで幅広く学べます。

今はAIにコードを尋ねれば、答えが返ってくる時代です。

しかし、この本からは「コード」以上に、プログラミングに向き合う姿勢や考え方を学ぶことができるでしょう。


こちらの記事でも紹介しています。もしよろしければご覧ください。

【初心者歓迎】無料相談受付中 

運営者・ポテ

いつもありがとうございます!

限られた時間をより良く使い、日本の生産性を高めたい──

みんなの実用学を運営するソフトデザイン工房では、業務整理や業務改善アプリケーション作成のご相談を承っております。

お気軽にご相談ください。


こちらの記事でも紹介しております。

おわりに

運営者・ポテ

ご覧いただきありがとうございました!

この記事では、「シフト表ヘッダ部に祝日を反映する処理(配列利用)」を解説しました。

お問い合わせやご要望がございましたら、「お問い合わせ/ご要望」フォームまたはコメント欄よりお知らせください。

この記事が皆様のお役に立てれば幸いです。

なお、当サイトでは様々な情報を発信しております。よろしければトップページもあわせてご覧ください。

この記事を書いた人

運営者・ポテソフトデザイン工房|日々の業務にちょうどいい自動化を
■人生を追求する凡人 ■日本一安全で、気の向くままに自分の時間を過ごせる、こだわりのキャンプ場を作るのが夢 ■ソフトデザイン工房運営(個人事業者) - 業務改善アプリケーションをご提供 ■人生は時間そのもの。ひとりでも多くの人が「より良い人生にするために時間を使って欲しい」と願い、仕事のスキルの向上、余暇の充実、資産形成を追求。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です