ExcelVBA
ExcelVBA

以前、Dictionaryについて簡単に紹介しました。

Dictionaryは、Keyを使ってデータを管理できるので、

「このデータは存在する?」

という確認をするときにも便利です。

今回はもう少し実践的に、2つの項目を組み合わせてKeyを作り、2つのデータの差分を調べる方法を紹介します。

例えば、

「品番は同じだけど、工程が違う」

といったデータを区別したい場合です。

今回使うコード

まずは、実際のコードを見てみます。

今回やりたいのは、

前回のデータにはあったけど、今回のデータにはないもの

と、

今回新しく追加されたもの

を調べることです。

例えば、前回のデータが、

| 品番 | 工程 |
| —- | — |
| A001 | 加工 |
| A001 | 塗装 |
| A002 | 加工 |
| A003 | 組立 |

だったとします。

そして今回のデータが、

| 品番 | 工程 |
| —- | — |
| A001 | 加工 |
| A001 | 塗装 |
| A002 | 組立 |
| A004 | 加工 |

になったとします。

この場合、

* A002 + 加工 → なくなった
* A002 + 組立 → 追加された
* A003 + 組立 → なくなった
* A004 + 加工 → 追加された

という差分があります。

これをDictionaryで調べてみます。

Dim dictOld As Object
Dim dictNew As Object

Dim key As Variant

Set dictOld = CreateObject("Scripting.Dictionary")
Set dictNew = CreateObject("Scripting.Dictionary")

'前回データ
dictOld.Add "A001" & "|" & "加工", True
dictOld.Add "A001" & "|" & "塗装", True
dictOld.Add "A002" & "|" & "加工", True
dictOld.Add "A003" & "|" & "組立", True

'今回データ
dictNew.Add "A001" & "|" & "加工", True
dictNew.Add "A001" & "|" & "塗装", True
dictNew.Add "A002" & "|" & "組立", True
dictNew.Add "A004" & "|" & "加工", True

'なくなったデータを調べる
For Each key In dictOld.Keys

```
If dictNew.Exists(key) = False Then

    Debug.Print "削除:" & key

End If
```

Next

'追加されたデータを調べる
For Each key In dictNew.Keys

```
If dictOld.Exists(key) = False Then

    Debug.Print "追加:" & key

End If
```

Next

実行すると、

削除:A002|加工
削除:A003|組立
追加:A002|組立
追加:A004|加工

という結果になります。

これで、前回と今回のデータの差分を確認することができました。

2つの項目をどうやってKeyにしているのか

ここが今回のポイントです。

Dictionaryは基本的に、

Dictionary.Add Key, Item

という形でデータを登録します。

ただし、DictionaryのKeyは基本的に1つです。

では、

「品番」と「工程」の2つをKeyとして使いたい場合はどうするのでしょうか。

そこで今回は、

"A001" & "|" & "加工"

のように、2つのデータを1つの文字列にまとめています。

すると、

A001|加工

という1つのKeyとして扱うことができます。

なぜ「|」を入れているのか

単純に、

"A001" & "加工"

としても動きます。

ただ、これだと、

A001加工

となってしまうので、どこまでが品番で、どこからが工程なのか分かりにくくなります。

そこで、

"A001" & "|" & "加工"

として、

A001|加工

という形にしています。

この区切り文字は`|`でなくても構いません。

例えば、

"A001" & "_" & "加工"

とすれば、

A001_加工

になります。

自分が分かりやすい区切り文字を使えばOKです。

2つの項目を組み合わせると何が便利なのか

例えば、品番だけをKeyにしてしまうと、

A001

というKeyしか作れません。

でも実際には、

A001 + 加工
A001 + 塗装
A001 + 組立

のように、同じ品番でも工程が違うデータがあります。

これを区別したい場合、

A001|加工
A001|塗装
A001|組立

とすれば、それぞれ別のKeyとしてDictionaryに登録できます。

つまり、

複数の項目を組み合わせて、1つのKeyを作る

という考え方です。

ExcelのデータからKeyを作る

実際のExcelでは、例えばA列に品番、B列に工程が入っているとします。

A列       B列
品番      工程
A001      加工
A001      塗装
A002      加工
A003      組立

この場合は、

key = Cells(i, 1).Value & "|" & Cells(i, 2).Value

とすれば、

A001|加工
A001|塗装
A002|加工
A003|組立

というKeyを作ることができます。

あとは、

dict.Add key, True

としてDictionaryに登録します。

差分チェックではExistsが便利

今回の差分チェックで重要なのが、Dictionaryの`Exists`です。

If dictNew.Exists(key) = False Then

```
Debug.Print "削除:" & key
```

End If

これは、

「今回のDictionaryの中に、このKeyは存在する?」

という確認をしています。

存在しなければ、

「前回にはあったけど、今回はなくなった」

と判断できます。

逆に、

If dictOld.Exists(key) = False Then

```
Debug.Print "追加:" & key
```

End If

とすれば、

「今回にはあるけど、前回にはなかった」

というデータを見つけることができます。

今回の処理を簡単にすると

今回やっていることは、実はかなりシンプルです。

まず、前回のデータをDictionaryに入れます。

A001|加工
A001|塗装
A002|加工
A003|組立

そして今回のデータもDictionaryに入れます。

A001|加工
A001|塗装
A002|組立
A004|加工

あとは、

前回にはあるけど、今回にはない

というKeyを探します。

すると、

A002|加工
A003|組立

が見つかります。

逆に、

今回にはあるけど、前回にはない

というKeyを探せば、

A002|組立
A004|加工

が見つかります。

Dictionaryは複数の項目を組み合わせても使える

Dictionaryというと、

「KeyとValueをセットで管理するもの」

というイメージがあると思います。

もちろん、それがDictionaryの基本的な使い方です。

ただ、今回のように複数の項目を組み合わせてKeyを作ることで、

複数の条件をまとめて1つのKeyとして扱う

という使い方もできます。

例えば3つの項目を使いたければ、

key = 品番 & "|" & 工程 & "|" & 担当者

というようにすることもできます。

「2つのデータを比較したいけど、1つの項目だけでは判断できない」

という場合には、この方法が結構使えます。

Excelで大量のデータを比較するときなどにも便利なので、Dictionaryの使い方の一つとして覚えておくといいと思います。