Excel: マトリクスとリストを相互に変換してみる


###### 実施環境 : Microsoft Office Professional Plus 2016

### 0. 概要

以下は、適当に作ったサンプルデータをマトリクスで表示したものです。

![WS000310.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/e4b394b5-3db6-5125-dd43-03e5f7bf77e5.jpeg "マトリクス")

そして以下は、同じデータをリストで表示したものです。

![WS000318.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/0848d496-dd6d-a360-5c37-1d44d28a1c6f.jpeg "リスト")

この2つについて、相互に変換したい場合があります。
もちろんそのためのソフトウェアを使用してもよいですが、インストールできるソフトに制限がある場合など、 Excel の機能だけで変換できると便利です。
今回はその変換の方法をいくつか紹介します。

### 1. マトリクス ⇒ リスト

まずは、マトリクスをリストに変換することを考えます。
今回使用するデータは以下の通りです。

![WS000310.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/e4b394b5-3db6-5125-dd43-03e5f7bf77e5.jpeg "元マトリクス")

###### 1.1. OFFSET 関数

方法はいろいろありますが、今回は OFFSET 関数を用いた方法を紹介します。

以下の空のリストにデータを転記していきます。

![WS000311.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/58c35ed9-894b-d1e5-c4ed-e4b4b8753caa.jpeg "転記先リスト")

まずは、 ROW 関数を用いてリストの各行の行番号を計算します。

```Excel:A2 ~ B16
=ROW()
```

![WS000312.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/44ca5748-1df5-5e28-8476-f45f6793ea9a.jpeg "ROW01")

開始が2からだと扱いにくいので、2を引いて0始まりにします。

```Excel:A2 ~ B16
=ROW()-2
```

![WS000313.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/f0cf39e9-043b-4e78-a05b-6e7eb688f0f2.jpeg "ROW02")

これを、先ほどのマトリクスの軸の何番目にあたるかの数値に変換していきます。

まずは、A列の値を縦軸の番号に変換します。
ここでは、 INT 関数を使用します。
 INT 関数は数値を整数に切り捨てる関数で、今回は「5で割って切り捨てる」ことにします。
5は横軸の列数で、この処理をすると横軸の列数分だけ同じ数値が並ぶことになります。

```Excel:A2 ~ A16
=INT((ROW()-2)/5)
```

![WS000314.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/dd442b6b-c000-b6c2-b3d7-91bafecdf665.jpeg "INT")

次に、B列の値を横軸の番号に変換します。
ここでは、 MOD 関数を使用します。
 MOD 関数は割り算のあまりを取得する関数で、今回は「5で割ったあまり」を取得します。
5は横軸の列数で、この処理をすると横軸の列数分までの連番が繰り返し作られることになります。

```Excel:B2 ~ B16
=MOD(ROW()-2,5)
```

![WS000315.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/5cf9535a-629a-704b-1eb0-6c55ec907a10.jpeg "MOD")

さて、いよいよ OFFSET 関数の登場です。
 OFFSET 関数は引数で動的に指定したセルの値を取得する関数で、以下の文法で記載します。

 OFFSET(基準となるセル, 下に何マスずらすか, 右に何マスずらすか)

まずは縦軸について記載してみましょう。
E1を基準として、先ほどの数値分下にずらします。
数値は0始まりだったので、+1します。

なお、コピペしやすいようにE1は`$`を付けて絶対参照にします。
これで他のセルに式をコピペしてもセル番号がずれません。

```Excel:A2 ~ A16
=OFFSET($E$1,INT((ROW()-2)/5)+1,0)
```

![WS000316.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/1584d2dc-cb2e-16a5-d992-2dd5ff1b45a1.jpeg "OFFSET01")

次に横軸について記載してみましょう。
E1を基準として、今度は右にずらしていきます。

```Excel:B2 ~ B16
=OFFSET($E$1,0,MOD(ROW()-2,5)+1)
```

![WS000317.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/48cb024e-bfda-020c-e080-ef674528d033.jpeg "OFFSET02")

最後に交点の値をC列にいれていきましょう。
下と右両方にずらすようにします。

```Excel:C2 ~ C16
=OFFSET($E$1,INT((ROW()-2)/5)+1,MOD(ROW()-2,5)+1)
```

![WS000318.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/0848d496-dd6d-a360-5c37-1d44d28a1c6f.jpeg "OFFSET03")

マトリクスをリストに変換できました。

### 2. リスト ⇒ マトリクス

今度は逆に、リストをマトリクスに変換することを考えます。
今回使用するデータは以下の通りです。

![WS000318.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/0848d496-dd6d-a360-5c37-1d44d28a1c6f.jpeg "元リスト")

### 2.1. ピボットテーブル

まずは一番お手軽な、ピボットテーブルを使用した方法を紹介します。
元データの変更には対応できませんが、元データがどのようなパターンをとっていても対応できるという利点があります。

ピボットテーブルを使用するには、「挿入」⇒「ピボットテーブル」を選択します。

![WS000319.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/6d97ca06-b02f-4886-1280-799f2d4a5b38.jpeg "ピボットテーブル")

データ範囲を選択し、「 OK 」を押します。

![WS000320.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/7fe14498-3df8-3054-1ff4-d498856ccc6d.jpeg "ピボットテーブルの作成")

今回は作成場所を新規ワークシートにしているので、以下のような新規シートが作成されます。

![WS000321.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/9631969e-6733-a27a-f602-52be21f0a540.jpeg "ピボットテーブルシート")

右のメニューで、ピボットテーブルの設定をします。
まずは、①すべての項目にチェックを入れます。
ただこれだけだと「縦軸」と「横軸」の両方が「行」に入ってしまいリスト形式のままなので、②「横軸」を「列」にドラッグ&ドロップします。
「値」の集計方法は今回の場合なんでもよいです。

![WS000324.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/3c587391-cd70-2be7-ca1a-0682a3281a39.jpeg "メニュー")

これで、以下のようにマトリクスに変換できます。

![WS000325.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/271e8a97-1b5c-6d36-d460-ec64458842e0.jpeg "結果マトリクス")

### 2.2. VLOOKUP 関数

他の方法として、 VLOOKUP 関数を使用する方法があります。
少々複雑ですが、値の変更にも対応することができます。

まずは、元のリストに少々手を加えます。
 VLOOKUP 関数はリストのある軸から値を検索して他の軸の対応する値を返す関数ですが、、2つの軸を同時に検索することができません。
そのため、縦軸と横軸をまとめて、新たに1つの軸を作ります。
今回は、C列に新しい列を挿入し、「縦軸:横軸」という形で値を作りましょう。
使用する CONCATENATE 関数は文字列を結合する関数です。

```Excel:C2 ~ C16
=CONCATENATE(A2,":",B2)
```

![WS000327.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/3528c432-af8f-80c5-1453-ab47ebe32e3a.jpeg "CONCATENATE")

次に転記先のマトリクスの軸を作りましょう。
地道に作ってもよいですが、新しいシートで以下のように操作すると簡単です。

まずは新しいシートに列をコピーします。

![WS000344.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/474d477f-607a-fe8a-325b-7461903d1195.jpeg "列コピー")

次に1つの列を選択して、「データ」⇒「重複の削除」を選択します。

![WS000328.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/39cb6fa3-6285-5672-1cca-e83784f083cd.jpeg "重複の削除1")

1つの列だけ選択していることを確認して、「 OK 」を押します。

![WS000329.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/4839585b-ab46-b4e8-4258-fce89367cc28.jpeg "重複の削除2")

確認メッセージが出るので、「 OK 」を押します。

![WS000330.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/8fac5410-c0dd-6d02-c940-cf502fa70624.jpeg "重複の削除3")

これで、各列について重複を排除した値のリストが取得できます。

![WS000331.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/3fc6f9ce-dd68-cdfe-74aa-bff17c79618a.jpeg "重複削除後")

これをもとに、転記先のマトリクスを作成します。

![WS000332.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/df607bb2-30a1-3a7d-f482-6af03c802241.jpeg "転記先のマトリクス")

このマトリクスに、 VLOOKUP 関数で値を転記していきます。
 VLOOKUP 関数は以下の文法で記載します。

 VLOOKUP(検索する値, 検索するリスト, 左から何番目の値を返すか, 近似一致か完全一致か)

検索する値は縦軸と横軸を先ほどと同じく CONCATENATE 関数で結合したものです。
なお、今回はセル番号の一部だけ絶対参照にしています。
検索自体は指定したリストの一番左の列を対象に行われるので、今回は C 列から指定します。
返す値は D 列なので、 C 列から見て2番目の列です。
完全一致で検索するので、 FALSE を指定します。

```Excel:G2 ~ K4
=VLOOKUP(CONCATENATE($F2,":",G$1),$C$1:$D$16,2,FALSE)
```

![WS000333.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/d3c397df-3f03-ece3-f6dc-2b93090085a4.jpeg "VLOOKUP")

これでマトリクスを作成できました。

### 2.3. OFFSET 関数

かなり限定されたパターンになりますが、2つの軸について「全通り」のパターンが存在し順番に並んでいる場合は OFFSET 関数を使用することも可能です。

以下の空のマトリクスにデータを入れていきましょう。

![WS000345.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/abd5ea9e-1ff3-8ed2-6862-c21e628f39cb.jpeg "空のマトリクス")

まずはE列について ROW 関数で行番号をとります。

```Excel:E2 ~ E4
=ROW()
```

![WS000335.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/a5bfa85c-c050-cc08-6797-173ea3a9820b.jpeg "ROW11")

次に行1について COLUMN 関数で列番号をとります。

```Excel:F1 ~ J1
=COLUMN()
```

![WS000338.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/2a3ab1c5-a843-5741-e111-a9a9b038eb17.jpeg "COLUMN")

このままだとやはり扱いにくいので、それぞれ0始まりに変換します。

```Excel:E2 ~ E4
=ROW()-2
```

```Excel:F1 ~ J1
=COLUMN()-6
```

![WS000341.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/90e12c5a-96e9-0951-9e6f-b5bc9613a561.jpeg "0始まり")

 1.1 と同じようにして、 OFFSET 関数で軸の値を入れていきます。
なお、縦軸については同じ値が横軸の列数=5マス連続で続いているため、5マス飛ばしになるよう5をかける必要があることに注意してください。

```Excel:E2 ~ E4
=OFFSET($A$2,(ROW()-2)*5,0)
```

```Excel:F1 ~ J1
=OFFSET($B$2,COLUMN()-6,0)
```

![WS000342.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/81f4c174-9c7a-1633-a71f-f4d164a9a157.jpeg "OFFSET11")

最後に、 OFFSET 関数で交点の値を入れていきます。
リスト上の値は1列に並んでいるので、縦軸と横軸の番号の和をとればよいです。

```Excel:F2 ~ J4
=OFFSET($C$2,((ROW()-2)*5)+(COLUMN()-6),0)
```

![WS000343.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/f0efa894-57cb-9143-80b9-38c5f6595703.jpeg "OFFSET12")

これでマトリクスを作成できました。