とりにくを好きな人がVBAを勉強しています。

VBAを中心に、その他日々の生活で感じていることを書いていきます。

【VBA】重複しないリストをVBAでつくりたい

おはようございます。こんにちは。こんばんは。
ネタ切れしてますが、意外とモチベーションが続いていて驚いているとりにくVBAです。

今回は実務でよくある重複しないリスト作りをしてみました。

完成イメージ

f:id:mayo032j:20200529062416p:plain

こんな感じのものを一瞬でスパッと!



f:id:mayo032j:20200529062445p:plain

ロジック解説

まず、表全体について、最初の行を見出しとして昇順に並べ替えます。
そして、セルのデータを比較して同じだった場合、行ごと削除します。
これを表を一番下から繰り返していきます。

なぜ下からかというと、順番に処理していく場合、行番号を動かして繰り返し処理をしようと考えているので、上からだと行削除すると行番号が変わってしまって(上に詰まる…うまく説明できません)、うまくいきません。

同じものを上から処理してしまった場合の画像はこちら。
f:id:mayo032j:20200529063424p:plain

ちょっと残ってしまいますね。
今回私が使った考え方では、上からではなく下からの処理をします。

コードにしてみよう

さて、ロジックをコードに落とし込んでいきます。

並び替え

まず、並べ替えですが、VBAではSortメソッドが用意されています。

"範囲".Sort

このあとにパラメーターをいろいろ設定するのですが、Sortメソッドについては意外と公式リファレンスが見やすいので参照してください。

docs.microsoft.com

Key1はRange("A1")を指定します。文字列でもいいと書いているので、"ア行"と書いてもでも大丈夫です。
省略可能と書いてあるので、今回は列が1つしかないから大丈夫かと思い、省略してみたらエラー出ました。

理由はよくわからないですが、明示的に指定するのが無難だと思います。

次にOrder1は、昇順にしたいのでxlAscendingを指定します。


あとは、先頭行を見出しとするかどうかをHeaderで指定します。
今回は見出しとして並べ替えの対象から外したいので、xlYesを指定します。
省略すると見出しとしてくれないみたいです。
また、Excelに判断を任せるxlGuessというのが用意されているのですが、使う場面が思いつきません。

ちなみに今回の表だと、いっしょに並べ替えられてしまいました。
f:id:mayo032j:20200529065710p:plain

さらに、どうすれば見出しとして認識してもらえるか試したところ、書式を変えてみたらうまくいきました。
f:id:mayo032j:20200529065846p:plain

いずれにしても、Excelに任せないでしっかり指定するのがよいと思います。

重複の判定から行削除

重複の判定は、並べ替えられたそれぞれのデータを上のデータと比較して同じものであれば行を削除するとします。
繰り返し処理の変数を行数として扱う前提で、セルの指定はCellsを使用します。

ひとつ上のデータと比較する

i行のセル値とその一つ上、つまりi-1行のセルの値を比較します。
比較ということでif文を使います。

If Cells(i,1).value = Cells(i-1,1).value then

End If

行を削除する

セルの値を比較して、同じ値であれば行ごと削除していきます。
そのセルが属する行を取得するのは、EtireRowを使います。
削除はDeleteです。

If Cells(i,1).value = Cells(i-1,1).value then

    Cells(i,1).EntireRow.Delete

End If

繰り返す

最後に繰り返し処理で挟んでおしまいです。
今回は一番下の行から処理していくので、ForNext文のStepにー1を指定します。

For i = Cells(Rows.Count,1).End(xlup).Row to 2 Step -1

    If Cells(i,1).value = Cells(i-1,1).value then

        Cells(i,1).EntireRow.Delete

    End If

Next

Cells(Rows.Count,1).End(xlup).Rowについては常套句で~といった感じでそのまま覚えましょうとよく言われますが、
いつかよい解説ができそうになったら記事にしてみたいと思います。

おわりに

今回、重複しないリストづくりをVBAでやってみました。その中でSortメソッドについて少し詳しくなれましたし、知っていることも再確認することができました。

プログラミングでは最終的な結果が同じでも、いろいろな過程があるのがおもしろいですよね。
今回の方法以外にも違うものを作ったら解説していきたいと思います。

今回の行ごと削除っていうのは、とてもExcel的な処理だと思っていて、ワークシートにデータがあるのが前提となっています。
そうでない場合にも一発でパーンとリストだけ作ったりしたい場面があるんじゃないかなあと想像しています。
また、ワークシート上のデータを扱う場合でも、関数が入っていて行ごと削除したくないとかいろいろな条件が出てくるような気がしますので、場面場面でさらなる工夫が必要になると思います。

とりあえず、いい勉強になりました。