こんにちは、ECF Tech
担当 Michiharu.Tです。
Excel VBA 実践レポートと題しまして、実用的なツールを作成するための試行錯誤の状況やプログラムの解説をお伝えしたいと思います。いくつかの記事に分けてお伝えするボリュームになると思いますが、VBAツールの作成練習用の題材としても使用できると思いますので、ご活用頂けたら幸いです。
その他のExcel VBA関連の教材および練習問題は下記よりご覧いただけます。

本記事の対象読者
- Excelの基本的な操作知識をお持ちの方
- Excel VBAの基本的な知識をお持ちの方
- Excel VBAで何らかのツール(便利なしくみ)を構築したいと考えている方
仕様の検討
作成するのは、勤怠管理・給与計算ツールです。下は簡単な処理フローになります。

- 従業員は勤怠入力用ファイルに、月ごとの勤怠状況を入力する。
- 従業員は勤怠入力用ファイルを、経理担当に提出する。
- 経理担当は給与計算ファイルを使用し、給与明細書を作成する。
図に示すように、作成するExcelファイルは2つです。まずは勤怠管理の入力用ワークシートを検討します。
勤怠管理シートのレイアウト
勤怠管理のレイアウトは次のように検討しました。

次のような点を考慮しています。
- 入力セルを広めにとり、見やすさを重視。
- L4セルから始まる空欄は、表示項目が増えた場合の予備として準備。
- A4に収まるレイアウトで作成。ボタンはA4サイズの外。
本記事で実装する仕様
本記事では、次のしくみを実装します。
- 西暦年(A2セル)と月(D2セル)を入力し、日付設定ボタンを押すと日付と曜日(B9~B39セル)が自動入力される。
- 勤怠列(C9~C39セル)は、ドロップダウンリストによる選択入力とする。
- 開始列(F9~F39セル)、終了列(I9~I39セル)、休憩(O9~O39セル)は「HH:MM」形式で入力できる方式とする。
HHは0~23、MMには0~59が入力できる。 - 時間外列(O9~O39)、勤務時間列(R9~R39)は自動入力されるようにする。
実践レポート
ここから、実際の作成手順を紹介しながら、感じたことを合わせて書いていきたいと思います。基本となるExcelファイルは、こちらからダウンロードできます。
管理情報シートの作成
Excelでツールを作成する際、定数や入力リストを設定しておく管理用シートを作成すると便利です。本記事の段階では、次のように値を設定した「管理情報」シートを準備しています。

シートは定数を設定しておくエリアと入力リストを設定しておくエリアに分けています。定数や入力リストが必要になる都度、空いているセルに追加していくようにします。これらの値の具体的な使用方法は、実際に使用する箇所で説明しています。
日付と曜日の設定
日付と曜日の設定が、下図の手順で実行されるようにします。

②のボタンが押されたらマクロを実行し、処理を実現する動作とします。マクロの内容を下に示します。
Function getLastDay(year, month)
Dim lastYmd As Date '末日(年月日)
Dim lastDay As Integer '末日(数値)
'指定年月の末日を年月日情報として取得
lastYmd = DateSerial(year, month + 1, 0)
'日のみを取得
lastDay = Format(lastYmd, "d")
'指定年月の末日日付を返す
getLastDay = lastDay
End Function
Sub SetDays()
Dim year As Integer '年
Dim month As Integer '月
Dim day As Integer '日
Dim lastDay As Integer '末日
year = Cells(2, 1).Value '西暦取得
month = Cells(2, 4).Value '月取得
'日のみを取得
lastDay = getLastDay(year, month)
'日数分のくり返し
Dim i
For i = 1 To 31 Step 1
If i <= lastDay Then '実在日付チェック
'処理対象年月日
Dim targetYmd
targetYmd = DateSerial(year, month, i)
'日付の設定
Cells(8 + i, 1).Value = i
'曜日の設定
Cells(8 + i, 2).Value = Format(targetYmd, "aaa")
'曜日によって文字色を設定
Select Case Weekday(targetYmd)
Case 1 '日曜
Cells(8 + i, 2).Font.Color = RGB(&HFF, &H33, &H0)
Case 7 '土曜
Cells(8 + i, 2).Font.Color = RGB(&H0, &H66, &HFF)
Case Else '平日
Cells(8 + i, 2).Font.Color = vbBlack
End Select
Else
'存在しない日付なら空を設定
Cells(8 + i, 1).Value = Empty
Cells(8 + i, 2).Value = Empty
End If
Next
End Sub
プログラムのポイントをいくつか解説します。
DateSerial(year, month + 1, 0)は、指定された年と月から末日を返しています。DateSerial関数は、3つの引数にそれぞれ年、月、日を指定することで日付型の値を返します。月にmonth + 1を指定することで指定月の翌月となります。その上で日に0を指定することで、翌月1日の前日、つまり指定月の末日を表すことができます。yearが2026、monthが5なら、2026年6月1日の前日を表しているため、2026年5月31日を返すことができます。その上でFormat(lastYmd, "d")の処理で「日」のみを取得し、戻り値として返しています。
lastDay = getLastDay(year, month)は、作成したgetLastDay関数を呼び出す処理です。引数に年(A2セル)と月(D2セル)の値を指定し、戻り値として返される日付を変数lastDayに代入しています。
Forループでは31日分の処理を行います。どの月も必ず31日まであるわけではないので、If i <= lastDay Thenで実在する日付かをチェックした上で処理を分岐しています。
Format(targetYmd, "aaa")は、日時情報を特定の書式で出力します。targetYmdは処理対象の年月日です。書式は"aaa"とすることで、曜日を漢字1文字で返してくれます。
Select Case Weekday(targetYmd) ~ End Selectでは、設定した曜日に応じてフォントの色を変更しています。Weekday(targetYmd)は、引数で指定した年月日を元に、曜日を数値で返してくれます。返される数値は日曜日を1とし、順に7(土曜日)までの値で返されます。返された値に応じて、Case 1などで処理を分岐し、それぞれに適した色を設定しています。
色の設定はRGB関数を使っています。RGB関数は、3つの引数に赤(Red)、緑(Green)、青(Blue)の色の度合いを数値(0~255)で指定します。色を表す数値は16進数で表示しています。これは、Webページの作成などで色を指定する際によく用いられる形式です。16進数で数値を指定する場合は数値の先頭に(&H)をつける必要があります。
#FF3300のように記載されています。赤、緑、青の情報は下の図のようになっていますので、それぞれをRGB関数の3つの引数に設定します。

筆者は、こちらの色見本サイトをよく利用しています。
Forループ内のElseは、日付が実在しない場合の処理です。日付と曜日に空を示すEmptyを代入しています。シートの見た目は空セルになります。
ボタンの設置
マクロが作成できたら、ボタンを設置します。メニューから開発タブ > 挿入 > ボタン の順に操作し、ボタンを選びます。

ドラッグ&ドロップでボタンの場所と大きさを設定し、「マクロの登録」ダイアログが表示されたら、作成したマクロを選択し、OKをクリックします。

設置したボタンを右クリックし、「テキストの編集」をクリックすれば、ボタンのタイトルを変更できます。

ボタンが設置できたら西暦年と月を入力し、ボタンクリックで動作を確認してみましょう。日の列に日付と曜日が入れば成功です。

勤怠列のドロップダウンリスト化
勤怠列を下図のように、選択式に変更します。選択する画面部品をドロップダウンリストと呼びます。

それでは作成手順です。メニューから、データ > データの入力規則 を選びます(下図)。

「入力値の種類」から「リスト」を選択し、「元の値」のテキストボックス右の↑をクリックします。

「データの入力規則」ダイアログが下のようになったら「管理情報」シートをクリックし、G3セル~G9セルをドラッグで選択。最後にダイアログ右上の×をクリックします。

OKをクリックします。

C9セルをクリックし、ドロップダウンリストから選べるようになっていれば設定ができています。
最後に、C9セルの内容をC10~C39にコピーします。
時刻書式の設定
開始、終了、休憩、時間外、勤務時間の列には、それぞれ時刻形式の書式を設定します。これにより入力がしやすくなり、また、計算に必要な式の入力も簡単になります。

F9セルを選択した状態で、メニューから、ホーム > 数値エリアのドロップダウンリストをクリックし、「その他の表示形式」をクリックします。

「セルの書式設定」ダイアログが表示されますので、表示形式タブから、分類で「ユーザー定義」を選択、種類で「 [h]:mm 」を選択し、OKをクリックします。

C9セルに1を入力してみましょう。「24:00」と表示されたら時刻形式の設定ができています。確認できたら24:00の値を削除し、F9セルの内容をF10~F39セル、I9~R39セルにコピーします。
勤務時間と時間外労働時間を自動計算
勤務時間は、R9セルに=I9-F9-L9の式を設定して求めます。終了時刻から、開始時刻と休憩時間を引き算する式です。これで勤務時間の計算ができます。できたら、R9セルの内容をR10~R39セルにコピーします。
時間外労働時間は、O9セルに=R9-管理情報!B$2の式を設定して求めます。管理情報シートのB2セルには、法定労働時間として8:00が入っています(下図)。R列で求めた勤務時間から8時間を引くことで残業時間を単純計算しています。

できたら、O9セルの内容をO10~O39セルにコピーします。
この時点で時間外の列は下のような表記になると思います。

「########」の表示は利用者に不安を与えてしまうので対応したいところですが、これについては次回のテーマとさせて頂きたいと思います。
まとめと次回の課題
今回は勤怠管理シートの作成にあたり、次の機能を実装しました。
- 日付・曜日の自動入力(マクロ)
- 勤怠列のドロップダウンリスト化(入力規則を利用)
- 勤務時間と時間外労働時間列の自動計算(Excel関数を利用)
基本的な動作は実現できましたが、一方で次のような問題を残しています。
- 開始、終了、休憩列に不正な値が入力できてしまう。
- 開始、終了、休憩列の入力値によっては、勤務時間列も「########」のような表示になる。
など、問題を残している部分もあります。次回は、これら不正な値の対処やエラー発生時の対応を中心に実装を進めたいと思います。
最後までお読みいただき、ありがとうございました。引きつづきご活用頂けますと幸いです。

