• ベストアンサー

A列と完全一致したセルとその右隣だけを残す

A列に10000行ほど、キーワードが記入されています。 B列~Q列にもキーワードが記入されていて、 そのB列~Q列内で、A列と完全一致したセルとその右隣だけを残す(他のセルは空欄にする) という風にしたいです。 例: A列 B列 C列 D列 E列 東京 東京 ラーメン 大阪 ケーキ 神奈川 岡山 お好み焼き 広島 イカ焼き 静岡 沖縄 そば 石川 パスタ 大阪 滋賀 コーヒー 大阪 たこ焼き ↓ A列 B列 C列 D列 E列 東京 東京 ラーメン 神奈川 静岡 大阪 大阪 たこ焼き このような形になるのが理想です。 これは、マクロでできるでしょうか? どのような記述でできますか? よろしくお願いいたします。

質問者が選んだベストアンサー

  • ベストアンサー
  • kkkkkm
  • ベストアンサー率65% (1624/2466)
回答No.10

東京の行に大阪とかあってもそれは削除されます、質問の例だと大阪 ケーキとかです。質問の結果がそうなっていますので。 そうではなく、東京なのに削除されるのでしたら可能性として A列かB列の対象文字列の前後に空白があるのかもしれません。 とりあえず以下のデータだけで試してみてください。 以下のデータをA1にコピペして「データ」の「区切り位置」で「カンマやタブなどの・・・」を選んで次の所で「,」にチェックをして完了するとAからQ列までデータが分かれます。F列とG列で東京東京と何かの間違いでダブる可能性がないとも限らないのと考えてわざとダブらせています。 東京,東京,1,東京,2,東京,東京,3,大阪,4,東京,5,東京,東京,6,東京,7 大阪と4だけが削除されたのでしたら空白が存在する可能性がありますので以下のコードで試してください。 一行ごと Sub testTrim() Dim i As Long, j As Long, k As Long, LastRow As Long Dim SCol As Long, ECol As Long Dim tmp1 As Variant, tmp2 As Variant LastRow = Cells(Rows.Count, "A").End(xlUp).Row SCol = Range("B1").Column ECol = Range("Q1").Column ReDim tmp2(ECol) For i = 1 To LastRow k = 0 tmp1 = Range(Cells(i, "A"), Cells(i, "Q")).Value tmp2(0) = tmp1(1, 1) For j = SCol To ECol If Trim(tmp1(1, 1)) = Trim(tmp1(1, j)) Then k = k + 1 tmp2(k) = tmp1(1, j) If j < ECol Then If Trim(tmp1(1, j + 1)) <> Trim(tmp1(1, 1)) Then k = k + 1: j = j + 1 tmp2(k) = tmp1(1, j) End If End If End If Next Cells(i, "A").Resize(1, ECol).Value = tmp2 ReDim tmp2(ECol) Next End Sub 最初にすべて Sub test2Trim() Dim i As Long, j As Long, k As Long, n As Long, LastRow As Long Dim SCol As Long, ECol As Long Dim tmp1 As Variant, tmp2 As Variant LastRow = Cells(Rows.Count, "A").End(xlUp).Row SCol = Range("B1").Column ECol = Range("Q1").Column ReDim tmp2(LastRow, ECol) tmp1 = Range(Cells(1, "A"), Cells(LastRow, "Q")).Value For i = 1 To LastRow k = 0 n = i - 1 tmp2(n, k) = tmp1(i, 1) For j = SCol To ECol If Trim(tmp1(i, 1)) = Trim(tmp1(i, j)) Then k = k + 1 tmp2(n, k) = tmp1(i, j) If j < ECol Then If Trim(tmp1(i, j + 1)) <> Trim(tmp1(i, 1)) Then k = k + 1: j = j + 1 tmp2(n, k) = tmp1(i, j) End If End If End If Next Next Cells(1, "A").Resize(LastRow, ECol).Value = tmp2 End Sub 英数文字や数字がある場合で全角と半角が混在している場合は Trim(tmp1(i, 1)) のように今回Trimで囲んだところを全て以下のように変更してください。 (それぞれのコードでIfの後ろ計4か所あります。両方で8カ所) StrConv(元のTrimで囲まれた部分,vbNarrow) 上記の場合だと以下のようになります StrConv(Trim(tmp1(i, 1)), vbNarrow)

mute_low
質問者

お礼

理想の形にできました。どうもありがとうございます。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (11)

  • kkkkkm
  • ベストアンサー率65% (1624/2466)
回答No.12

回答No.10の説明の訂正です。 > A列かB列の対象文字列の前後に空白があるのかもしれません。 A列かB列以降の対象文字列のどちらかの前後に空白がある、もしくは両方ともに空白にあるが数が違う、のかもしれません。

全文を見る
すると、全ての回答が全文表示されます。
  • msMike
  • ベストアンサー率20% (363/1775)
回答No.11

[No.9]の修正、 No.9 の式だけの訂正です。m(_._)m ×→_=IFERROR(INDEX(B2:N2,SMALL(IF($B2:$O2=$A8,COLUMN($B2:$O2)),1)-1),0)  ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄↓↓ ○→=IFERROR(INDEX(B2:$O2,SMALL(IF($B2:$O2=$A8,COLUMN($B2:$O2)),1)-1),0)

全文を見る
すると、全ての回答が全文表示されます。
  • msMike
  • ベストアンサー率20% (363/1775)
回答No.9

[No.8]の修正、 締め切られるのではアンメーかと慌てたもんで(詭弁です(*^_^*))で、呈示式の修正す。m(_._)m G/標準;; に書式設定し、かつ、式 =IFERROR(INDEX(B2:N2,SMALL(IF($B2:$O2=$A8,COLUMN($B2:$O2)),1)-1),0) を入力したセル B8 を右方(O列まで)&下方(11行目まで)にズズーッとオートフィルされたい。 【お断わり】上式は必ず配列(CSE)数式として入力のこと

全文を見る
すると、全ての回答が全文表示されます。
  • msMike
  • ベストアンサー率20% (363/1775)
回答No.8

マクロのオンパレードですが、哀しからずや、私ゃマクロ音痴なもんでスンマソンm(_._)m 添付図参照(Excel 2019)  ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄↓↓↓↓↓↓↓↓↓↓↓↓↓

全文を見る
すると、全ての回答が全文表示されます。
  • imogasi
  • ベストアンサー率27% (4737/17068)
回答No.7

タイプとして、検索の問題だと思う。 すると、VBAではFind,FindNext の利用が、まあ普通に出てくる発想かと思った。 Find法は、学習には、判り難い点もあると、日頃より思っている。 質問のデータ例が列がこのサイトでは崩れやすいので、本件はよく判らないでテストした面はある。 別シートにでもデータをコピペして、そちらをActiveSheetにして、テストしてください。 A列が検索語一覧。B-Q列にデータ。 Find法は処理スピードはそんなに速くないかも。でも1万行、10列ぐらいなら瞬く間に終わるだろう。 ーーーー 標準モジュールに Sub test01() Application.ScreenUpdating = False lr = Range("A10000").End(xlUp).Row MsgBox lr For i = 1 To lr x = Cells(i, "A") '検索語句設定 Set searchRng = Range("b1:Q10000") '検索範囲設定 '------------------------- '初出を検索 Set frng = searchRng.Find(what:=x, lookat:=xlWhole) If frng Is Nothing Then GoTo p1 fr = frng.Address frng.Offset(0, 1).Interior.ColorIndex = 4 ’該当セルの隣セルに色付け MsgBox fr '初めに見つかったセル番地 '------------------------ '2度目以降該当箇所探索 Set mycell = frng Do Set mycell = searchRng.FindNext(mycell) 'FindNext If mycell.Address = fr Then GoTo p1 MsgBox mycell.Address mycell.Offset(0, 1).Interior.ColorIndex = 4 ’’該当セルの隣セルに色付’ '初めて見つかったセルに、戻っていないか Loop While mycell.Address <> frng.Address 'Addressで比較 '------------------ p1: '次の語句の検索処理へ Next i Application.ScreenUpdating = True End Sub 'Findメソッドは検索範囲のなかで最初に見つけたセルを返します。 '一方、FindNextメソッドは、Findメソッドで見つけたセルの次から検索します。 '指定範囲をすべて検索し終えたら最初に戻ることに注意してください。 ================= 少数の勝手なデータでのテストなので充分でないかもしれない。 Msgbox の行は、少数のデータのテストデータ用なので、本番ではDebug.printに変えるか削除する。 データ抹消する本番では 該当以外をデータ抹消するなら、 VBA作業終了後、操作で、セルの書式で検索し、それ以外をデータを削除することになろう。 >他のセルは空欄にする どういうニーズなのか、理解できてないので、該当の方だけ色付けしたが、 検索語句の自体(A列以外の)語句セルデータも残すなら、もうセルの色付けのため、2行加える必要がある。 ーーー この反転作業を嫌うなら、「セル総なめ法」が有力かも。

全文を見る
すると、全ての回答が全文表示されます。
  • kkkkkm
  • ベストアンサー率65% (1624/2466)
回答No.6

回答No.4と回答No.5は間違っているやつをコピペしたようなので訂正です。 一行ずつ配列に読み込むやつ Sub test() Dim i As Long, j As Long, k As Long, LastRow As Long Dim SCol As Long, ECol As Long Dim tmp1 As Variant, tmp2 As Variant LastRow = Cells(Rows.Count, "A").End(xlUp).Row SCol = Range("B1").Column ECol = Range("Q1").Column ReDim tmp2(ECol) For i = 1 To LastRow k = 0 tmp1 = Range(Cells(i, "A"), Cells(i, "Q")).Value tmp2(0) = tmp1(1, 1) For j = SCol To ECol If tmp1(1, 1) = tmp1(1, j) Then k = k + 1 tmp2(k) = tmp1(1, j) If j < ECol Then If tmp1(1, j + 1) <> tmp1(1, 1) Then k = k + 1: j = j + 1 tmp2(k) = tmp1(1, j) End If End If End If Next Cells(i, "A").Resize(1, ECol).Value = tmp2 ReDim tmp2(ECol) Next End Sub 最初にすべて配列に読み込むやつ Sub test2() Dim i As Long, j As Long, k As Long, n As Long, LastRow As Long Dim SCol As Long, ECol As Long Dim tmp1 As Variant, tmp2 As Variant LastRow = Cells(Rows.Count, "A").End(xlUp).Row SCol = Range("B1").Column ECol = Range("Q1").Column ReDim tmp2(LastRow, ECol) tmp1 = Range(Cells(1, "A"), Cells(LastRow, "Q")).Value For i = 1 To LastRow k = 0 n = i - 1 tmp2(n, k) = tmp1(i, 1) For j = SCol To ECol If tmp1(i, 1) = tmp1(i, j) Then k = k + 1 tmp2(n, k) = tmp1(i, j) If j < ECol Then If tmp1(i, j + 1) <> tmp1(i, 1) Then k = k + 1: j = j + 1 tmp2(n, k) = tmp1(i, j) End If End If End If Next Next Cells(1, "A").Resize(LastRow, ECol).Value = tmp2 End Sub

mute_low
質問者

補足

回答ありがとうございます。 マクロを試してみましたが、なぜかB列以降が全削除となります。 何かExcelの設定などが必要なのでしょうか?

全文を見る
すると、全ての回答が全文表示されます。
  • kkkkkm
  • ベストアンサー率65% (1624/2466)
回答No.5

一行ずつだと遅いなと思う場合は、最初にすべて配列に読み込んで処理します。セルへの読み書きは最初に1回最後に1回の2回だけです。 Sub test2() Dim i As Long, j As Long, k As Long, n As Long, LastRow As Long Dim SCol As Long, ECol As Long Dim tmp1 As Variant, tmp2 As Variant LastRow = Cells(Rows.Count, "A").End(xlUp).Row SCol = Range("B1").Column ECol = Range("Q1").Column ReDim tmp2(LastRow, ECol) tmp1 = Range(Cells(1, "A"), Cells(LastRow, "Q")).Value For i = 1 To LastRow k = 0 n = i - 1 tmp2(n, k) = tmp1(i, 1) For j = SCol To ECol If tmp1(i, 1) = tmp1(i, j) Then k = k + 1 tmp2(n, k) = tmp1(i, j) If tmp2(n, k + 1) <> tmp1(i, 1) Then k = k + 1: j = j + 1 tmp2(n, k) = tmp1(i, j) End If End If Next Next Cells(1, "A").Resize(LastRow + 1, ECol + 1).Value = tmp2 End Sub

全文を見る
すると、全ての回答が全文表示されます。
  • kkkkkm
  • ベストアンサー率65% (1624/2466)
回答No.4

セルを一個一個読み込むのではなく一行ずつ配列に読み込んで処理して書き戻します。 Sub test() Dim i As Long, j As Long, k As Long, LastRow As Long Dim SCol As Long, ECol As Long Dim tmp1 As Variant, tmp2 As Variant LastRow = Cells(Rows.Count, "A").End(xlUp).Row SCol = Range("B1").Column ECol = Range("Q1").Column ReDim tmp2(ECol) For i = 1 To LastRow k = 0 tmp1 = Range(Cells(i, "A"), Cells(i, "Q")).Value tmp2(0) = tmp1(1, 1) For j = SCol To ECol If tmp1(1, 1) = tmp1(1, j) Then k = k + 1 tmp2(k) = tmp1(1, j) If tmp2(k + 1) <> tmp1(1, 1) Then k = k + 1: j = j + 1 tmp2(k) = tmp1(1, j) End If End If Next Cells(i, "A").Resize(1, ECol + 1).Value = tmp2 ReDim tmp2(ECol) Next End Sub

全文を見る
すると、全ての回答が全文表示されます。
  • kon555
  • ベストアンサー率52% (1761/3379)
回答No.3

 マクロというか、VBAでなら可能です。  ちょっと面白かったのでVBAで組んでみました。  もっとスマートなやり方もある気がしますが、一応動きます。多分10000行程度なら実用上問題ない時間で処理できるとは思います。 Sub サンプル() Dim i As Long, j As Long, k As Long Dim List() For i = 1 To Cells(Rows.Count, 1).End(xlUp).Row If Cells(i, 1) <> "" Then k = Cells(i, Columns.Count).End(xlToLeft).Column v = 0 ReDim List(k - 1) List(v) = Cells(i, 1) For s = 2 To Cells(i, Columns.Count).End(xlToLeft).Column If Cells(i, 1) = Cells(i, s) Then v = v + 1 List(v) = Cells(i, s) v = v + 1 List(v) = Cells(i, s + 1) End If Next s Range(Cells(i, 1), Cells(i, k)).Value = List End If Next i End Sub  記述としては、forと配列の組み合わせです。  WEB検索で出てくる内容で充分組める範囲なので、ご興味があれば勉強してみて下さい。

mute_low
質問者

補足

回答ありがとうございます。 マクロを試してみたら、なぜかB列以降が全削除になります。 これは何か別の設定などが必要でしょうか?

全文を見る
すると、全ての回答が全文表示されます。
回答No.2

B列~Q列内で、A列と完全一致したセルとその右隣のセル1個だけを残すのね。 作戦を同じシート内でのVBA(VBAを使う)とすると、for~next, cells, ifステートメントだけでできる。VBA抜きでやる方が大変で、見にくいような気がする。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • 【エクセル】2列間で、同じ組み合わせのものを抽出したい。

    A列には地名、B列にはお店が書いてあるような表で A列とB列の組み合わせが他の行でもあった場合それを表示しないよう にさせたいんです。 たとえば以下な表を、(A,B列は元から記入されています) │A   │B     │C│D│││││ 1│東京  │ラーメン屋│ │││││ 2│東京  │花屋    │ │││││ 3│神奈川│花屋    │ │││││ 4│東京  │ラーメン屋│ │││││ 5│神奈川│自転車屋 │ │││││ 6│埼玉  │ラーメン屋│ │││││ 7│神奈川│花屋     │ │││││ を・・ │A   │B      │C  │D │E│ 1│東京  │ラーメン屋│東京 │ラーメン屋│2│ 2│東京  │花屋    │東京 │花屋 │2│ 3│神奈川│花屋    │神奈川│花屋 │1│ 4│東京  │ラーメン屋│神奈川│自転車屋 │2│ 5│神奈川│自転車屋 │埼玉 │ラーメン屋│1│ 6│埼玉  │ラーメン屋│    │ │ │ 7│神奈川│自転車屋 │     │ │ │ というように、C列、D列、E列に、A,B列の元データで共に重複している 部分を表示させないようにするには、どうしたらよいでしょうか? ちなみに、マクロはなるべく使わず、関数で教えてもらえると有難いです。 よろしくお願いします。

  • A、B列でのセルの個数を出したい。

    excel2003を使用しており、 A列    B列 東京   Aさん 東京   Aさん 東京   Aさん 東京   Bさん 東京   Cさん 東京   Cさん 名古屋  Dさん 名古屋  Dさん 名古屋  Dさん 名古屋  Eさん 名古屋  Eさん 名古屋  Aさん 大阪   Fさん 大阪   Fさん 福岡   Gさん 福岡   Gさん 福岡   Hさん といった状態のセルがあます。 この中から、【東京には3人、名古屋3人、大阪には1人福岡2人】 という数値を返す関数が分らないのです。 条件として、A列の土地名の種類は今後は増えません。B列の人名は今後も増える予定です。また、上例の様に、Aさんが東京にも名古屋にも存在するっといった事があります。 色々、COUNT系の関数を調べながらやってみたんですがうまいこといきません。お力添え頂ければ幸いです。宜しくお願い致します。

  • 検索2列で一致した個数を表す関数

    エクセル2000にある表1を元に表2を作成しようとしています。 表1 A列:「都道府県」 B列:「市区町村」 C列:「フラグ」 表2 D列:「都道府県」 E列:「件数」 F列:「フラグ数」 表1は既に値が入っていて、ある条件を見たすとC列(フラグ)に"○"がつきます。レコード自体が増える可能性はありますが、増える場合は一番下の列に追加される形で増えます。 表2はD列は既に値(都道府県名)が入っていて変わることはありません。E列とF列を関数で制御したいと思っています。(マクロは使用不可) E列は表2のE列に一致するA列の個数 F列はEの個数の中でC列のフラグが"○"の個数です。 E列は「COUNTIF」で書けましたが、 F列の関数が分かりません。 分かる人がいましたら、教えて下さい。 よろしくお願いします。 <表1>   A列   B列    C列   都道府県 市区町村  フラグ   --------------------------- 1 東京都   新宿区 ○ 2 東京都   豊島区 3 東京都   渋谷区 4 神奈川県  横浜市  ○ 5 神奈川県  厚木市  ○ <表2>   D列   E列    F列   都道府県 件数   フラグ数   ----------------------------- 1 東京都  3     1 2 神奈川県 2     2

  • 列ごとの数値の一致と不一致を調べるVBAについて

    画像のように各列ごとにランダムな数値が入力されています。この時に各列ごとに同じ数値が入っているかいないかを調べたいのですが、どのようにプログラムを作ればいいかわからなく質問しました。 画像の内容としては、列Aのセル中の数値と列Bのセル中の数値は一致しないのでB15セルに"1" 列Aのセル中の数値と列Cのセル中の数値は『66』が一致するのでC15セルには何も入力せず というように D15セルは列Aと列Dの一致、不一致の結果 C16セルは列Bと列Cの一致、不一致の結果 D16セルは列Bと列Dの一致、不一致の結果 D17セルは列Cと列Dの一致、不一致の結果 を入力できるプログラムがあれば教えていただければ幸いです。よろしくお願いします。

  • Excelのセルをコピペして、Google検索をす

    ExcelのA列にキーワードが記入されています。  A列 1 東京 2 大阪 3 静岡 4 福岡 このA列の1~4を選択してコピペ。 コピペした1~4を↓という風に、Google検索したいです。 Google検索 東京(タブ1)|大阪(タブ2)|静岡(タブ3)|福岡(タブ4) 「Pasty」というGoogleChromeのエクステンションがあり、 それは、URLをコピペして、Google検索できるというものです。 Pastyのキーワード版で、同じようなことをしたいと思っています。 Excelのハイパーリンクで同じようなことができますが、 一つずつしかできませんし、いくつかやってると規制?で止まります。 A列にあるキーワードを効率良く、 タブで分けて、Google検索していきたいです。 Excelの式や機能、エクステンション、ツール・ソフトとかで、 Excelのセルをコピペして、Google検索をすることはできますでしょうか? できるとしたら、どのような方法がありますでしょうか? 教えていただけたら、嬉しいです。 Excel2016を使っています。 よろしくお願いいたします。

  • エクセル ピボットテーブルで同一列内の同じ文字を抽出

    マクロを使い、ピボットテーブル上でA列の任意の文字をクリックすると、 A列を検索して同じ文字があれば抽出した行を反転?(青くなる奴です)したいです。   A    B    C  ・・・ 1 大阪  50 2 静岡  15 3 東京  33 4 大阪  14 5 大阪  05 6 東京  88 この場合、セルA5の"大阪"をクリックするとA列の1行目と4,5行目の"大阪"の文字をキーワードに、1・4・5行を反転させたいのですが可能でしょうか? 当方エクセル、VBAともに初心者です。よろしくお願いします。 補足 A6セルをクリック(A6セルの上にカーソルがある状態)すれば3・6行を反転という事です。

  • Excel データを部分一致で抽出して表示したい (関数 または VBA)

    まずは下のサンプルデータを見ながら本文を読んでください。 Excelの関数(lookup か vlookup) か VBAを利用して、 Sheet2のセルA列にデータを自動的に表示したい と思っています。 Sheet2のセルA列に表示したいデータは、Sheet1のセルAの情報です。 例えば、Sheet2のセルB1が「静岡県」の場合は、「営業2部」という文字が Sheet2のセルA1に表示されるようにしたいと思っています。 つまり、Sheet1のセルB が Sheet2のセルB の内容と 部分一致した場合に、Sheet2のセルA列に 該当データ(Sheet1のセルA)を 抽出して表示するということをやりたいと考えています。 どうぞよろしくお願い致します。 サンプルデータ ◆Sheet1 参照元となる表 ___|___セルA___|________セルB ---------------------------- 1 | 営業1部 | 東京都千代田区 ---------------------------- 2 | 営業2部 | 静岡県 ---------------------------- 3 | 営業2部 | 山梨県 ---------------------------- 4 | 営業3部 | 東京都渋谷区 ---------------------------- 5 | 流通1部 | 神奈川県 ---------------------------- ◆Sheet2 データを埋めたい表 ___|____セルA_____|_______セルB ---------------------------- 1 |________________| 静岡県富士市大淵 24 ---------------------------- 2 |________________| 東京都千代田区丸の内1-8 ---------------------------- 3 |________________| 大阪府大阪市中央区南船場1―15 ---------------------------- 4 |________________| 神奈川県横浜市 ---------------------------- 5 |________________| ※以下 セルBには500件ほどの都道府県データあり。 6 7 ・ ・

  • 関数で、最大値のあるセルの列を表示したい

    エクセルの関数について教えてください。 セルH1に関数を使って、列A、列C、列E、列Gの最大値を出しました。 その下のH2のセルに、関数を使って、列A、列C、列E、列Fの最大値のある列(A,B,C,Dのいずれか)を表記させたいのですが(下記のように)、可能でしょうか?   A B C D E F G H 1 10 ※ 28 ※ 66 ※ 26 99 2 56 ※ 29 ※ 89 ※ 28 A 3 99 ※ 12 ※ 66 ※ 10 (列Hが上記のようになるようにしたいのです。)

  • Excel HLOOKUPで一致したセルの列番号

    Excelの関数で、HLOOKUPの関数を使うと セルの値が出てきますが、値ではなくセル番地(列番号)を表示する方法はないでしょうか。 以下のようにシート(SHEET1)を作成しました。  |A  | B | C | D | E | ――――――――――――――――――――― 1|日付 | Bさん   | Aさん   | ――――――――――――――――――――― 2|4/1|   |   |早退 |1.0| 3|4/2|遅刻|1.0|   |   | 4|4/3|   |   |遅刻 |0.5| 他のシートに”Aさん”のそれぞれの集計を 出すように関数(SUMIF)を作成したのですが、 どうしても列番号が必要? 関数またはVBAでなにかよい方法はないでしょうか。

  • EXCEL○印を付けるとその列の最上セルを引用する

    進捗   A  B  C  D  E  F  D A     ○ E              ○ B        ○ という様に、○印を付けるとその列の最上セルの表示を 第一列(進捗)のその行に 引っ張ってくる様にしたい。

専門家に質問してみよう