プロが教えるわが家の防犯対策術!

A列    B列    C列
りんご  りんご 
みかん  みかん 
もも   もも 
バナナ 
ライチ  

という表があるとします。
C列にA列とB列で重複しないデータ(バナナとライチ)を関数などで簡単に表示させる方法はありますか?
つまりA列にデータを貼り付けたら、毎回自動的にC列に重複しないデータが抽出されるようなフォーマットを作りたいです。

毎月同じ形式の売上表を各支店ごとに20個程作っているのですが、
毎回A列とB列を別シートに一列に並べて条件付き書式で重複データを色付け→重複しないセルをフィルターで抽出→抽出したデータをC列に貼付け、という作業を何回も繰り返し膨大な時間がかかっています・・。
ちなみにExcelを仕事で使い始めて4か月、マクロとかVBA?は使ったことがありません。
一から勉強するには時間がかかりそうなので、今月からすぐにでも使えそうな方法を探しています。
よろしくお願いします。

A 回答 (5件)

#2です。

コメント拝見しました。
ちょっと改造したうえで、説明用のコメントを追加しています。
前回同様、1行目は見出し行と考えています。
最後の吐き出し先はC列のままとしていますが、適宜いじってください。
B、C、K列の列番号は、それぞれ、2、3、11です。

'---------------------------------------------------------------------------
Option Explicit

Sub 非重複抽出()

'変数宣言とセット
Dim r As Long, k As Long, myStr As String
Dim Dic As Object, myKeys As Variant
Dim WSF As Object, Lstrow As Long

Set Dic = CreateObject("Scripting.Dictionary")
Set WSF = Application.WorksheetFunction

'B列K列のデータから非重複のリストを作成

r = 2 '2行目から下に、B列を見に行き、初めて出てきた品名をDicに格納
Do While Cells(r, 2).Value <> "" 'B列(列番2)
 myStr = Cells(r, 2).Value    'B列(列番2)
 If Not Dic.Exists(myStr) Then
  Dic.Add myStr, myStr
 End If
 r = r + 1
Loop

r = 2 '2行目から下に、K列を見に行き、初めて出てきた品名をDicに格納
Do While Cells(r, 11).Value <> "" 'K列(列番11)
 myStr = Cells(r, 11).Value
 If Not Dic.Exists(myStr) Then
  Dic.Add myStr, myStr
 End If
 r = r + 1
Loop

myKeys = Dic.Keys '出来上がったDicの結果を、配列 myKeysとする

'配列 myKeysを順に見ていき、その中から、B列またはK列にしか存在しないものを列記(BK両方にあるものは無視)

For k = 0 To UBound(myKeys) 'myKeysの値をすべてループ
'CountIf関数を用いて、B列(列番2)の個数が0 または、K列(列番11)の個数が0ならば転記(それ以外はスルー)
 If WSF.CountIf(Columns(2), myKeys(k)) = 0 Or WSF.CountIf(Columns(11), myKeys(k)) = 0 Then
  Lstrow = Cells(Rows.Count, 3).End(xlUp).Row + 1 '転記先はC列(列番3)
  Cells(Lstrow, 3).Value = myKeys(k) 'C列(列番3)
 End If
Next k

Set Dic = Nothing
Set WSF = Nothing

MsgBox "End."

End Sub
'-----------------------------------------------------

このマクロを実行するには、先の回答通り、Alt+F8 から行ってください。

あるいは、ボタンに登録したほうが楽かもしれません。念のため登録方法は以下。

1)エクセル上部のリボンから「開発」タブを選択
 「開発」が出ていない場合は、ファイル>オプション>リボンのユーザー設定>右半分の「メインタブ」のところで「開発」にチェック

2)「挿入」ボタン。道具箱にトンカチとスパナがクロスした絵のやつ。
3)フォームコントロール。左上の「ボタン」をクリックし、シート上で適当な大きさにするようドラッグ
4)マクロの登録 となりますので、「非重複抽出」を登録すればOK
ボタン名が「ボタン1」などとイケていないので、ボタンの上で右クリック、「ボタン1」のあたりで左クリックすれば変更可能。

ホントは、C列の前回結果を消去するフローも入れたほうがより楽でしょうが、詳細が分からないので対応していません。
学習がてら適宜対応ください。
    • good
    • 0
この回答へのお礼

助かりました

お礼が遅くなりました。
いただいた情報をもとにただいま勉強中です。
ご丁寧にありがとうございました!

お礼日時:2016/01/17 20:15

No.3です。



>実際のフォーマットはそれぞれ文字列がA列が2行目から、B列が3行目から、表示させたいC列も4行目から・・という風にばらばらです

というコトですので↓の画像のような感じだとします。
要するにINDEX関数の範囲(配列)の何番目のデータを表示させるか?
という行合わせだけの問題になります。

画像ではC4セル(数式を入れるセルはどこでも構いません)に
=INDEX(A$2:A$1000,SMALL(IF(COUNTIF(B$2:B$1000,A$2:A$1000)=0,ROW(A$2:A$1000)-1),ROW(A1)))&""
という配列数式にし、フィルハンドルで下へコピーしています。

※ 配列数式の操作方法は前回同様です。

※ これでもわかりにくい場合は
VBAで処理する方が簡単かもしれません。
必要であれば、補足にでも書いてください。m(_ _)m
「離れた2列を比べて重複しないデータを隣の」の回答画像4
    • good
    • 0
この回答へのお礼

助かりました

お礼が遅くなりました。
いただいた情報をもとに色々試しております。
ありがとうございました!!

お礼日時:2016/01/17 20:16

こんばんは!



一例です。
データは1行目からあるとします。
C1セルに
=INDEX(A$1:A$1000,SMALL(IF(COUNTIF(B$1:B$1000,A$1:A$1000)=0,ROW(A$1:A$1000)),ROW(A1)))&""
配列数式ですので、Ctrl+Shift+Enterで確定!
この画面からコピー&ペーストする場合は
上記数式をドラッグ&コピー → C1セルを選択 → 数式バー内に貼り付け → そのまま(編集可能なまま)
Ctrl+Shiftキーを押しながらEnterキーで確定!
数式の前後に{ }マークが入り配列数式になります。
C1セルのフィルハンドルで下へコピー!
こんな感じではどうでしょうか?

※ 文字列限定としています。
(数値データの場合は文字列として表示されます)
※ 極端にデータ量が多い場合は配列数式はPCにかなりの負担をかけ、計算速度が落ちます。
作業用の列を設けたりする方法が良いかもしれません。m(_ _)m
    • good
    • 0
この回答へのお礼

ご丁寧にありがとうございます!
配列数式という存在を始めて知りました!
今早速やってみているのですが、
実際のフォーマットはそれぞれ文字列がA列が2行目から、B列が3行目から、表示させたいC列も4行目から・・という風にばらばらです。
(表が全シートこの位置に貼り付いていて、数式が入ってるのでずらすのが怖いです・・)
その状態でも可能でしょうか??
上記の数式をコピペして、A$1をA$2とかに置き換えてやってみたのですが、うまくいきません。
ABC3列とも1行目から文字列が始まるように調整するしかないでしょうか・・

お礼日時:2016/01/03 11:29

ご意向にはそぐわないのかもしれませんが、質問カテゴリがここでもあるので、VBAを使う方法を


一つ。

以下を前提にしています。
・一番上の行(1行目)は見出しと考えています。
・A2から下にデータ、B2から下に比較対象のデータがある。
・C2から下に、A,Bで重複しないデータを並べる

すぐにでも使える、ということから、詳細の説明は省きますが、以下の流れでどうぞ。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

【1】そのエクセルファイル上で、Alt+F11 を押す。
  別の画面が開きます。(Visual Basic Editor。以下VBE)

【2】VBE画面上で、Alt + I 、M
  真っ白の画面となります。

【3】以下をコピペ
'-----------------------------------------------------
Option Explicit

Sub 非重複抽出()

'変数宣言とセット
Dim r As Long, k As Long, myStr As String
Dim Dic As Object, myKeys As Variant
Dim Rng As Range, Sel As Range
Dim WSF As Object, Lstrow As Long

Set Rng = Cells(1, 1).CurrentRegion
Set Rng = Rng.Offset(1, 0).Resize(Rng.Rows.Count, 2)

'A列B列のデータから非重複のリストを作成
Set Dic = CreateObject("Scripting.Dictionary")
For Each Sel In Rng
 If Not Dic.exists(Sel.Value) And Sel.Value <> "" Then
  Dic.Add Sel.Value, Sel.Value
 End If
Next Sel
myKeys = Dic.Keys

'非重複リストの中から、A列またはB列にしか存在しないものを列記(AB両方にあるものは無視)
Set WSF = Application.WorksheetFunction
For k = 0 To UBound(myKeys)
 If WSF.CountIf(Columns(1), myKeys(k)) =0 Or WSF.CountIf(Columns(2), myKeys(k)) = 0 Then
  Lstrow = Cells(Rows.Count, 3).End(xlUp).Row + 1
  Cells(Lstrow, 3).Value = myKeys(k)
 End If
Next k

Set Dic = Nothing
Set Rng = Nothing
Set WSF = Nothing

MsgBox "End."

End Sub
'-----------------------------------------------------

【4】VBE画面を閉じる

【5】A列、B列に必要なデータを入れる

【6】Alt+F8 でボックスを表示させ、今仕込んだマクロ(非重複抽出)を実行。


・【1】~【4】は今回だけの作業。
 実際には、【5】~【6】だけ。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

とりあえず、わたしの手元のダミーデータではうまく作動しました。
ご参考までお願いします。
    • good
    • 0
この回答へのお礼

すごい!!ありがとうございます。
意味を解読するには時間がかかりそうなので、これを他の色んな表でコピペして使うとして、今後参照する列を変えたい場合(今作業している表でいうとB列K列のデータから非重複のリストを作成、'非重複リストの中から、B列またはK列にしか存在しないものを列記(BK両方にあるものは無視)にしたい)にどの部分を変えたらいいのか教えていただけないでしょうか??

この方法も試してみたいです!!

お礼日時:2016/01/03 15:41

B列のデータの順番が、もも・りんご・みかん の順になってた場合も、C列は同じですか?

    • good
    • 0
この回答へのお礼

同じです!

お礼日時:2016/01/01 21:41

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています