• ベストアンサー

エクセルのセル内の重複文字列処理について

よろしくお願いいたします。 セル内にスペースで区切られた文字列(単語)があり、文字列の数は不確定です。 その文字列の中で重複する文字列があり、それらを1つにまとめたいという要望です。 セルの行数は約6000ほどあります。 例 A1セル:リンゴ リンゴ みかん B1セル:リンゴ みかん A2セル:みかん バナナ みかん バナナ みかん B2セル:みかん バナナ ・・・ よろしくお願いいたします。 Windows7 HomePremium Office2010

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

  • ベストアンサー
  • tom04
  • ベストアンサー率49% (2537/5117)
回答No.2

こんばんは! VBAになってしまいますが、一例です。 データは1行目からあるとします。 画面左下の操作したいSheet見出し上で右クリック → コードの表示 → VBE画面に ↓のコードをコピー&ペーストしてマクロを実行してみてください。 (Alt+F8キー → マクロ → マクロ実行です) Sub test() 'この行から Dim i As Long Dim k As Long Dim tmp As Variant Dim myArray As Variant Application.ScreenUpdating = False Columns(2).ClearContents For i = 1 To Cells(Rows.Count, 1).End(xlUp).Row tmp = WorksheetFunction.Substitute(Cells(i, 1), " ", " ") If InStr(tmp, " ") > 0 Then myArray = Split(tmp, " ") For k = 0 To UBound(myArray) If InStr(Cells(i, 2), myArray(k)) = 0 Then Cells(i, 2) = Cells(i, 2) & myArray(k) & " " End If Next k Else Cells(i, 2) = Cells(i, 1) End If Next i Application.ScreenUpdating = True End Sub 'この行まで こんな感じではどうでしょうか?m(_ _)m

dagajamaja
質問者

お礼

いつもありがとうございます。 不具合なく実装することができました。 ありがとうございました。 お礼が遅くなり申し訳ございませんでした。

その他の回答 (7)

  • cj_mover
  • ベストアンサー率76% (292/381)
回答No.8

こんにちは。お邪魔します。   <元データ ダミーサンプル> A列 ■みかん   りんご  バナナ  りんご みかん ■ ■夏みかん みかん みかん箱  ミカン みかん  'ミカン' りんご酢 りんご 青りんご リンゴ バナナ ■ ■  バナナ みかん りんご ばなな ばなな園 みかん缶詰 モンキーバナナ■ ■  ■ ■■ ■みかん■   <結果> B列 ■みかん りんご バナナ■ ■夏みかん みかん みかん箱 りんご酢 りんご 青りんご バナナ■ ■バナナ みかん りんご ばなな園 みかん缶詰 モンキーバナナ■ ■■ ■■ ■みかん■ (※ ■ は、外縁。■■ は、値無し。'ミカン' は、半角「ミカン」の意。) ↑こんな感じのサンプル、100,000行で試しながらマクロ書いてみました。 (仕様的には#3さんのと似ているかと。) 目視でチェックできない文末のスペースとか、スペースの連続とか、全半角の誤入力とか、 ありがちなNGに(多少)対処していたりもしますが、 行数が多いようなので、なるべく軽く速く処理できるように書きました。 ただ、求める結果がこれで良いかどうかは質問者さんにしか解りませんね。  1◆ [全角|半角] [大文字|小文字] ([かな|カナ])  2◆ [部分一致|完全一致]  3◆ 区切り文字(スペース)が連続した場合の処理 Excelの一般機能でも普通に確認を求めてくるような条件付けを 質問文なり補足欄なりで指定した方が ニーズにピッタリあった回答が得られやすいと思いますよ。 この手の質問って、不調に終わること多いですけれど 勘を頼りに独自の解釈で答えをつけて、ニーズと違ってたり、 なんであれ汎用的に応えようとして 必要以上に煩雑だったり、難しすぎると毛嫌いされたり、それでも不足があったり、、、 もう少し対話的にできればいいのになぁと思ってしまいます。 できれば、提示された方法を一度は試してみて欲しいです。 数が多いと大変なのは解るのですけどね。 一応、何か補足をする場合の介けにでもなればと、以上書いてみました。 ' ' ==================新規の標準モジュール================== ' ' ======================================================== Option Explicit Option Compare Text ' ' ======================================================== Sub Re7810353L()   Const nTop As Long = 1   Dim mtxS   Dim mtxP   Dim nBtm As Long   Dim nYSize As Long   Dim i As Long   nBtm = Cells(Rows.Count, 1).End(xlUp).Row   nYSize = nBtm - nTop + 1   mtxS = Range("A" & nTop & ":A" & nBtm).Value   ReDim mtxP(1 To nYSize, 1 To 1)   For i = 1 To nYSize     mtxP(i, 1) = fLtdTxtUniqFilter(mtxS(i, 1))   Next i   Application.ScreenUpdating = False   With Range("B" & nTop & ":B" & nBtm)     .Value = Empty     .Value = mtxP   End With End Sub ' ' -------------------------------------------------------- Function fLtdTxtUniqFilter(ByVal S As String, Optional ByVal D As String = " ") As String   Dim sPr As String   Dim nLn As Long   Dim nSP As Long   Dim nPP As Long   Dim nPL As Long '  If Len(D) <> 1 Then Exit Function   nLn = Len(S) + 2   sPr = String$(nLn, D)   S = D & S & D   nSP = 2&   nPP = 2&   Do     nPL = InStr(nSP, S, D) - nSP     If nPL > 0 Then       If InStrRev(sPr, Mid$(S, nSP - 1&, nPL + 2&), nPP) = 0 Then         Mid(sPr, nPP) = Mid$(S, nSP, nPL)         nPP = nPP + nPL + 1&       End If     End If     nSP = nSP + nPL + 1&   Loop While nSP < nLn   If nPP < 3& Then Exit Function   fLtdTxtUniqFilter = Mid$(sPr, 2, nPP - 3&) End Function ' ' ========================================================

dagajamaja
質問者

お礼

ご対応ありがとうございます。 希望通りの答えが得られることができました。 補足のつけ方がわからず、余計に時間を取らせてしまったかもしれません。 質問の仕方ももう少し詳しくできるよう努力いたします。 ありがとうございました。

  • keithin
  • ベストアンサー率66% (5278/7940)
回答No.7

ALT+F11を押す 現れた画面で挿入メニューから標準モジュールを挿入する 現れたシートに下記をコピー貼り付ける sub macro1()  dim a, myDic, x  dim h As Range  set myDic = createobject("Scripting.Dictionary")  on error resume next  range("B:B").clearcontents  for each h in range("A1:A" & range("A65536").end(xlUp).row)   a = split(replace(h, " ", " "), " ")   for each x in a    mydic.add x, ""   next   h.offset(0, 1) = join(mydic.keys, " ")   mydic.removeAll  next end sub ファイルメニューから終了してエクセルに戻る A列に元データを配置、ALT+F8を押しマクロを実行して完成。

回答No.6

「区切り位置」と「統合」という一般機能を組み合わせた簡単な方法をご紹介します。 文章で説明すると長くてたいへんそうですが、実際はアッと言う間に終わると思います。 (1) A 列と B 列の間に十分な数の列を挿入してください。具体的には、A 列に入力されている最大の単語数よりも多い列数を空けます。そうしておかないと、次の「区切り位置」を完了する際に、B 列のデータを上書きしてしまうとの警告が出ます。 (2) A 列全体を選択した状態で、リボン「データ」の「区切り位置」ウィザードを起動。「カンマやタブなどの…」を指定し、「次へ」。「スペース」にチェックを入れ、「完了」。1 セルに入力されていた複数の単語が複数のセルに分割されます。 (3) 旧 B 列に対して(2)と同じ処理をします。 (4) 新しくできた A 列、B 列、C 列、…の右隣にそれぞれ 1 列ずつ挿入された状態にします。 (5) 列を挿入後の B1 セルに好きな数字を入力します。 (6) (5)までに作成されている一覧の外にあるどこかのセル(添付図では A7)をクリックします。この位置に、次の「統合」による結果が入力されます。 (7) リボン「データ」の「統合」ダイアログを起動。「統合元範囲」として「$A$1:$B$4」、「$C$1:$D$4」などを記入し、それぞれを「追加」ボタンで「統合元」一覧に加えていきます。この記入の作業はマウスのドラッグでできるのですが、6,000 行と量が多いなら、適当な行数の範囲をドラッグしておいて、行番号だけタイプして 6000 に書き換えるとラクでしょう。最後に「左端列」にチェックを入れて OK すれば、でき上がり。

dagajamaja
質問者

お礼

画像まで張っていただきありがとうございます。 思った通りの結果になりました。 ありがとうございます。 応用をもう少し勉強したいと思います。

  • KURUMITO
  • ベストアンサー率42% (1835/4283)
回答No.5

回答No1です。 シート2のU1セルに入力する式はあまりにも力技といった感じですので、シート2でのK1セルへの入力する式を、K1セルを空にしてL1セルに入力しU1セルまでドラッグコピーします。 =IF(COUNTIF($A1:A1,A1)=1,TRIM(K1&" "&A1),K1) シート2のU列を選択してコピーし、シート1のB1セルに貼り付けをすればよいでしょう。 マクロを使って処理するよりも計算に負担がかからないでしょう。

dagajamaja
質問者

お礼

なるほどこういうやり方もあるのですね。 ありがとうございます。 お礼が遅れて申し訳ございませんでした。

  • kagakusuki
  • ベストアンサー率51% (2610/5101)
回答No.4

 毎回、コピー&ペーストやボタンのクリック等の手動損さを行わずとも、関数と作業シートを使用して全自動で行う事が出来る方法です。  今仮に、A列に元データが入力されているシートがSheet1であり、Sheet2を作業シートとして使用するものとします。  まず、Sheet2のA1セルに次の関数を入力して下さい。 =IF(INDEX(Sheet3!$A:$A,ROW())="",""," "&SUBSTITUTE(TRIM(SUBSTITUTE(INDEX(Sheet3!$A:$A,ROW())," "," "))," "," ")&" ")  ※「ROW()),」の直後にある" "内の空白は全角の空白1文字、「)&」の直前にある" "内の空白は半角の空白2文字ですから、間違わないよう注意して下さい。  次に、Sheet2のB1セルに次の関数を入力して下さい。 =IF(OR(A1="",A1=CHAR(160)),"",IF(ISNUMBER(FIND(" ",A1,2)),SUBSTITUTE(A1,LEFT(A1,FIND(" ",A1,2)),)&CHAR(1)&TRIM(LEFT(A1,FIND(" ",A1,2))),CHAR(160)))  次に、Sheet2のB1セルをコピーして、「Sheet1のA列の1つのセル内に、存在している単語の"種類の"数」を2つ以上上回るのに十分な列数となるまで、Sheet2のB1よりも右にあるセル範囲に貼り付けて下さい。  次に、Sheet2の1行目全体をコピーして、2行目以下に貼り付けて下さい。  次に、Sheet1のB1セルに次の関数を入力して下さい。 =IF(INDEX($A:$A,ROW())="","",TRIM(SUBSTITUTE(INDEX('Sheet3 (2)'!1:1,MATCH(CHAR(160),'Sheet3 (2)'!1:1,0)-1),CHAR(1)," ")))  次に、Sheet1のB1セルをコピーして、Sheet1のB2以下に貼り付けて下さい。  これで、Sheet1のA列のセルに元データを入力するだけで、Sheet1のB列のセルに重複する単語を1個だけ残して削除した文字列が、自動的に表示されます。

dagajamaja
質問者

お礼

ありがとうございます。 結構簡単にできました。 もっと勉強します!

回答No.3

こんばんは。 VBAの古いアルゴリズムですが、ユニーク抽出の解決方法があります。 関数の方法もあるのかもしれませんが、どのみち、配列を使うのでしたら、6000行では無理でしょうから、VBAの解決に軍配が上がるかもしれません。なお、食事前に即席で作ったものですので、バグが残っているかもしれません。(スペックとしては同じ環境です) たぶん、スペースは全角でも半角でも、また、スペースが複数でも、処理出来るはずです。 標準モジュールに貼り付けてください。 '// Sub UniqSelect()  'ユニークなデータを抽出する  Dim c As Variant  Dim a As Variant  Dim k As Variant  Application.ScreenUpdating = False  For Each c In Range("A1", Cells(Rows.Count, 1).End(xlUp))   a = Trim(c.Value)   If InStr(1, a, " ", 1) > 0 And a <> "" Then    Do     a = Replace(a, Space(2), Space(1), , , vbTextCompare)    Loop Until InStr(1, a, Space(2), 1) = 0    a = Split(a, Space(1), , 1)    k = UniqData(a)    c.Offset(, 1).Value = Join(k, Space(1))   Else    c.Offset(, 1).Value = a   End If   a = ""  Next c  Application.ScreenUpdating = True End Sub Function UniqData(myData As Variant) Dim Ub As Long Dim i As Long, j As Long Dim k As Long, m As Long, o As Long Dim S As Long Dim Flg As Boolean Dim a()   Ub = UBound(myData)   ReDim a(0 To Ub)  For j = 0 To Ub    a(0) = myData(0)    Flg = True 'sentinel    For m = 0 To S      If a(m) = myData(j) Then       Flg = False       Exit For      End If    Next m    If Flg = True Then      S = S + 1      a(S) = myData(j)    End If   Next j   For o = 0 To Ub    If a(o) = Empty Then      Exit For    End If   Next o   ReDim Preserve a(0 To o - 1)   UniqData = a End Function

dagajamaja
質問者

お礼

お礼が遅れて申し訳ございませんでした。 こちらも要望通りの答えを得ることができました。 ありがとうございます。 朝飯前ならぬお食事前ですごいですね。

  • KURUMITO
  • ベストアンサー率42% (1835/4283)
回答No.1

行数が6000とかなりのデータ数ですので複雑な式を使って作業すれば計算にも負担がかかります。 作業シートを別に用意して対応するのがよいでしょう。 ご質問のデータがシート1のA列にあるとします。単語の数が仮に10までに対応できる方法です。勿論それ以上でも可能です。 シート1のA列をコピーしてシート2のA1セルを選択して貼り付けます。 その後にシート2のA列を選択してから「データ」タブの「区切り位置」で「カンマやタブの区切り文字によって…」を選択し、「次へ」をクリック、「スペース」にチェックをして「次へ」「完了」と進みます。 A列に合った文字列がスペースごとに個々の列に表示されます。 シート2のK1セルには次の式を入力してT1セルまでドラッグコピーしたのちに下方にもドラッグコピーします。 =IF(COUNTIF($A1:A1,A1)=1,A1,"") 重なりのない形で文字列が表示されます。 シート2のU1セルには次の式を入力して下方にドラッグコピーします。 =K1&" "&L1&" "&M1&" "&N1&" "&O1&" "&P1&" "&Q1&" "&R1&" "&S1&" "&T1 このデータをシート1のB列に貼り付けをすればよいでしょう。 あるいはシート1のB1セルには次の式を入力して下方にドラッグコピーすれば完成です。 =Sheet2!U1

dagajamaja
質問者

お礼

早々にご回答いただきありがとうございました。 確認させていただきました。 手数が多くなってしまうのを解消できればと思いました。 しかしながらご検討いただきありがとうございました。

関連するQ&A

  • セル内の文字列に複雑な処理をしたい

    セルの中の複数の異なる文字列を以下のように処理したいのですが、Excelの標準の文字列操作の関数で試行錯誤してみたのですが、どうもうまくできませんでしたので、ご存知の方がいらっしゃいましたらご教授ください。VBAで処理しないとできないかもしれませんがよろしくお願いします。 あるリストのC列に備考欄が設けてあり、次のようなデータが入っています。 4/30 みかんを買った(強制改行して) 5/1 りんごを売った 5/2 ぶどうを食べた 5/5 すいかを買った このセルを調べて、 (1) セル内に"みかん"と"りんご"という文字列があったら、これを取り出して、右隣のセルに表示           (結果)⇒ みかん りんご (2) セル内に"みかん"と"りんご"という文字列があったら、これを"A","B"に置き換えて、右隣のセルに表示          (結果)⇒ A B (3) セル内の数値データと"を食べた"、"を買った"、"を売った"を取り除いて、右隣のセルに表示          (結果) ⇒ みかん りんご ぶどう すいか   (4) セル内に"か"を含む文字列があったら個数に関係なく"A"に置換して右隣のセルに表示             (結果) ⇒ A   すべて取り出したい文字列(上の例ではみかん、りんご)や置換したい文字列(A、B)以外の文字列は全てクリアして表示しないようにします。少し複雑ですが、やり方をご存知の方がいらっしゃいましたら、お教えください。

  • 一番初めに文字列が入っている列の文字列を知りたい

    次の条件で、よりA列に近い文字列を引っ張り出すにはどのような関数を使えば良いのでしょうか? 1)行の中にそれぞれ"文字列"が入っている 2)文字列が入っているセル数は行によって異なる   【A】 【B】 【C】 【D】 【E】 【1】りんご 【2】   ばなな 【3】   みかん りんご 【4】ばなな           みかん この回答を【F】列に示す場合、 【F1】はりんご、【F2】はばな、【F3】はみかん、【F4】はばなな、になって欲しいのです。 上手く質問できないのですが、とても困っています。宜しくお願いします。

  • Excelでの文字列とりだしについて

    Excel(version2013)について質問です。 ある文字列を検索範囲内で検索し、みつかった場合、 その文字列を返すようにしたいです、どのような関数を使えば宜しいでしょうか。 例えば下記A列に検索したいリスト(りんご、ばなな、ぶどう)があり、 検索したい範囲がD1~E5とします。 その場合、B列に関数を使った式を入れ、 りんご、ばなな、空文字、りんご、ぶどうと並ぶようにしたいです。 どのような関数を使えば宜しいでしょうか。       A         B      C      D        E 1  りんご   (式)        りんご  みかん 2  ばなな  (式)        ばなな すいか 3  ぶどう   (式)        すいか みかん 4              (式)        りんご  すいか      5              (式)        ぶどう  みかん                                      

  • エクセル重複セルについて

    例えば    A   B 1  品名 数量 2 みかん  2 3 りんご  2 4 みかん  1 5 いちご  1 6 りんご  1  とあるとして、 他のセルに    C   D 1  品名  個数 2  みかん  3 3  りんご  3 4  いちご  1  のように 重複セルを削除し、なおかつ 個数もまとめるというようなことは エクセルでできないでしょうか? 宜しくお願いします。

  • EXCELで重複する値の検索

    EXCELで重複する値を検索して、かつその重複した値と同じ行の隣のセルの値を返すということをしたいのですが、どうすればうまくいきますでしょうか。 具体的には下記のようになります。    A    B   C 1 りんご  A市場 2 みかん  C市場 3 りんご  D市場 4 なし   B市場 5 バナナ  A市場 6 りんご  F市場 上のような表があったとして、A列の重複を検索(この場合はりんごが重複)して、重複した場合はB列の値をC列に返すことをしたいんです。 希望する出力は以下のような形です。    A    B    C  1 りんご  A市場  D市場、F市場 2 みかん  C市場 3 りんご  D市場  A市場、F市場 4 なし   B市場 5 バナナ  A市場 6 りんご  F市場  A市場、D市場 よろしくお願いします。

  • エクセルで文字の識別と文字を飛ばして足し算したい。

    以下のような表を作り、(1)、(2)の機能をつけたいのですがうまくいきません。 計算式の分かる方がいれば教えてください。    A    B   C   D 1 リンゴ  90円 1個  90円 2 バナナ 20円 2個  40円 3 みかん 30円 3個  90円 4 バナナ 20円 1個  20円 5 みかん 30円 2個  60円 6  合計  -  9個 300円 (1)この表のAの列に「リンゴ」「みかん」「バナナ」を入力すると自動的にB列に価格が表示される。 (2)C列に「未定」などの文字を入れるとオートSUMが機能しなくなるので、これをC列に文字を入れると文字を入れたセルを飛ばして計算する。 よろしくお願いします。

  • エクセル 同じセルを抜き出す

    すみません、初心者でうまく説明ができるかわからないのでそのまま書きます。 エクセルで、単語を羅列しているんですが、たとえばA列とB列に同じ単語が有った場合、それをC列に抜き出すといった作業はできるんでしょうか? 例) A1-5に『りんご』『バナナ』『みかん』『もも』『ぶどう』とあり、 B1-4に『すいか』『もも』『バナナ』『オレンジ』とあった場合に、 Cに『もも』『ばなな』と抜き出したいんです。できませんでしょうか? ご教授のほど、よろしくお願いします。

  • Excelで重複データの件数ではなく、何番目かを求める方法

    下記のような表があり、A列に入っている値が重複している場合、 B列に件数を求めるにはCOUNTIF関数を使いますが、件数ではなく、 何番目かを求めることはできるのでしょうか。  A列   B列  りんご 1  りんご 2  みかん 1  りんご 3  バナナ 1  みかん 2 すみませんが、ご教授いただけたら幸いです。 宜しくお願い致します。

  • エクセルの重複データ、必要数を指定して絞る

    エクセルの重複データ、必要数を指定して絞ることは可能ですか。 エクセル2010です。 マクロはよくわからないので、マクロを組まねばならないようでしたらあきらめます。 たとえばある列に (別の列もデータがあります。 この列を基点にしぼるイメージです) りんご りんご りんご りんご りんご りんご りんご りんご バナナ バナナ バナナ バナナ バナナ バナナ みかん みかん みかん みかん みかん みかん みかん みかん みかん みかん と、個数がランダムで同データがあるような場合に りんご りんご りんご りんご りんご バナナ バナナ バナナ バナナ バナナ みかん みかん みかん みかん みかん と5個に絞るということです。 「重複するレコードは無視する」としたときに1つにしぼられますが、 1つでなく、5つに絞るようなイメージです。 そのような指定がなんらかで可能でしょうか。 テキストフィルターをうまく使えばできたりするでしょうか。 よろしくお願い致します。

  • エクセルで一致する数をカウントしたい

    エクセル2010、OSはWindoes7です。 エクセルでセルに入っている単語、文章で一致するものの数をカウントしたいです。 例1 A列に以下のような単語が入ってるとします A1 りんご A2 みかん A3 バナナ さて、A列の「リンゴ」という単語の数を数えたい場合、普通は以下のようにします。 =countif(A1:A3,"りんご") (引数2は、どこかのセルに入れた凡例を参照するもよし) こうすれば結果は1となります。 他の単語の場合も同様です。引数2を代えれば、どんな単語でも自在にできます。 では以下のような場合はどうすればいいでしょうか? 例2 A列に以下のような単語が入ってるとします A1 りんご A2 みかん A3 バナナ A4 りんご   みかん A5 いちご   りんご A6 さっちゃんはね、バナナが大好き 本当だよ (注 A4,A5はAlt+Enter入力で、セル内改行してある) この状態で、A列にある、「りんご」の数をカウントせよ、という関数命令を実行させると 解答が りんご= 3 となるような関数を知りたい。 同様に「みかん」 =3  「バナナ」=2 と返してくるような関数を知りたい。 ちなみに、例2に対してcountif関数を実行させると、結果は りんご 1 みかん 1 バナナ 1 となる。 なぜならcountif関数では、カウントする定義は「一文字目から最終文字まで、完全一致」となっているので・・・。 よろしくお願いします。

専門家に質問してみよう