クラスモジュールで、勤務年数と勤労10年以上の対象者になるのか判定する処理を作ってみた。

クラスモジュールをとにかく使ってみよう!

クラスモジュールの利点がよくわかりません。Twitterの猛者からアドバイスをもらってみたものの、まだお粗末なコードしか書けませんでしたが投稿します。正直、Excel関数でできることです。クラスで記述するとこうなるのかぁ~と思っていただければ幸いです。


1 閲覧対象者

クラスモジュールの初心者。クラスモジュールに興味のある方。

2 得られる効果

オブジェクト指向の考え方が分かる!?(作っていて自信がないので…)

3 設計

f:id:bimori466:20200911052704p:plain

上の表の入社日から、勤務年数を求める。勤務年数が10年以上であれば表彰対象者とする。


処理後のSheet↓↓
f:id:bimori466:20200911053032p:plain

エクセル関数ではなく、クラスモジュールを作成して、標準モジュールで実行して上の表の結果を得ます。

4 クラスモジュールを書こう!

では、まずクラスモジュールを記述しましょう。とりあえず以下に全コードを先に張り付けます。

クラスモジュール

Private Const STANDARD_VALUE As Date = #4/1/2007#

Public id As String
Public surName As String
Public name As String
Public gender As String
Public joiningDate  As Date
Public YearsOfService As Integer
Public joiningDateCommend As String

Public Property Get GetYearsOfService() As Variant

GetYearsOfService = DateDiff("y", STANDARD_VALUE, joiningDate)

GetYearsOfService = WorksheetFunction.RoundDown(GetYearsOfService / 365, 0)

End Property

Public Property Get GetjoiningDateCommend(ByVal YearsOfService As Integer)

If YearsOfService >= 10 Then
    GetjoiningDateCommend = "対象者"
    
Else
    GetjoiningDateCommend = "非対象者"
    
End If
    
End Property


ポイントとしては、DATEDIFF関数で使う開始日付をこのクラスの中で定数をとして宣言しています。
(Private Const STANDARD_VALUE As Date = #4/1/2007#)
この基準日に対して、入社日から勤務年数を求め、10年以上であれば表彰対象者とします。

5 標準モジュールを書いて処理する

そんなに長くないので、まず全コードを貼り付けます。

標準モジュール

Sub GetMyYearOfService_Commend()

Dim myYearOfService As YearsOfService: Set myYearOfService = New YearsOfService

i = 2

Do Until i = 5
    myYearOfService.joiningDate = Range("E" & i)
    Range("f" & i) = myYearOfService.GetYearsOfService
    Range("g" & i) = myYearOfService.GetjoiningDateCommend(myYearOfService.GetYearsOfService)
        
    i = i + 1
Loop

End Sub


2~4行目だけを処理することを目的としたLoop処理です、そこはあまり気にせずで。

本題の中身です。

クラスモジュールのインスタンス

まずは、クラスモジュールのインスタンス化をします。
(Dim myYearOfService As YearsOfService: Set myYearOfService = New YearsOfService)。
これで、 myYearOfServiceがYearsOfServiceクラスのインスタンスとして作成されました。

勤続年数を求める

勤続年数を求める処理は、(Range("f" & i) = myYearOfService.GetYearsOfService)です。
クラスモジュールの中に、「GetYearsOfService」というプロパティプロシージャを作成しました。
その処理が、(myYearOfService.GetYearsOfService)で実行されます。中身としてはDATEDIFFで基準日と入社日の差を求めて、÷365してRoounddownしてます。その結果が列Fに返ります。

10年以上勤務の表彰対象か判定する

表彰対象か判定する処理は、(Range("g" & i) = myYearOfService.GetjoiningDateCommend(myYearOfService.GetYearsOfService))です。
クラスモジュールの中に、「GetjoiningDateCommend」という処理を作成しました。
その処理が、myYearOfService.GetjoiningDateCommend(myYearOfService.GetYearsOfService)で実行されます。
今回は引数として、(myYearOfService.GetYearsOfService)を使用。つまり、「勤務年数」を引数としています。
処理の内容としては、引数の勤務年数が10年以上であれば列Gに「対象者」と返し、それ以外は「非対象者」と返します。

6 作ってみての感想

まだ、これではエクセル関数のDATEDIFとIFを使えばいいよね!で終わってしまう話です。
同じ引数をもち複数の処理をする場合、または追加でこのプロパティが欲しい、となったら自作でクラスモジュールを作るとのアドバイスTwitterでもらいました。
初期段階は、お粗末なモジュールになってしましましたが、深堀してクラスモジュールの便利さを感じ、お伝えできればと思います。