タイダログ

もっと怠けますか? (y/n)

まくろ☆マギカ [後編] 完成の物語

私と VBA の出会いの話。関数では私を救えない。

この話の続きです。

taidalog.hatenablog.com

VBA に救いを求める

「どうやら VBA? とかいう技術があるらしい。なんでも関数では不可能な操作も実現できるそうな」

一応 VBA の存在は知っていましたが、食わず嫌いをしていたのと、職場にあったマクロの処理速度がやたら遅かったので使ってみる気になりませんでした。

そうは言っても他に手はなし、ネットで調べつつマクロを組んでみることに。まずは自分がしたいことをあらためて洗い出して、それからその機能を実現するために必要な操作を考えます。

したいこと

  • 出勤時間入力ボタンを押すと、押した時刻をその日の出勤時間セルに入れる
    例)10月1日の朝8:30に押すと、1日のセルに「8:30」と入れる
  • 退勤時間入力ボタンを押すと、押した時刻をその日の退勤時間セルに入れる
    例)10月5日の夜21:00に押すと、5日のセルに「21:00」と入れる
  • 勤怠管理シートを複製して保管しておく
    再提出を求められた時のため
  • 勤怠管理シートから入力した時刻を全てクリアする
    翌月も使うため

必要な操作

  • 現在時刻から時間の部分を取得する
  • 現在時刻から分の部分を取得する
  • 数値を5刻みにする
  • その日の出勤時刻のセルを取得する
  • その日の退勤時刻のセルを取得する
  • セルに時刻を入力する
  • シートを複製する
  • 特定のセルの内容を消去する

あとはそれぞれの操作を VBA 上でどうやって行うか調べて、順番に書いていけば完成です。たしか3日かかって完成させた気がします。

……なんて簡単に言っていますが、実際にはプログラミング自体初めてだったので、「変数」やら「メソッド」やら「プロパティ」やら、よくわからない概念に囲まれて苦労しましたし、そもそも VBA の編集画面(VBE)の開き方すらわからなかったので我ながらよくやったなぁという感じです。

コード

実際のコードがこちらです。今見るとツッコミどころ満載ですね。

  • 変数名に A とかダメだろ
  • Range("A1").PasteSpecial xlPasteAll とか何がしたいんだ
  • でも Range("A1").Select からの Selection.Copy がないのは素晴らしい
Sub 出勤時刻()
    Dim H As Integer
    H = Hour(Time)
    Dim M As Integer
    M = Minute(Time)
    Dim SM As Integer
    SM = Int(M / 5) * 5
    Dim ST As String
    ST = H & ":" & SM
    
    Range("D3").Offset(Day(Date), 0).Value = ST
    
    Range("A1").Select
End Sub

Sub 退勤時刻()
    Dim H As Integer
    H = Hour(Time)
    Dim M As Integer
    M = Minute(Time)
    Dim LM As Integer
    LM = (Int(M / 5) + 1) * 5
    Dim LT As String
    LT = H & ":" & LM

    Range("F3").Offset(Day(Date), 0).Value = LT
    
    Range("A1").Select
End Sub

Sub 行列調整()
    Const ROW_LAST = 35
    Const COL_LAST = 12
    Dim r As Long
    Dim c As Long
    
    For r = 1 To ROW_LAST
        Rows(r).RowHeight = Worksheets(1).Rows(r).RowHeight
    Next r
    
    For c = 1 To COL_LAST
        Columns(c).ColumnWidth = Worksheets(1).Columns(c).ColumnWidth
    Next c
    
End Sub

Sub あたらしい月がきた()
    Dim A As Integer
    A = Worksheets(1).Range("F2").Value
    Dim B As String
    B = A & "月"
    Dim c As Integer
    c = Worksheets(1).Range("D2").Value
    
    Worksheets.Add after:=Worksheets(1) '------------新しいシートを作成
    ActiveSheet.Name = B
        
    Worksheets(1).Range("A1:L34").Copy '------------新しいシートにコピー
    Range("A1").PasteSpecial xlPasteAll
    Worksheets(1).Range("B4:C34").Copy
    Range("B4").PasteSpecial xlPasteValues
    Application.CutCopyMode = False
    行列調整
    Range("A1").Select
    
    Worksheets(1).Select '------------[入力]シートのデータ初期化
    Range("D4:D33").Value = "0:00"
    Range("F4:F33").Value = "0:00"
    Range("J4:L33").ClearContents
    
    If A + 1 <= 12 Then '------------[入力]シートの月変更
        Range("F2").Value = A + 1
    Else
        Range("F2").Value = A - 11
        Range("D2").Value = c + 1
    End If
    
    Range("A1").Select
End Sub

Sub 保存更新()
    Dim RTN As String
    RTN = MsgBox( _
        "入力内容を別のシートに保存して" & vbLf & _
        "出勤時刻と退勤時刻を初期化します" & vbLf & _
        "実行しますか?" & vbLf & _
        vbLf & _
        "※実行後でも、保存したデータは編集できます", _
        vbYesNo + vbQuestion + vbDefaultButton1, "確認")
    Select Case RTN
        Case vbYes
            あたらしい月がきた
        Case vbNo
            End
        End Select
End Sub

ほんと良くやったわ。

悲劇に見舞われる

「これはいいものが出来上がったぞ。これからどんどん使っていこう」
そう思った矢先、私は教頭からの発表に絶望することとなりました。
「来年度から勤怠管理はポータルサイト内の入力フォームで行うことにします」

完成したのが10月で、翌3月で終了だから6ヶ月の命か。儚いな。
ほんまなんやねん。

一連の流れを終えて

作ったファイルはすぐに使わなくなりましたが、まあよいでしょう。今回の大きな収穫は面倒な作業を何とかして効率化した経験と、そのための VBA という手段です。

効率化や自動化を考えることで私の仕事がちょっと楽になり、他の先生たちも楽になって周りにちょっとだけ優しくできるようになり、私は感謝され、より一層怠惰を極める大義名分を得る。素晴らしいことではありませんか。もっと楽をしていこう。

怠惰な私の怠惰な旅路は、ここから始まったのです。

あと、だいぶ後になってから ctrl + : でセルに現在時刻を入力できることを知りました。ショートカットキー、そういうのもあるのか。