アラサーからのプログラマー生活

アラサーの新米PGが必死に頑張る成長記録です。あとは旅行とか。

【ExcelVBA】考え方ひとつでコードが削れた話

こんにちは、堀井です。

最近は現場が変わってAWS関係のお仕事をぼちぼちしていますが中々訳わからなくて面白くなってきました。

先輩や上司に嘆いたところAWS公式チュートリアルやUdemyの利用をお勧めされたので今後はこれで勉強しようと思います。

と言いたいところですが、それ以前にLinux、Docker、Maven、Gradle、Gitその他諸々が大前提の知識として必要と言うことなので笑うしかない。

でも今日はVBAです。


まずはこちらをご覧下さい。

終業まであと何時間かな?と思ったときにコピペで使えるVBAを作りました。

残り時間 = 3 : 08 と言った表示がされるだけのものです。

Constの値として8:30始業、17:00終業、11:45~12:30が休憩時間としていますが、自由に書き換えてください。

Option Explicit

Public Sub 残り時間計算()
    Const START_HOUR As Long = 8
    Const START_MIN  As Long = 30
    Const END_HOUR   As Long = 17
    Const END_MIN    As Long = 0
    Dim nowHour As Long: nowHour = hour(Now())
    Dim nowMin  As Long: nowMin = Minute(Now())
    Dim remHour As Long: remHour = END_HOUR - nowHour
    Dim remMin  As Long: remMin = END_MIN - nowMin

    If isEndLunch(nowHour, nowMin) = False Then remMin = remMin - 45
    Do While remMin < 0
        remHour = remHour - 1
        remMin = remMin + 60
    Loop
    Debug.Print "残り時間 = " & remHour & " : " & AddZero(CStr(remMin))
End Sub

'休憩後ならTrue
'(休憩中にマクロ走らせない前提のコード)
Private Function isEndLunch(ByVal hour As Long, ByVal min As Long) As Boolean
'    Const LUNCH_START_HOUR As Long = 11
'    Const LUNCH_START_MIN  As Long = 45
    Const LUNCH_END_HOUR   As Long = 12
    Const LUNCH_END_MIN    As Long = 30
    
    isEndLunch = False
    If hour > LUNCH_END_HOUR Or _
      (hour = LUNCH_END_HOUR And min >= LUNCH_END_MIN) Then
       isEndLunch = True
    End If
End Function

'一桁の場合0を手前に付与する
' 例:"1" -> "01"、"15" -> "15"
Private Function AddZero(ByVal str As String) As String
    AddZero = str
    If Len(str) <> 2 Then AddZero = "0" & str
End Function

はい、全部で41行でした。

休憩前なら残り時間に休憩時間(45分)を足し算して表示するだけの単純なものです。

時・分を別々に分けて計算しているので若干面倒でしたが、ではこうするとどうでしょうか。

Option Explicit

'終業時刻までの残り時間を表示します
Public Sub 残り時間計算()
    Const START_MIN As Long = (8 * 60) + 30         ' 8:30、始業時間
    Const LUNCH_END_MIN As Long = (12 * 60) + 30    '12:30、休憩終了
    Const END_MIN As Long = (17 * 60) + 0           '17:00、終業時間
    
    Dim nowMin As Long: nowMin = (hour(Now()) * 60) + Minute(Now())
    Dim remMin As Long: remMin = END_MIN - nowMin
    If nowMin < LUNCH_END_MIN Then remMin = remMin - 45
    Debug.Print "残り時間 = " & MinToTime(remMin)
End Sub

' 分→時間表記に変更する(例:325→"5 : 25")
Private Function MinToTime(ByVal tm As Long) As String
    Dim hour As Long: hour = WorksheetFunction.RoundDown(tm / 60, 0)
    Dim min  As Long: min = tm Mod 60
    MinToTime = hour & " : " & AddZero(CStr(min))
End Function

'一桁の場合0を手前に付与する
' 例:"1" -> "01"、"15" -> "15"
Private Function AddZero(ByVal str As String) As String
    AddZero = str
    If Len(str) <> 2 Then AddZero = "0" & str
End Function

全部で27行でしたので3割ほど削減できました。

最初から分として計算しておけばここまで簡単に書けるのかという気持ちになって面白かったです。

勉強して暫く経ったら初期のコードを見返して「なんだこの下手なコードは・・・」とビビるの、とてもお勧めです。

それではまた次回。