顧客コードや取引先名の列から、2回以上出てくる値だけを取り出したいことがあります。重複の削除やUNIQUE関数で作る「重複を除いた一覧」では、この目的には合いません。この記事では、まずCOUNTIFで値ごとの出現回数を数えます。次に、2件以上ある値だけを1件ずつ並べ、その横に出現回数を出します。元の表は消したり並べ替えたりしないので、確認用の一覧として安全に使えます。

先に決めること:「重複件数」は何の数か

「重複件数」は、次の2つのどちらを指すかで数字が変わります。

数え方 T001が3行あるときの数 使う場面
出現回数 3 同じ値が何行に出てくるかを見る
余分な行数(出現回数−1) 2 1件だけ残すと何行減るかを見る

この記事の一覧には「出現回数」を出します。余分な行数は最後の確認で計算します。

もう1つ決めておくのが「同じ」とみなす基準です。1列(取引先コードなど)で判定するのか、複数列の組み合わせ(日付+伝票番号など)で判定するのかを先に決めます。

例に使う表

A列に取引先コードが入っている表を使います。A9は空白です。

セル 取引先コード
A2 T001
A3 T002
A4 T003
A5 T001
A6 T004
A7 T002
A8 T001
A9 (空白)
A10 T005

ほしい結果は次のとおりです。

重複している値 出現回数
T001 3
T002 2

方法1:FILTER関数が使える場合

FILTERとUNIQUEは、Microsoft 365、Excel 2021以降、Web版Excelなどで使えます。入力して #NAME? になる場合は使えないバージョンなので、方法2へ進んでください。

重複している値を1件ずつ出す

C2に次の式を入れます。結果は下方向へ自動で広がる(スピルする)ので、C3以降は空けておきます。

=UNIQUE(FILTER(A2:A10,(COUNTIF(A2:A10,A2:A10)>=2)*(A2:A10<>""),"重複なし"))

式は次の順に動きます。

  1. COUNTIF(A2:A10,A2:A10) が、各行の値が範囲内に何回あるかを行ごとに返します。T001の行は3、T002の行は2、T003の行は1です。
  2. >=2 で、2回以上の行だけがTRUEになります。
  3. (A2:A10<>"") を掛けて、空白セルを対象から外します。
  4. FILTERが条件に合う行の値を取り出します。この時点では、T001が3回、T002が2回並んでいます。
  5. UNIQUEで、同じ値を1件にまとめます。

該当する値が1つもないときは「重複なし」と表示されます。FILTERの第3引数を省くと、この場合は #CALC! になります。

出現回数を横に並べる

D2に次の式を入れます。C2# は、C2から広がった範囲全体を指します。

=COUNTIF(A2:A10,C2#)

C列の値が増減しても、D列は自動で同じ行数に合わせて広がります。C2が「重複なし」のときは、D2は0になります。

回数の多い順に並べる(任意)

HSTACK関数が使える環境なら、値と回数を1つの式で作り、回数の多い順に並べられます。

=LET(r,A2:A10,k,UNIQUE(FILTER(r,(COUNTIF(r,r)>=2)*(r<>""))),SORT(HSTACK(k,COUNTIF(r,k)),2,-1))

この式は、重複が1件もないと #CALC! になります。

範囲を固定しない

行が増えていく表では、A2:A10 のような固定範囲だと新しい行が対象から漏れます。元の表をテーブルにして、テーブル1[取引先コード] のような列の参照に置き換えると、行を追加しても対象に含まれます。

なお、範囲全体を条件としてCOUNTIFに渡すこの式は、行数が増えるほど計算量が急に増えます。数万行を超えて重く感じる場合は、ピボットテーブルで件数を数える方法なども検討してください。

方法2:FILTER関数が使えない場合(補助列を使う)

Excel 2019以前などでは、補助列で「出現回数」と「重複している値が最初に出てきた行」に印を付け、別の列に一覧を作ります。

列 見出し 2行目の式 役割
B 出現回数 =IF(A2="","",COUNTIF($A$2:$A$10,A2)) 各行の値が何回出てくるか
C 連番 =IF(AND(A2<>"",B2>=2,COUNTIF($A$2:A2,A2)=1),MAX($C$1:C1)+1,"") 重複している値が初めて出てきた行に1、2、3…と番号を振る

B2とC2に入力したら、A列のデータがある最終行までコピーします。C列の COUNTIF($A$2:A2,A2) は下の行へ行くほど範囲が広がるので、同じ値の2回目以降の行には番号が付きません。C1には見出しの文字を入れておきます。MAXは文字を無視するので、最初の番号は1になります。

例の表では、C2(T001)に1、C3(T002)に2が付き、ほかの行は空白になります。

続いて、一覧を作る列に式を入れます。

列 見出し 2行目の式
E 重複している値 =IFERROR(INDEX($A$2:$A$10,MATCH(ROWS($E$2:E2),$C$2:$C$10,0)),"")
F 出現回数 =IF(E2="","",COUNTIF($A$2:$A$10,E2))

E2とF2は、重複している値の数より多めに下へコピーします。ROWS($E$2:E2) はコピー先で1、2、3…と増えていき、INDEXがその番号の付いた行の値を取り出します。番号が尽きた行は空白になります。

一覧を関数で作る必要がなければ、B列とC列を作ったところでオートフィルターをかけ、C列が空白でない行だけを表示してA列とB列をコピーしても同じ結果になります。

複数列の組み合わせで重複を探す場合

「日付と伝票番号の両方が同じ行」のように複数列で判定するときは、COUNTIFの代わりにCOUNTIFSを使います。ここではA列に日付、B列に伝票番号があるとします。

FILTERが使える場合は、D2に次の式を入れると、重複している組み合わせが2列で出ます。

=UNIQUE(FILTER(A2:B10,(COUNTIFS(A2:A10,A2:A10,B2:B10,B2:B10)>=2)*(B2:B10<>""),"重複なし"))

出現回数はF2に次の式で出します。重複が1件もなく、D2が「重複なし」のときはエラーになります。

=COUNTIFS(A2:A10,INDEX(D2#,0,1),B2:B10,INDEX(D2#,0,2))

補助列を使う場合は、方法2の式のCOUNTIFをCOUNTIFSに置き換え、列ごとに条件を並べます。たとえばC列の「初めて出てきた行」の判定は、COUNTIFS($A$2:A2,A2,$B$2:B2,B2)=1 になります。

COUNTIFで数え間違えやすい値

COUNTIFは、見た目どおりに比べない場面があります。出現回数がおかしいと感じたら、次の点を確認してください。

ケース COUNTIFの扱い 対処の方向
大文字と小文字(abc と ABC) 同じ値として数える 区別したい場合はEXACTを使う(下記)
前後の空白、全角と半角 別の値として数える 見た目が同じでも別扱いになる。元データの表記をそろえてから数える
* ? ~ を含む値 ワイルドカードとして解釈され、ほかの値まで数えることがある = で比べる式に切り替える(下記)
数字だけの文字列(001 と 1) 同じ値として数えることがある = で比べる式に切り替える
16桁以上の数字の文字列(カード番号など) 先頭15桁が同じなら同じ値として数えることがある = またはEXACTで比べる
255文字を超える文字列 正しく数えられず #VALUE! になる = で比べる式に切り替える

= で比べると、ワイルドカードや数値への読み替えをせずに比較できます。方法2のB列を次のように書き換えます。

=IF(A2="","",SUMPRODUCT(--($A$2:$A$10=A2)))

大文字と小文字も区別したい場合は、EXACTを使います。

=IF(A2="","",SUMPRODUCT(--EXACT($A$2:$A$10,A2)))

C列の COUNTIF($A$2:A2,A2)=1 やF列のCOUNTIFも、同じ考え方で SUMPRODUCT(--($A$2:A2=A2))=1、SUMPRODUCT(--($A$2:$A$10=E2)) に置き換えて、比べ方をそろえます。UNIQUEも大文字と小文字を区別しないので、区別が必要なときは補助列の方法を使ってください。

結果を確かめる

一覧ができたら、次の3点で数が合っているか確かめます。

  1. 出現回数の合計:D列(方法2ではF列)の合計が、重複に関わる行数と一致するかを見ます。FILTER版なら、次の2つの式が同じ値になります。例の表ではどちらも5です。
    • =SUM(D2#)
    • =SUMPRODUCT((COUNTIF(A2:A10,A2:A10)>=2)*(A2:A10<>""))
  2. 余分な行数:=SUM(D2#)-ROWS(C2#) で、1件ずつ残したときに減る行数が出ます。例の表では 5−2=3 です。シートのコピーで「重複の削除」を実行し、表示される削除件数と比べれば突き合わせになります。空白行があったり、上の表のような表記の違いがあったりすると、差が出ることがあります。
  3. 抜き取り確認:一覧から値を1つ選び、元の表をその値でフィルターします。表示された行数が出現回数と同じかを確かめます。

エラーが出たときの目安は次のとおりです。

  • #SPILL!:結果が広がる先のセルに何か入っています。C列・D列の下を空けてください。
  • #CALC!:FILTERの結果が0件で、第3引数を指定していません。
  • #NAME?:FILTER・UNIQUE・HSTACKなどが使えないバージョンです。方法2を使ってください。
おすすめの記事