【Excel】エクセル七つ道具ではじめるシンプルなタスク管理

# はじめに

どうも、y-tetsuです。暑い日が続きますが、皆様いかがお過ごしでしょうか。

筆者の方はというと、夏バテ気味で日々のタスクに追われておりますが、そんな中にも何かしら楽しみを見出そうと、精進しております。

ところで、普段のお仕事でのタスク管理、皆様はどのようにされておりますでしょうか？

![himawari.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/0e652286-4880-7e80-d25c-f863563adc60.png)

市販のタスク管理ツールや、社内で代々受け継がれているツール、付箋に手書き、自らのメモリ(記憶)、など色々あるかと思います。皆さんそれぞれに置かれている状況や事情に応じて、なるべく最適なものを選ばれているのではないかと思います。

そんな筆者の環境はというと、割とエクセル文化が広く根付いていたりします。もちろんプロジェクトによっては`Redmine`だったり`Jira`だったりといった、プロジェクト管理ツールを使っている所もあります。ただ、あまり自分の周りには浸透していない現状に流されつつ…。

これらを少なからず使ってきた中で、筆者が感じたこととしては、ちょっとした自分のタスクを管理するだけだったら、もっと簡単にできたりしないかな、という思いでした。

例えば、代々受け継がれてきたエクセルツール。見た目が自分の好みと違う、入力項目がやたら多い、なんかミスるとマクロが動かなくなる、メンテしようにも中身がカオス、…みたいな悩みは尽きることがありません。

![ramune.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/009003e0-2636-4fed-da75-aae9ccc5cb5a.png)

だったら、「自分好みのものを作ってみようかな」と思い立ってしまいました。

プロジェクト管理ツールほど大々的なもの(サーバーを立てたり、お金を使うようなもの)ではないけれど、単純に付箋アプリやメモ帳にタスクを残しておくよりはマシ、みたいな自分にとってちょうどいい感じの、簡単に使えるエクセルツールを目指してみることにしました。(結局これも、まわりまわってだれかの煩わしさにならないことを願いますが)

ついでにこのツールを作る過程も紹介することで、エクセルはこれからですっ！という方にとっての、何かの足しになれればいいなと思いました。

バキバキのエクセル上級者の方や、あるいはエクセル神話ちょっとニガテ…な方におかれましては、どうかお手柔らかにお見守り願います。

![katorisenko.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/b1436e85-d1f1-ea07-a425-6b91d4ebac38.png)

# 完成品
早速なんですが、最初に今回作ったタスク管理ツールの完成品をお見せします。

(見た目)
![face.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/c430407c-26dc-43d1-522d-e6628caba6fe.png)

(使っている様子)
![act.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/7cf2e7d1-bfe5-ccba-c5b8-806721770909.gif)

![act2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/cade3ff0-f684-9221-9865-adb45a09011e.gif)

アピールポイントは以下です。

- 入力項目は必要最小限に
- シートの作りもなるべく簡単に
- ガントチャートが付いてます
- タスクのソート機能も付いてます

「どんなエクセルの機能をどのように使ったのか」や「作っていく過程」については、この後じっくりと説明していきます。

ですので、中身がブラックボックスでメンテできない！みたいな心配は、ほとんどないと思います。さらに、記事の説明をご理解いただけると、より自分好みのものに作り変えられるのではと思います。

ダウンロードは以下からできます。

https://github.com/y-tetsu/simple_task_management

それでは、話を進めていきいたいと思います。


# 七つ道具
まずは、今回のタスク管理ツールを作るために活用した、七つの道具(エクセルの機能)をご紹介します。これらの道具で何ができるのか、どんな時に使うと良いのか、をさらっとここで掴んでいただければと思います。

いずれも使いこなせれば、便利なものばかりだと思いますので、是非知っておいてください。使える道具が増えると、作る楽しみも増すのかなと思います。

## ①セルの書式設定
セルの書式設定を使うと、大きく以下を変更できます。
- フォントやフォントサイズ、文字の色
- セルの中の配置
- 塗りつぶしの色
- 罫線
- 表示形式

今回の活用方法としては

タイトルを目立つように設定したり
![title.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/3944b9f8-4b52-f009-05a1-f2f998f68fc3.png)

表を罫線で描いたり
![table.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/5c3dfdf9-9df0-b827-d4a3-38a1731ff3d0.png)

セルの配置を中央寄せにしたり
![position.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/a73ca286-fd0f-1858-7901-b798006abdfc.png)

表示形式で進捗や日付の見た目を整えたり
![dispformat.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/4cff4e6a-7cfe-f278-ac23-bf6e6ce5f87f.png)

といった事に使いました。

セルの書式設定の基本的な説明は、以下のサイトが参考になりました。

https://office-de-tips.com/excel-cell-formatting.html


## ②条件付き書式
条件付き書式を使うとセルの値に応じて、何かしら書式を変更することができます。

今回の活用方法としては

日付に応じてガントチャートの線(塗りつぶし)を引いたり
![gunt.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/e0be096e-4993-427c-c9cb-f1b67e495d07.png)

日付に応じて罫線を引いたり
![keisen.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/01ee190d-30d7-be09-9a8b-8e074470e346.png)

進捗率をデータバーで表現したり
![databar.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/e75523af-aad5-f05d-9d06-82e0269480be.png)

進捗率に応じて塗りつぶしの色を変えたり
![taskdone.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/1810b548-cd48-d04c-ea68-1e3b1a822d19.png)

といった事に使いました。

条件付き書式の基本的な説明は、以下のサイトが参考になりました。

https://exceljoshi.cocoo.co.jp/media/excel-condition


## ③データの入力規則
データの入力規則を使うと、セルに入力できる値を制限できます。

今回の活用方法としては

プルダウンリストからプロジェクト名を選べるようにしたり
![project.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/8f9faf76-80ed-1fdb-7628-9c3d34de84c6.png)

優先度を選べるようにしたり
![prior.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/14f1dcc9-84ab-fceb-0505-e52aa943a6a1.png)

といった事に使いました。

データの入力規則の基本的な説明は、以下のサイトが参考になりました。

https://excel-doctor.jp/input-rules/


## ④フィルター
フィルターを使うと、表の特定の条件のみ表示させることができるようになります。

特定の担当者のタスクのみを表示させたり
![tantou.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/a7139e48-7c93-65ec-eb46-cc503ea98fd7.png)

優先度の高いタスクのみを表示させたり
![highprior.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/c9f7c99d-4ae1-8ded-9fec-6c994d172519.png)

といった事に使いました。

フィルターの基本的な説明は、以下のサイトが参考になりました。

https://excel-doctor.jp/filter/


## ⑤数式・関数
セルの中に数式を入れることで様々な計算が行えます。また、数式の中であらかじめ用意された便利な関数を利用する事ができます。

今回の活用方法としては

`TODAY`関数で今日の日付をとってきたり
![today.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/9b41c46e-ee36-9f6d-f307-078fe1d29caf.png)

ガントチャートの日付を数式で計算して動的に切り替わるようにしたり
![calender.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/0d5403a3-d312-4f3d-4110-41a5ed0053f0.gif)

`NETWORKDAYS`関数で土日祝を除外した日数を計算したり
![networkdays.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/d6a74430-2a80-9fbb-7cbb-76c6d211c55e.png)

といった事に使いました。

数式・関数の基本的な説明は、以下のサイトが参考になりました。

https://excel-master.net/common/excel-basic/excel-formula/

https://excelcamp.jp/media/function/8387/


## ⑥マクロ
マクロは、あらかじめVBAで書いておいたロジックにしたがって、一連の操作を一括で自動実行する際に使います。

今回の活用方法としては

無秩序に追加されたタスクをボタン一つでソートできるようにしたり
![sort.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/0d64e9f4-e204-f405-f363-8dbc28eff500.gif)

行が足りなくなった際にこれもボタン一つで追加できるようにしたり
![addcol.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/7b46b73f-713a-70dc-1f0e-53bd958f37a1.gif)

といった事に使いました。

マクロの基本的な説明は、以下のサイトが参考になりました。

https://sakusaku-office.com/excel/post-15192/

## ⑦ウィンドウ枠の固定・グループ化
ウィンドウ枠の固定とグループ化は別々の機能です。ですが、両方とも表示に関係するものということで、強引ですがひとくくりにさせていただきました。

今回の活用方法としては

ウィンドウ枠の固定で、スクロールバーを操作した際に、表の見出しや列は固定とし、ガントチャートは先々の予定をスクロールして確認できるようにしたり
![windowfix.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/ed97df06-7727-c9e5-ca8d-bb3044d0b7e3.gif)

グループ化で、ガントチャートをより広く見えるように、一部の列を非表示にして表をコンパクトにしたり
![grooping.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/6f128f4b-c479-68d7-f96b-10e0220d468d.gif)

といった事に使いました。

ウィンドウ枠の固定・グループ化の基本的な説明は、以下のサイトが参考になりました。

https://litera.app/blog/excel-freeze-rows-and-columns/

https://office-hack.com/excel/grouping/


以上で、エクセルのタスク管理ツールを作るための七つ道具の紹介は終わりです。

# 作成過程
ここからは、何もないゼロから始めて、冒頭の完成品にいたるまでの過程を、順を追って説明していきたいと思います。

結構長いのですが、お付き合いいただけると大変うれしく思います。

## 1. タスク管理の項目を決める
まずは、どのようなタスクの管理方法がちょうどいいか探っていきます。

究極的にシンプルな形は、単純なタスクの羅列になります。
![simple1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/1f788484-aa4b-7efb-2ddc-8f516db8e644.png)

タスクがあれば追加し、終われば消す運用になると思います。

これなら、付箋アプリでも十分なのでもう少し何か足さないと、やる意味がなさそうです。

では、ここに何か足すと良いものとして、タスクの状態と期限、それから優先度はどうでしょう。
![simple2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/b1aa9f28-800a-007e-b9c2-90a850816976.png)

処理しないといけないタスクが増えすぎると、期限や優先順位に応じてどうこなすかをやりくりする必要がでてきますよね。

状態も入れたことで、終わったタスクとそうでないタスクも区別できるようになりました。過去に消化したタスクの履歴も残せますね。

続いて、開始と終了の日付、担当者名を追加するのはいかがでしょうか。
![simple3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/345a2577-0c7e-8959-54c0-f161c7f487ec.png)

タスクのやりくりに、開始と終了の日付を活用できると予定が立てやすくなりそうです。また、担当を入れたので自分以外の人にお願いした仕事も管理できるようになりました。


…と、こんな感じで実用性を吟味しつつ、最終的に採用した項目は、以下となりました。

|項目名 |用途 |
|---|---|
|No. |タスクの識別。「何番のタスク」と呼べば周りと共有しやすい。 |
|プロジェクト |タスクが関係するプロジェクト名。大項目の位置づけ。 |
|カテゴリ |タスクが属する分類。中項目の位置づけ。 |
|タスク |こなすべきタスクの内容。小項目の位置づけ。 |
|担当 |タスクを実施すべき人の名前。個人管理用とはいえ誰かにタスクをお願いすることはある。 |
|優先度 |タスクの優先度。タスクには絶対やらないといけないものや、後でもいいけどやっておいた方がいいものがある。 |
|進捗 |タスクの進み具合。割合で表記する。タスクの状態も合わせて管理。|
|開始 |タスクを開始する日付。着手日。予定兼実績。|
|終了 |タスクを終了する日付。納期。予定兼実績。|
|日数 |タスク消化に必要な日数。土日祝は除く。|
|備考 |何かあったときにメモを残すための欄。|

タスクの分類だったり、日付の部分はもう少し充実させることもできそうですが、さっと使える事を優先し絞りました。

項目が少ないと入力は楽ですが、機能性が損なわれます。一方で、項目を増やすと機能性は増しますが、入力が面倒になります。両者は**トレードオフ**の関係にあり、好みも分かれるところかなと思います。是非皆さんにとってのちょうどいいポイントを見つけてみて下さい。

以上で、タスク管理の土台は完成です。

## 2. タスク一覧を作る
ここでは、先ほどの項目を元に、タスクの一覧表を作っていきます。

前章の**七つ道具**を思い出しつつ読んでもらえればと思います。

### フォントを統一
シートに書き込んでいく前に、全セルのフォントを一括で指定して統一しておきましょう。

筆者は普段使いで硬すぎない`メイリオ`を使いました。

矢印のあたりを押して全選択し、フォントを指定します。
![setfont.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/527e3bc3-1060-80c5-f7f3-893c4efbca4e.png)

### タイトルを書く
続いて、タイトルを書きます。少しフォントサイズを大きくして目立たせてみました。
![title.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/95294939-c89b-c9b7-d4c1-ef4eb75e2c6a.png)

### 表を描く
今度は罫線を使って表を書きます。
![table2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/48fc841b-149b-e1c5-c711-bfc50ff434b3.png)

見出しの空行2行は、あとでガントチャートのカレンダーと位置を合わせるために入れています。

見出しは色を変えて見やすくしてみます。
![header.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/b4967814-5ea3-9f53-59f6-420456cb728d.png)

### 書式を決める
こまごま、書式を調整します。以下の図のように設定しました。
![tableformat.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/efdad2b0-0b87-0f22-6bb1-52b5521c191f.png)

### 設定用シートを作る
次の章でリスト入力の設定により、プルダウンから項目を選べるようにするため、ここではその前準備を行います。

新しいシートを作って、シート名を「設定」とします。そして、以下のような表を作ります。
![settings.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/28bc6c5c-a2c9-d6e7-ddf3-6313981a985c.png)

|列目 |用途 |
|---|---|
|見出し行|タスク一覧表の見出し部分の行番号を記載します。1行目に記載が必要です。|
|開始行|タスク一覧表の入力欄の開始行番号を記載します。1行目に記載が必要です。|
|開始列|タスク一覧表の開始列の名前を記載します。1行目に記載が必要です。|
|終了列|タスク一覧表の終了列の名前を記載します。1行目に記載が必要です。|
|並び替え優先項目|タスクをソートする際の優先度を決めます。上にあるほど先に考慮されます。見出し名を指定します。|
|プロジェクト|プロジェクト名をリストアップしておきます。|
|カテゴリ|カテゴリ名をリストアップしておきます。|
|担当|タスクを実施する人の名前。関係者をリストアップしておきます。|
|優先度|タスクの優先度、特にこだわりがなければ、「高」「中」「低」の3段階としておきます。|
|祝日|祝日の登録用。日数算出の際に除外されます。|

プルダウンリストからは最大で30個まで選べるよう、あらかじめ30行分の枠を用意しています。

実際の設定例は以下のようなイメージになります。
![settings2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/b6e65cce-b4c9-2372-ea56-ec6bf37f5bfe.png)

プロジェクトやカテゴリの列などで1行目を空けている部分は、空欄を選択できるようにするための措置です。

### リスト入力を設定する
リスト入力を設定する項目は以下です。
- プロジェクト
- カテゴリ
- 担当
- 優先度

対応する設定欄を入力の対象にするのですが、ここで1つ工夫を入れたいと思います。

あらかじめ30個までの上限を設けましたが、この範囲内であれば、メンテ不要で設定したものが反映されるようにしたいと思います。

データの入力規則で、リスト入力の元の値に以下の数式を設定します。

```
=OFFSET(設定!$G$4,,,COUNTA(設定!$G$4:$G$33)+1)
```

![listin.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/b8ada9c6-1ec0-665e-4d61-565d37640fa3.png)

`COUNTA`関数にて項目が空でないものの個数を取得して、それにさらに1を足しています。これは最初の空欄分を考慮するためです。

あとは`OFFSET`関数にて、**最初の要素から先ほどの個数までの範囲**をリスト入力の元の値にするという処理をしています。


### 日数の計算をする
日数の計算には`NETWORKDAYS`関数を用いました。

```
=NETWORKDAYS(I7,J7,設定!$K$4:$K$33)
```

上記により、開始(I列)～終了(J列)の日数から土日と祝日を除外した営業日を計算しています。祝日は`設定!$K$4:$K$33`にて設定シートの値を読み込んで判断しています。
![networkdays.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/e3b96f1e-bc99-1be3-e0bd-91d3dfe3fe57.png)

上図のように土日の2日間はカウントされておりません。

### 優先度と日数に条件付き書式を設定する
優先度は以下の書式設定を行いました。

|値 |書式 |
|---|---|
|高 | ![hprior.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/bbf313a7-89e1-4fd5-4e45-96555e49f365.png) |
|中 | ![mprior.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/41405a8c-f9c3-7b7c-c22a-9115b258b580.png) ※書式変更なし |
|低 | ![lprior.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/ef491910-a80c-f2be-7aec-65cd3dc16cfa.png) |

![priorset.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/fefa6b8a-2ea9-e330-07e7-7cad193d38db.png)

日数は数式が入っていて、うっかり消さないようあえて見えるようにしておきます。ただ、色が標準のままだと、なんとなく不格好に見えるので、値が0のときに色を少し付けるようにしました。

![days.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/5fc1df77-03bf-cd55-fbcf-6e84107ddfef.png)

![daysset.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/eefc1056-51fa-924e-d9a0-537c44ea3676.png)

![daysini.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/557c4005-6b51-63c2-34c1-318ab63ceaa9.png)

### 進捗にデータバーを表示させる
条件付き書式のデータバーを使って進捗状況を把握しやすくします。
![databar2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/8fedbba3-caf5-67db-515e-11162a5cab19.png)

![databarset.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/110e8393-abe1-d5e7-1d52-649fd129a3b4.png)


### 日付と進捗に応じて警告表示する
タスクの一覧も漫然と眺めていると、細かい部分は見落としやすいです。

そこで、タスクの進捗状況に応じた色分けを行う事で、ぱっと見で把握しやすくしておきます。

|タスクの状態 | 条件 | 書式 |
|---|---|---|
|完了 | タスクの進捗が100% | ![taskdone2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/874ff03e-e8c1-9c89-ce27-45a147f1fb3b.png) |
|着手中 | タスク実施期間中で、進捗が入力されている | ![taskdo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/f0c3fcd5-383d-8e7e-110e-31a72285d017.png)　|
|着手遅れ | タスク実施期間中で、進捗が未入力 | ![tasknotdo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/e864bd33-1817-9444-0b89-f03c2924211c.png)　|
|期限切れ | 終了期限が過ぎている | ![taskexpire.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/210d50c5-d3f3-e2a7-fca3-171427bb9a75.png) |

上の方の条件に該当した書式が優先されるため、順番は以下とします。
![taskorder.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/8c94981a-7404-44b0-01dc-a2bf3d6ac2ce.png)

色がピンクに近づくほど、注意してタスクの状況を確認すると良いです。


### フィルター設定する
条件に応じてタスクの絞り込みをするため、フィルターを設定します。

以下のようにタスク表を選択し
![filterselect.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/8daa6f87-cb57-7d47-808f-d87f22eca55d.png)

フィルターを押してください。
![filter.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/c6f2f39a-2362-1471-de18-376d77ee9fa2.png)

これでフィルターの設定ができました。
![filterd.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/788a0f14-c14e-4efb-c60a-18d86b94b23a.png)

ここまでで、タスクの一覧の作成は完了となります。

## 3. ガントチャートを作る
続いて、タスク一覧の右側にガントチャートを作ります。

ガントチャートがあれば、タスクの進行状況やタスクの重なり具合、期限までの猶予などがイメージしやすくなります。

### ガントチャートの枠を作る
ガントチャートは90日分まで用意しておくこととします。そのための枠を以下のように作ります。
![guntframe.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/91307ea8-c55e-8235-8e26-205cd15c1d33.png)

### カレンダーを動的に表示する
カレンダーは90日の枠の範囲で、基準日を好きに変更すれば、いつの日付でも表示できるようにします。

カレンダーの上に、基準日と何日前から表示させるかの入力欄を作ります。

基本的に基準日には`TODAY`関数を入れておき、何日前の欄を状況に応じて変更する運用を想定しています。一旦、本日より7日前から表示を開始する設定とします。
![calenderin.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/6a710e5e-a43a-52ad-3c8b-33734b7525a3.png)

続いては、カレンダーの日付を先ほどの入力に応じて計算する数式を書きます。

(日)
1列目は`N2-N3`で"基準日"-"X日前から表示"で日付を計算します。
![dayformula1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/9c53b7d9-c045-8342-de8f-e032f17ea3e8.png)

また月の表示形式は以下。
![dayformat.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/be7b8d0c-f5bb-9f38-426a-25fdde3dadd3.png)

2列目以降は、単純に前列+1して1日ずつ足していきます。
![dayformula2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/a0072f20-3974-3d8d-2106-2fc117e74f18.png)

(月)
月は開始列と、毎月1日のみ表示とします。

1列目は`MONTH`関数を使います。
![monthformula1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/4536556c-4802-d803-f28f-9b9d5494a966.png)

2列目以降は、その月の1日の場合は`MONTH`関数とし、それ以外位は空文字("")としています。
![monthformula2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/1af7dabb-c066-7071-85c2-296174a53393.png)

(曜日)
曜日は`TEXT`関数と`WEEKDAY`関数を組み合わせて実現します。
![yobiformula.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/da4a8262-c682-3869-473e-d9d66cab6895.png)

まず、`WEEKDAY`関数により日付の情報から曜日を表す番号を求めます。

そして、`TEXT`関数により番号に応じた曜日の文字に変換して、最終結果としています。

引数の`aaa`は曜日を短縮形で表示するためのオプション指定です。

|番号 | 曜日 | 短縮形 |
|---|---|---|
|1 |日曜日 |日 |
|2 |月曜日 |月 |
|3 |火曜日 |火 |
|4 |水曜日 |水 |
|5 |木曜日 |木 |
|6 |金曜日 |金 |
|7 |土曜日 |土 |

### 月始めの列に罫線を引く
月始めに罫線を引いて見た目を整えます。
![firstkeisen.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/34641062-d8bc-974f-62c8-6bf4bbb082f4.png)

条件付き書式の設定は以下です。
![firstkeisenset.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/3ab8091d-5918-1a1b-c95c-1b9c883aed98.png)

### 土日の文字色を変える
土日の文字色も変えて見た目を整えます。
![donichi.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/32e76c44-a802-cb95-4805-aab8be478ccb.png)

条件付き書式の設定は以下です。
![doset.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/f363e065-7609-82dd-40a1-a8eafeb8975f.png)

![nichiset.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/ff64b044-3759-dbe2-bcf9-edee07efe792.png)

### 休日の列の塗りつぶし色を暗めにする
休日も見た目で分かるように、列の塗りつぶしの色を変えるようにします。
![holyday.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/eae60d98-b04d-7ac9-b145-35a46ff43354.png)

条件付き書式の設定は以下です。
![holydayset1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/cdbac41a-8b49-c275-a5a9-699f2a3332a5.png)

![holydayset2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/88df9c70-749d-f806-388b-0bf68ba2a098.png)

1つ目が土日用で、2つめが祝日用です。祝日用は`COUNTIF`関数で**日付が祝日に該当するか**をチェックしています。

### 今日の列の塗りつぶし色を目立たせる
今日の日付がガントチャート上でどこにあるのかはとても大事なので、列の塗りつぶしで目立つ色を付けるようにします。
![todaycol.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/f51f294c-d68e-19b6-7f81-2101a61c7f3d.png)

条件付き書式の設定は以下です。
![todaycolset.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/3ac6147f-8edb-8f4a-9f01-b082e6078975.png)

### 開始から終了までの期間を塗りつぶす
ガントチャートの一番の見せ場は、やはり日程を表わす部分ですね。

開始から終了までの間を塗りつぶしの色を変えて表現するようにします。
![chart.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/7895832d-1d4b-f2b6-fe7f-106c6ae5626f.png)

条件付き書式の設定は以下です。
![chartset.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/ff5e0cb8-77b8-5bc4-6de9-9145ede56f67.png)

もうここまでくると、条件付き書式はさすがにおなかいっぱいですね…。(安心してください、もうでてきません)

### ウィンドウ枠を固定して列をグループ化する
タスク一覧を表示しつつ、ガントチャートスクロールできるようにするため、ウィンドウ枠を固定します。

以下をセル選択して
![winfix1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/67d7ed28-678a-fbe6-f171-15cc6ea871f2.png)

ウィンドウ枠の固定を押します。
![winfix2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/e159f8b1-72a0-b88d-2f76-9a4f9fd4cae8.png)

選択した位置を基準に、以下のピンク線の内側が可動し、それ以外は固定されます。
![winfix3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/5e2f92b9-a951-2d0b-5767-4978282c7472.png)

グループ化は、以下のようにグループ化したい列をまとめて選択して
![groop1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/b7476df2-7bd7-825d-5f95-dbe65a695aff.png)

グループ化を押します。
![groop2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/12fc7b17-f38e-2364-930a-72c82d70ce03.png)

めでたくグループ化されました。
![groop3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/b578f68e-dc7d-5a90-16cb-6881b738551b.png)

これにて、ガントチャートの作成も完了です。

最後に、マクロで少し使い勝手を良くしたいと思います。

## 4. マクロを活用する
今回使うマクロは全て、専用のボタンクリックで実行できるようにします。

マクロの実行は、ショートカットキーで実行する方法もありますが、今回は対応していません。興味のある方は以下を試してみて下さい。

https://daitaideit.com/vba-set-shortcut-key


### タスクのソート機能を作る
新しいタスクを追加する際に、わざわざ狙った位置に手動で行を挿入して、追加するような手間は省きたいところです。

そこで、今回はタスクの項目毎にあらかじめ設定した優先度に応じて、マクロでソートするようにしたいと思います。

まずは以下に、タスクをソートするためのVBAコードを載せておきます。

```VB:
Public Const SETTING_START_COL = 4       ' 設定シートの開始行番号
Public Const SETTING_HEADER_ROW = 2      ' 設定シートのタスク一覧の見出し行の列番号
Public Const SETTING_TASK_START_ROW = 3  ' 設定シートのタスク一覧の開始行の列番号
Public Const SETTING_TASK_START_COL = 4  ' 設定シートのタスク一覧の開始列の列番号
Public Const SETTING_TASK_END_COL = 5    ' 設定シートのタスク一覧の終了列の列番号
Public Const SETTING_TASK_PRIOR_COL = 6  ' 設定シートのタスク一覧の並び替え優先項目列の列番号


' タスク一覧をソートする
Sub タスクのソート()
    Dim headerRow As Long
    Dim startRow As Long
    Dim endRow As Long
    Dim startCol As String
    Dim endCol As String
    Dim initSelection As Range
    Dim priorColNames() As String
    Dim targetCol As String
    Dim i As Long
    
    ' ソート実行前の準備
    Application.ScreenUpdating = False                                                    ' スクリーンの更新を止める
    Set initSelection = Selection                                                         ' 現在のセル選択位置を退避する
    headerRow = Worksheets("設定").Cells(SETTING_START_COL, SETTING_HEADER_ROW).value     ' 設定シートの見出し行番号を取得
    startRow = Worksheets("設定").Cells(SETTING_START_COL, SETTING_TASK_START_ROW).value  ' 設定シートの開始行番号を取得
    startCol = Worksheets("設定").Cells(SETTING_START_COL, SETTING_TASK_START_COL).value  ' 設定シートの開始列の取得を取得
    endCol = Worksheets("設定").Cells(SETTING_START_COL, SETTING_TASK_END_COL).value      ' 設定シートの終了列の取得を取得
    Range(startCol & startRow).Select                                                     ' 開始セルの選択
    endRow = Selection.End(xlDown).Row                                                    ' 最終行の取得
    
    ' データの並び替え優先度を設定する
    ActiveWorkbook.Worksheets(ActiveSheet.Name).Sort.SortFields.Clear  ' ソートの設定を初期化
    priorColNames = Split(GetPriorColNames(), ",")
    For i = LBound(priorColNames) To UBound(priorColNames)
        targetCol = FindColumn(headerRow, priorColNames(i))
        ActiveWorkbook.Worksheets(ActiveSheet.Name).Sort.SortFields.Add _
            Key:=Range(targetCol & startRow & ":" & targetCol & endRow), _
            SortOn:=xlSortOnValues, _
            Order:=xlAscending, _
            DataOption:=xlSortNormal
    Next i
    
    ' データの並び替え
    With ActiveWorkbook.Worksheets(ActiveSheet.Name).Sort
        .SetRange Range(GetNextColumn(startCol) & startRow & ":" & endCol & endRow)
        .Header = xlGuess
        .MatchCase = False
        .Orientation = xlTopToBottom
        .SortMethod = xlPinYin
        .Apply
    End With
    
    ' No.の番号をオートフィルで設定しなおす
    Range(startCol & startRow & ":" & startCol & startRow + 1).Select
    Selection.AutoFill Destination:=Range(Selection, Selection.End(xlDown)), Type:=xlFillValues
    
    ' ソート実行後の後処理
    initSelection.Select               ' 初期のセル選択位置に戻す
    Application.ScreenUpdating = True  ' スクリーンの更新を再開する
End Sub
```

```VB:
' ソートを優先する項目名の取得
Function GetPriorColNames() As String
    Dim startRow As Long
    Dim i As Integer
    Dim value As String
    
    i = SETTING_START_COL
    Do While Worksheets("設定").Cells(i, SETTING_TASK_PRIOR_COL).value <> ""   ' 設定シートの並び替え優先項目の開始行を取得
        GetPriorColNames = GetPriorColNames & "," & Worksheets("設定").Cells(i, SETTING_TASK_PRIOR_COL).value
        i = i + 1 ' 次の行に移動
    Loop
    
    ' 先頭の","を消す
    GetPriorColNames = Mid(GetPriorColNames, 2)
End Function
```

「設定」シートの並び替え優先度の項目に応じて、表全体をソートする流れになります。

前処理として

- セルの選択位置を退避
- スクリーンの更新を停止

を行い、処理の後で元に戻すことで、途中経過の操作を不意に意識しないで済むよう計らっております。

また、"No."の列は順番が入れ替わったままだと都合が悪いので、オートフィルし直して順番を正しています。


`FindColumn`や`GetNextColumn`のような、以下のようなサブ関数は、"列名"を取得するためのもので、ChatGPTにお願いして作ってもらいました。こういったこまごましたもの、想像以上に的確に提示してくれて、若干恐ろしくもありますね…。

```VB:
' 指定文字列を引数の行番号を始点に検索し、見つかった行番号を返す
Function FindColumn(ByVal rowNum As Long, ByVal searchStr As String) As String
    Dim i As Long
    Dim lastColumn As Long
    
    ' 最終列の取得
    lastColumn = Cells(rowNum, Columns.Count).End(xlToLeft).Column
    
    ' 指定文字列を探す
    For i = 1 To lastColumn
        If Cells(rowNum, i).value = searchStr Then
            FindColumn = Split(Cells(rowNum, i).Address, "$")(1)  ' 列番号の取得
            Exit Function                                         ' 対象の列が見つかった場合は関数を終了
        End If
    Next i
    
    ' 対象の列が見つからなかった場合はエラー終了
    Err.Raise 9999, , "指定の文字列が見つかりませんでした"
End Function
```

```VB:
' 次の列名を取得する
Function GetNextColumn(ByVal columnStr As String) As String
    Dim currentColumun As Range
    Dim nextColumun As Range
    
    Set currentColumn = Range(columnStr & "1")         ' 指定した列の1行目のセルを取得
    Set nextColumn = currentColumn.Offset(0, 1)        ' 指定した列の次の列のセル名を取得
    GetNextColumn = Split(nextColumn.Address, "$")(1)  ' 指定した次の列の列名を取得する
End Function
```

結局、本当の詳細までは説明しきれずブラックボックス化してしまってたら申し訳ありません。

このマクロを、以下の手順でボタンに割り付けると、クリックで実行できるようになります。

以下のメニューからボタンを配置します。
![add-macro-button.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/301095b8-3e02-4131-8d15-0d4ee6fa6fe6.png)

好きな場所に、図形を置くと
![button-added.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/8f124357-901a-4cfa-ffb6-412a8f2c9f7a.png)

マクロ実行用のボタンを追加できます。

右クリックでボタンのテキストを編集するとボタンの文字を変更できます。
![button-added2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/e6f71bba-3146-9e38-f476-8089f9d17997.png)

このボタンを右クリックして、以下のようにマクロを割り当てると
![select-macro.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/b4afa1d6-2d3c-3955-97b5-a36b8fa949cf.png)

無事に、ボタン押下でマクロ実行が可能になります。


### 行の追加機能を作る
タスクが増えてくると、行を増やす時に書式が乱れたり、数式がコピーされなかったりして煩わしくなります。今回はその点もマクロで補います。

追加したボタンと、割り付けたマクロは以下になります。

(追加したボタン)
![button-added3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/f308075a-c69c-6110-84d9-e490597b32a7.png)

```VB:
' 新しい行を一番下に追加する
Sub 行の追加()
    Dim ws As Worksheet
    Dim headerRow As Long
    Dim startRow As Long
    Dim endRow As Long
    Dim startCol As String
    Dim endCol As String
    Dim networkdaysCol As String
    Dim initSelection As Range
    
    ' 行追加前の準備
    Application.ScreenUpdating = False                                                    ' スクリーンの更新を止める
    Set initSelection = Selection                                                         ' 現在のセル選択位置を退避する
    headerRow = Worksheets("設定").Cells(SETTING_START_COL, SETTING_HEADER_ROW).value     ' 設定シートの見出し行番号を取得
    startRow = Worksheets("設定").Cells(SETTING_START_COL, SETTING_TASK_START_ROW).value  ' 設定シートの開始行番号を取得
    startCol = Worksheets("設定").Cells(SETTING_START_COL, SETTING_TASK_START_COL).value  ' 設定シートの開始列の取得を取得
    Range(startCol & startRow).Select                                                     ' 開始セルの選択
    endRow = Selection.End(xlDown).Row                                                    ' 最終行の取得
    ActiveSheet.Outline.ShowLevels columnlevels:=2                                        ' グループ化された列を必ず表示させる
    
    '新しい行の挿入
    Set ws = ActiveSheet                                    ' アクティブなシートを取得
    ws.Rows(endRow + 1).Insert Shift:=xlDown                ' 新しい行を挿入
    ws.Rows(endRow).EntireRow.Copy                          ' 前の行をコピー
    ws.Rows(endRow + 1).PasteSpecial Paste:=xlPasteFormats  ' 前の行の書式を新しい行にコピー
    
    ' 「No.」の列は前の行に＋1する
    Range(startCol & endRow + 1).value = Range(startCol & endRow).value + 1
    
    ' 「日数」の列は前の行の数式をコピーする
    networkdaysCol = FindColumn(headerRow, "日数")                          ' 日数列の取得
    Range(networkdaysCol & endRow).Copy                                     ' 追加前の最終行をコピー
    Range(networkdaysCol & endRow + 1).PasteSpecial Paste:=xlPasteFormulas  ' 追加行に前行の数式をコピーする
    
    ' 行追加後の後処理
    Application.CutCopyMode = False    ' クリップボードをクリアする
    initSelection.Select               ' 初期のセル選択位置に戻す
    Application.ScreenUpdating = True  ' スクリーンの更新を再開する
End Sub
```

大きくは、新しい行を表の一番下に追加した後、以下を処理して実現しています。
- セルの書式を全てコピー
- 「No.」列を前行＋1する
- 「日数」列を前行の数式をコピーする

以上で、今回ご紹介したかったタスク管理ツールの作成過程の紹介は、すべて終わりです。

長い間、大変お疲れ様でした。

![mushitoriami.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/7a02ddfa-557b-ecbd-ee44-00acad5b8c73.png)


# おわりに
退屈な日々のタスク管理も、自分らしくアレンジできれば、ちょっとは楽しくなったりしないかなと思ったり思わなかったり。

きっと世の中には、もっと自分に合ったより良いやり方がありそうなので、これからも追求していきたいです。

最後までお読みいただき、誠にありがとうございました！もし良かったら、「いいね」いただけますと大変励みになります！！

それでは皆さま、夏バテにはお気を付けて、お元気で～。

![asagao.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2653390/c3904b30-3a06-9a91-d8b5-c04ef51012cf.png)