出勤簿から給与計算マクロを作ろう3

Excel VBA

今回は以前の頁で作った「従業員ごとに勤務時間の小計を出す」プログラムを、変数配列を使って見直してみたいと思います。

よろしければ以前の頁のプログラムも合わせてご覧になってください。

出勤簿から給与計算マクロを作ろう

  1. 出勤時刻と退勤時刻から勤務時間を取得する
  2. アルバイト従業員ごとに勤務時間の小計を出す
  3. 勤務時間に時給を掛けて給料を算出する

以前のページで2番の、アルバイト従業員ごとの勤務時間の小計を出す、のプログラムを作成しましたが、今回は「変数の配列」を使い、もう一度2番のプログラムを作成したいと思います。今回のプログラムは、以前のページで5列目の勤務時間が計算されている前提でのプログラムとしています。

アルバイト従業員ごとに勤務時間の小計を出す

処理を想定してみる

今回は「変数の配列」に従業員名を格納し、従業員名がいくつでも対応できるプログラムを作ります。

それでは必要な処理を挙げてみましょう

  • 従業員名格納用の配列を作る
  • 1行目のみ最初に格納する
    • →他の従業員名との比較用
  • 2行目以降の従業員名を配列内から探す
    • →一致する名前があれば次の行へ移行する
    • →配列内に従業員名がなければ配列を増やし格納する。
    • →同時に従業員数をカウントする
  • (アルバイト従業員ごとに集計していく)
  • (集計した勤務時間をセルにセットする)

少々複雑そうですが、ひとつずつ機能を作っていきましょう。

()内の部分は以前の頁と同じですので、この頁ではプロシージャ完成時のみ触れたいと思います。

従業員名や数が不特定の場合

今回は従業員名が不特定であっても稼働できるプログラムを作成します。 今回のプログラムでは、モジュール冒頭部で「Option Base」ステートメントを使い、インデックスが1から始まるようにしています。 カウントの数とインデックスの数値が一致するため、プログラムのイメージが掴みやすくなります。

それではまず変数の配列から宣言しましょう。

Dim Jugyoin() As String    '動的配列として宣言

この配列に、「Redim Preserve」で配列を動的に増やしながら従業員名を格納していきます。

次に、比較のためにデータの1行目を、配列の先頭に格納します。 従業員数のカウントを増やすコードも忘れずに入れましょう。

Dim j As Integer            'ループカウンタ(行数用)
Dim JugyoinCnt As Integer   '従業員数

j = 2           'ヘッダ部を省いて2行目から
ReDim Jugyoin(1)
JugyoinCnt = 1
Jugyoin(JugyoinCnt) = Cells(2, 1).Value   '2行目のみ先に格納

続いて、2行目以降の従業員名を配列内から探すループを作りましょう。 一致する名前が配列内に見つかった場合は次の行に移動するためループ終了とし、そして配列の末尾まで見つからない場合は配列を足し、足した配列に従業員名を格納します。

Dim i As Integer            'ループカウンタ2つ目(インデックス用)

For i = 1 To JugyoinCnt    '従業員名が
If Cells(j, 1).Value = Jugyoin(i) Then  '名前が配列内にあればループ抜ける
        Exit For
ElseIf i = JugyoinCnt Then    '配列の末尾であれば配列を1つ増やす
        JugyoinCnt = JugyoinCnt + 1   '従業員数を増やす
        ReDim Preserve Jugyoin(JugyoinCnt)   '配列を追加する
        Jugyoin(JugyoinCnt) = Cells(j, 1).Value  '配列に最終行の名前を格納
End If
Next

最後に行を移していくループです。

Do Until Cells(j, 3).Value = "" Or Cells(j, 4).Value = ""   '時刻の入力がない行で終了
    j = j + 1     ‘次の行へ
Loop

以上の部品を組み合わせ、シートに表示する部分を合わせるとこうなります。

Option Base 1    ‘モジュール冒頭部に記述するコード

Sub DoutekiHairetsu()
    Dim JugyoinCnt As Integer   '従業員数カウント
    Dim i As Integer            'ループカウンタ
    Dim j As Integer            'ループカウンタ2つ目
    Dim Jugyoin() As String    '動的配列として宣言
    Dim Kinmujikan As Integer   '勤務時間計算用
    
    j = 2           'ヘッダ部を省いて2行目から
    ReDim Jugyoin(1)
    JugyoinCnt = 1  '従業員数カウント用変数を加算
    Jugyoin(JugyoinCnt) = Cells(2, 1).Value '2行目のみ強制的に格納
    
    Do Until Cells(j, 3).Value = "" Or Cells(j, 4).Value = ""
        For i = 1 To JugyoinCnt
            
            If Cells(j, 1).Value = Jugyoin(i) Then  '名前が配列内にあればループ抜ける
                Exit For
            ElseIf i = JugyoinCnt Then    '配列の末尾であれば配列を1つ増やす
                JugyoinCnt = JugyoinCnt + 1
                ReDim Preserve Jugyoin(JugyoinCnt)
                Jugyoin(JugyoinCnt) = Cells(j, 1).Value  '増やした配列に名前を格納
            End If
        Next
        j = j + 1
    Loop
   
    For i = 1 To JugyoinCnt          '従業員数だけループする
        Kinmujikan = 0      '集計用の変数をリセット
        j = 2               '一行目はヘッダのため2行目から計算する
        Do Until Cells(j, 3).Value = "" Or Cells(j, 4).Value = ""
            If Cells(j, 1).Value = Jugyoin(i) Then '対象の名前と一致したら加算していく
                Kinmujikan = Cells(j, 5).Value + Kinmujikan
            End If
            j = j + 1
        Loop
        Cells(i + 1, 6).Value = Jugyoin(i) '6列目に従業員名をセット
        Cells(i + 1, 7).Value = Kinmujikan '7列名に勤務時間の小計をセット
    Next
End Sub

長いコードになっていますが、大きく分けて、従業員名を配列に入れる部分と、集計してシートに表示する部分に分かれています。

それでは勤務記録に新規の行を追加し、結果を見てみましょう。

この1行を追加しています。 それでは実行後のシートを見てみましょう。

この1行が追加されました。 これで新しく従業員を増やしても、何人まででも対応できることになります。

今回のまとめ

今回は動的配列を使い、以前よりも柔軟な対応ができるプログラムを作成しました。

次回は「勤務時間に時給を掛けて給料を算出する」のプログラム作成をご説明します。

コメント

タイトルとURLをコピーしました