VBA 簡単な学習時間管理ツール

### 学習時間管理ツールについて
なんとなくすぐできそうだったので試しに作ってみました。
スマホのアプリなどは続かなかったので自作したものならカスタマイズできるし愛着でるかなと思ったので。

### 動作イメージ

![Animation5.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1744893/a8ad162b-1b12-4b89-6bd0-dda32ee033b1.gif)

### 動作の流れ
1. 勉強する内容をドロップダウンリストで選択
1. 勉強開始するときに打刻開始を押す
1. 終わるときに打刻終了を押す
1. マスタシートのテーブルに情報がされる
1. ピボットテーブルを更新
1. ダッシュボードのグラフに反映
### コード

```vb
Option Explicit

Sub StartTime()

'テーブルの項目数を取得
Dim N As Long

With Sheets("マスタ").Range("A1").ListObject
    '最終項目を取得
    N = .ListColumns(1).Range.Count
    
    'テーブルはデフォルトで１項目分確保されているので事前に項目があるのかないのかチェック
    If .ListColumns(1).Range(N).Value = "" Then
        .ListColumns(1).Range(N).Value = Date
        .ListColumns(2).Range(N).Value = Sheets("打刻").Range("B3").Value
        .ListColumns(3).Range(N).Value = Format(Time, "hh:mm")
    Else
        '最終項目の値を空白チェック（前の打刻が完了しているかいないかをチェック）
        If .ListColumns(4).Range(N).Value <> "" Then
            '完了していたら最終項目＋１に新しく項目を作成
            .ListColumns(1).Range(N + 1).Value = Date
            .ListColumns(2).Range(N + 1).Value = Sheets("打刻").Range("B3").Value
            .ListColumns(3).Range(N + 1).Value = Format(Time, "hh:mm")
        End If
    End If
End With

Range("C12") = "打刻中"

End Sub

Sub EndTime()

'テーブルの項目数を取得
Dim N As Long

With Sheets("マスタ").Range("A1").ListObject
    '最終項目を取得
    N = .ListColumns(1).Range.Count
    '最終項目の値を空白チェック（前の打刻が完了しているかいないかをチェック）
    If .ListColumns(4).Range(N).Value = "" Then
        '空白だったら現在の時間を入れる
        .ListColumns(4).Range(N).Value = Format(Time, "hh:mm")
    End If
End With

Range("C12") = "打刻停止"

ActiveWorkbook.RefreshAll

End Sub
```
### 解説

まずは打刻開始の説明

```vb
Sub StartTime()

'テーブルの項目数を取得
Dim N As Long

With Sheets("マスタ").Range("A1").ListObject
    '最終項目を取得
    N = .ListColumns(1).Range.Count
    
    'テーブルはデフォルトで１項目分確保されているので事前に項目があるのかないのかチェック
    If .ListColumns(1).Range(N).Value = "" Then
        .ListColumns(1).Range(N).Value = Date
        .ListColumns(2).Range(N).Value = Sheets("打刻").Range("B3").Value
        .ListColumns(3).Range(N).Value = Format(Time, "hh:mm")
    Else
        '最終項目の値を空白チェック（前の打刻が完了しているかいないかをチェック）
        If .ListColumns(4).Range(N).Value <> "" Then
            '完了していたら最終項目＋１に新しく項目を作成
            .ListColumns(1).Range(N + 1).Value = Date
            .ListColumns(2).Range(N + 1).Value = Sheets("打刻").Range("B3").Value
            .ListColumns(3).Range(N + 1).Value = Format(Time, "hh:mm")
        End If
    End If
End With

Range("C12") = "打刻中"

End Sub
```
まず、テーブルの最終項目を取得しています。
ただ、テーブルは空でも一項目文確保されているようで、空の場合と項目が一つの場合で挙動がかぶってしまったので、一列目の一項目目が空白かどうかチェックしています。
空白なら項目数は0で空白ではないなら項目数が1なのでそこで条件分岐をさせてます。

そして最終項目の打刻が完了しているかをIF文でチェック。
打刻が完了していないのに打刻開始が押せないように。
打刻が開始できたら、
１列目に今日の日付
２列目に選択した学習内容
３列目に今の時間
を転記します。

転記が終わったら
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1744893/fe53ebad-c038-f3f7-1bf8-785df52b0191.png)
状態の部分を打刻中に変更し、打刻開始の処理は終了。

次に打刻終了についての解説
```vb
Sub EndTime()

'テーブルの項目数を取得
Dim N As Long

With Sheets("マスタ").Range("A1").ListObject
    '最終項目を取得
    N = .ListColumns(1).Range.Count
    '最終項目の値を空白チェック（前の打刻が完了しているかいないかをチェック）
    If .ListColumns(4).Range(N).Value = "" Then
        '空白だったら現在の時間を入れる
        .ListColumns(4).Range(N).Value = Format(Time, "hh:mm")
    End If
End With

Range("C12") = "打刻停止"

ActiveWorkbook.RefreshAll

End Sub
```

同じく最終項目を取得後、打刻が完了しているかしていないかをチェックし、完了していなかったら現在の時刻を４列目に入れる。

入れ終わったら状態を打刻停止に変更。
ピボットテーブルは更新をしないと反映されないです。
４つあるのですべて更新で対応。

### 疑問
なぜか学習開始時間-学習終了時間をVBAで計算しようとしたらエラーになったのでテーブルに計算式を入れる形で学習時間を出力させました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1744893/8cd75ab4-7e52-5b55-aef1-7a553676e5ee.png)

### マスタシートについて
表示形式はシート全体に時刻をセットしておくと見やすいです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1744893/12723819-bdbb-364a-e72e-51a22f5569fd.png)

テーブルはこのような形式で作成しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1744893/09bdf3c1-ec16-b514-247c-6c4501c05d0b.png)

### ダッシュボードについて
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1744893/56b51217-94c2-8e91-fa95-94393a41a4bc.png)

好みでピボットテーブルを作成していろんな見せ方をできればいいと思いますが、試しに作ったのでこのくらいです。
直近の目標も出しておくといいかもしれません。
ピボットテーブルは一つのピボットテーブルで作成したり、コピペしてピボットテーブルを増やしてピボットグラフを作成すると、全部のグラフが連動してしまうので、それはそれで良し悪しありますが今回はグラフの軸が学習項目の場合と日付の場合で縦棒と横棒を作っているので、連動されると実装できなくなるのですべてを切り離しています。

やり方は空白セルを選択し、Alt＋D＋Pでピポットのウィザードを出します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1744893/57f4c5cd-4c6c-6cde-60eb-4c651f69eb98.png)
レポートの種類でピポットグラフレポートを選択し、次へを押します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1744893/ee831c00-abec-0acb-b1d3-91e258e9bd18.png)

テーブル名を入力し、次へを押す。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1744893/28da69c5-1c7d-4291-6afa-bacae685854c.png)

ここがポイントで、いいえを押すと連携しない独立したものを作成できます。
いいえを押します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1744893/ce3d3a21-9473-d50b-9cbf-aac301e8a532.png)

どちらでも好きな方を選択して完了を押す。

ピボットグラフを作成としているので、ピポットテーブルとピボットグラフが１つづつ作成されました。

グラフをダッシュボードの方に移動させて、ピポットテーブルに値を振り分けていきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1744893/08da6a9a-0573-78a1-f294-564b781f621f.png)

例えば棒グラフの作成ではこのような形でデータを挿入

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1744893/f68073d4-f829-e206-4872-cf140c6b0a8f.png)

値が個数になっているのでこのままだと勉強した回数のグラフになってしまうので、値の学習時間のプルダウンで値フィールドの設定から合計に変更します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1744893/66ff676a-d479-cf09-e4ff-45f942db1588.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1744893/47b66db6-f4c9-a3a0-d885-d79ef2bc5b65.png)

OKを押す
グラフの方を確認しに行くと勝手に棒グラフができている

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1744893/121319c2-52d7-cd42-f4f9-996dd51a7a66.png)

グラフの変更はデザイン→グラフの種類の変更から行い、必要なグラフを作成してダッシュボードをカスタマイズしてください。
メインはVBAコードなのでその他の説明は割愛

### 終わり
テーブルのメソッドあまり使い慣れていなかったのであえて使いました。
すこし勉強になりました！

せっかく自作したのでこれを使って自己管理していきたいなと思いました！
最近麻雀をやりはじめてはまってしまったので、麻雀の勉強時間も打刻しようと思います(笑)