• ベストアンサー

EXCEL VBAで語句の一部が一致する値の検索方法について

すいませんEXCEL VBAで教えていただきたいことがあります。 A列: 1行:"東京都小笠原村逆川" 2行:"神奈川県横須賀市中町二丁目" 3行:"山梨県甲府市曙町2番地" 4行:"埼玉県さいたま市大宮区土手町三丁目" ・ ・ (100行目までデータが入力されている) C列: 1行:"神奈川県縦須賀市谷町二丁目" 2行:"先玉県埼玉市大宮区土手町一丁目" 3行:"東京都小笠原村順川" 4行:"山梨県甲府村曙町3番池" ・ ・ (150行目までデータが入力されている) これらのデータが入っているとします。 ここで、 B列: A列のデータと6文字以上一致するC列の行数を、A列に対応する行に記載。 1行:"3" 2行:"1" 3行:"4" 4行:"2" ・ ・ このB列の処理をEXCEL VBAで行うにはどうしたらいいのでしょうか。 Sub AAA() Dim wRowA As Long wRowA = 1 Do Until Cells(wRowA, "A").Text = "" Call BBB(wRowA) wRowA = wRowA + 1 Loop End Sub Sub BBB(wRowA As Long) Dim wRowD As Long wRowD = 1 Do Until Cells(wRowD, "C").Text = "" 'A列の値と6文字以上一致するC列のセルがあるときは If ・・・・・・・・・・ Then Cells(wRowA, "B").Value = wRowD End If wRowD = wRowD + 1 Loop End Sub IF以降の部分がどうも導き出せません。 よろしくお願いします。

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

  • ベストアンサー
noname#52504
noname#52504
回答No.2

例えば、 「神奈川県横須賀市中町二丁目」 「神奈川県縦須賀市谷町二丁目」 を比べたとき、 {神奈川県×須賀市×町二丁目} で11文字が一致、ということでしょうか? 人間であれば、どの部分がどの部分に対応するのかを 総合的に判断できますから単純なルールに思えますが、 機械に同じことをさせるのは結構大変です。 例えば、 「埼玉県さいたま市」と 「さいたま県埼玉市」では? A:文字の位置ごとに判断する場合  「×××××××市」で1 B:前者を基準に順序を考慮する場合  「*埼玉*市*」なので3 C:後者を基準に順序を考慮する場合  「*さいたま*市*」なので5 D:順序を考慮せず比較する場合  {さ・い・た・ま・県・埼・玉・市}で8 ※Aの場合、  「埼玉県さいたま市大宮区土手町三丁目」  「先玉県埼玉市大宮区土手町一丁目」   では、{玉・県}で2になります。 ※Dの場合、  「広島県福山市」「福島県山広市」でも  (使われている文字は全て一致するので)6になります。 ●甲案:ルールB(前者を基準に順序を考慮)でカウント '------------------------------------------------------- Sub AAA()  そのまま End SUB Sub BBB(wRowA As Long)  Dim wRowD As Long  wRowD = 1  Do Until Cells(wRowD, "C").Text = ""   If CCC(Cells(wRowA, "A").Text, Cells(wRowD, "C").Text) >= 6 Then    Cells(wRowA, "B").Value = wRowD    Exit Do '←HITした時点でDoループを抜ける   End If   wRowD = wRowD + 1  Loop End Sub Function CCC(ByVal myStr0 As String, ByVal myStr1 As String) As Integer  Dim ct As Integer  Dim i As Integer  Dim j As Integer  Dim k As Integer  ct = 0  j = 1  For i = 1 To Len(myStr0)   k = InStr(j, myStr1, Mid(myStr0, i, 1))   If k <> 0 Then    j = k + 1    ct = ct + 1   End If  Next i  CCC = ct End Function '------------------------------------------------------- ●乙案:ルールD(順序を考慮しない)でカウント '------------------------------------------------------- Sub AAA()  そのまま End SUB Sub BBB()  甲案と同じ End SUB Function CCC(ByVal myStr0 As String, ByVal myStr1 As String) As Integer  Dim i As Integer  Dim ct As Integer  ct = Len(myStr1)  For i = 1 To Len(myStr0)   myStr1 = Replace(myStr1, Mid(myStr0, i, 1), "", , 1)  Next i  CCC = ct - Len(myStr1) End Function '------------------------------------------------------- いずれもExcel2003で動作確認済 なお、甲案,乙案いずれの場合も、 「○○県☆☆市△△町□丁目」と 「●●県★★市▲▲町■丁目」であれば、 {県,市,町,丁,目}だけで5文字一致になりますから、 6文字以上という基準ではゆるすぎるように思います。 以上ご参考まで。

takohasisa
質問者

お礼

ありがとうございます!とりあえず教えていただいたコードで検索をかけてみましたら格段にヒット数が増えました!! 実際のデータでは乙案の方がヒット数が多いみたいです。 Functionプロシージャの myStr1 = Replace(myStr1, Mid(myStr0, i, 1), "", , 1) の辺りがちょっとよくわからないので、今からテキストを見ながら勉強してみます。 またよろしくお願いいたします。

その他の回答 (1)

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.1

こんばんは。 元のデータでは、少し無理がありませんか? >A列のデータと6文字以上一致するC列の行数を、A列に対応する行に記載。 >1行:"3" >2行:"1" >3行:"4" >4行:"2" 6文字一致では、1つしかヒットしませんし、4文字までにしても、そのデータでは、4行目は、空欄です。 "埼玉県さいたま市大宮区土手町三丁目" "先玉県埼玉市大宮区土手町一丁目" (埼玉) であっても、一致するのは、3文字までです。フリガナの取得だとかなり面倒です。 For i = 6 To 4 Step -1 一回だけなら、i = 6 To 6 です。 Sub TestMacro()   Dim c As Range   Dim r As Range   Dim dat As String   Dim i As Long   '最初にB列のデータを消す   Range("A1", Range("A65536").End(xlUp)).Offset(, 1).ClearContents    For Each c In Range("A1", Range("A65536").End(xlUp))     For Each r In Range("C1", Range("C65536").End(xlUp))       '数を減らして、4までとする       For i = 6 To 4 Step -1         If r.Value Like Left(c.Value, i) & "*" Then           dat = dat & "," & r.Row         End If         If c.Offset(, 1).Value = "" Then           '書き出し           c.Offset(, 1).Value = Mid(dat, 2)         End If         dat = ""       Next i     Next r   Next c End Sub

takohasisa
質問者

お礼

ありがとうございます。 For i = 6 To 4 Step -1 If r.Value Like Left(c.Value, i) & "*" Then というやり方を始めて学びました。 教えていただいたコードで検索をかけましたところヒットした数が格段に増え、かなり前進しました。 文頭が間違っている語についてはLeftではなくRightで検索をかけてみます。 またわからないことがありましたらよろしくお願いいたします。

関連するQ&A

  • EXCEL VBA 

    Excel VBAで アンケート集計をしたいと思い、プログラムを作ったのですが、J列までは入力がうまくいくのですが、K列にデータを入れて次の行にデータを入れると もともと存在していたKれつのデータが消えてしまします。 どう修正すれば ちゃんとデータが残ってくれるのでしょうか?  誰か教えてください Option Explicit Private Sub UserForm_Initialize() Dim チェックボックス As Control With cboBlood .AddItem "A型" .AddItem "B型" .AddItem "O型" .AddItem "AB型" End With cboBlood.ListIndex = -1 txtNo.Value = WorksheetFunction.Max( _ [Database].Resize(, 1)) + 1 txtNo.Enabled = False txtName.Text = "" optMale.Value = True txtAge.Value = 0 For Each チェックボックス In fraOS.Controls チェックボックス.Value = False Next txtName.SetFocus End Sub Private Sub cmdEntry_Click() Dim 行 As Long Dim 確認 As Integer 確認 = MsgBox("データを登録します。" _ & "よろしいですか?", vbYesNo) If 確認 <> vbYes Then Exit Sub 行 = [Database].Rows.Count + 1 [Database].Cells(行 - 1, 1).EntireRow.Insert [Database].Offset(行 - 1).Resize(1).Copy _ [Database].Cells(行 - 1, 1) [Database].Offset(行 - 1).Resize(1).ClearContents [Database].Cells(行, 1) = txtNo.Value [Database].Cells(行, 2) = txtName.Text If optMale.Value = True Then [Database].Cells(行, 3) = "男性" Else [Database].Cells(行, 3) = "女性" End If [Database].Cells(行, 4) = cboBlood.Text [Database].Cells(行, 5) = txtAge.Value If chkWin.Value = True Then _ [Database].Cells(行, 6) = "○" If chkMac.Value = True Then _ [Database].Cells(行, 7) = "○" If chkLinux.Value = True Then _ [Database].Cells(行, 8) = "○" If chkOther.Value = True Then _ [Database].Cells(行, 9) = "○" If chkOther.Value = True Then _ [Database].Cells(行, 10) = "○" Unload frmNew End Sub Private Sub cmdCancel_Click() Unload frmNew End Sub

  • ExcelにおけるVBAで、データの振り分けをしたい

    Sub a() Dim i As Long Dim s As Long Dim b As Worksheet Dim c As Worksheet Dim maxi As Long Dim maxs As Long Application.ScreenUpdating = False With ThisWorkbook Set b = .Worksheets("bbb") Set c = .Worksheets("ccc") End With maxi = b.Range("A1").CurrentRegion.Rows.Count maxs = c.Range("A1").CurrentRegion.Rows.Count For i = maxi To 2 Step -1 For s = maxs To 2 Step -1 If c.Cells(s, 1) = b.Cells(i, 1) And c.Cells(s, 2) = b.Cells(i, 2) Then c.Cells(s, 14) = b.Cells(i, 3) End If Next s Next i Application.ScreenUpdating = True End Sub ワークシートcとワークシートbの1列目と2列目が一致したときにだけ、cの14列目にbの3列目のデータを代入したく思い、以上のようなコードを書きましたが、重くて終わる様子がありません。 ・そもそもあっているのか、あっていないならどこを修正すればよいか ・早く終わるようにするにはどうしたらいいか アドバイスをよろしくお願いします。

  • ExcelのVBAで質問です。

    以下のようなシートがあります。 A列  B列  C列  D列  E列  F列  G列  H列 NO  名前  確認 日付1 日付2  確認 日付1 日付2 6行目からデータを入れる予定です。 C列には○印を入力します。 C列~E列までデータが入った行は、 F列~H列まで同じ処理をします。 (セルの背景色を変えます。) 以後同じことを列方向で繰り返します。 以下のようなVBAを組みましたが、 ○の個数を数える部分でエラーがでます。 Private Sub Worksheet_Change(ByVal Target As Range) Dim staff As String Dim kakunin As String Dim date1 As Date Dim date2 As Date Dim i As Long Dim j As Long Dim cnt As Long '100件分ループ For i = 6 To 105 '○の数をカウント cnt = WorksheetFunction.CountIf(ActiveSheet.Range(Cells(i, 2), Cells(i, 256)), "○") 'jとは確認の列番号のこと j = 3 * cnt staff = Cells(i, 2) kakunin = Cells(i, j) date1 = Cells(i, j + 1) date2 = Cells(i, j + 2) 'スタッフ名が入力されたら If staff = "" Then Range(Cells(i, j), Cells(i, j + 50)).Interior.ColorIndex = 15 Else Cells(i, j).Interior.ColorIndex = xlNone '○が入力されたら If kakunin = "○" Then Range(Cells(i, j + 1), Cells(i, j + 2)).Interior.ColorIndex = xlNone Else Range(Cells(i, j + 1), Cells(i, j + 2)).Interior.ColorIndex = 15 End If If Cells(i, j + 1) <> "" And Cells(i, j + 2) <> "" Then Cells(i, j + 3).Interior.ColorIndex = xlNone End If End If Next i End Sub ご教授いただけたら、幸いです。 よろしくお願いいたします。

  • エクセルVBAについて

    前回質問させていただきました件の追加機能になります。以前質問させていただきましたマクロが下記のものです。 Sub TESTa() Dim A As Long Dim B As Long Dim C As Long Dim D As Long Dim E As Long Dim F As Long '表の行数を調べる A = Worksheets("sheet1").Range("C65536").End(xlUp).Row - 1 For C = 1 To A For B = 4 To 7 'Sheet1のデータをSheet2に複写する Worksheets("Sheet2").Cells(B - 3 + D, 15) = Worksheets("Sheet1").Cells(C + 1, 1) Worksheets("Sheet2").Cells(B - 3 + D, 6) = Worksheets("Sheet1").Cells(C + 1, B) Worksheets("Sheet2").Cells(B - 3 + D, 14) = Worksheets("Sheet1").Cells(C + 1, 3) Worksheets("Sheet2").Cells(B - 3 + D, 10) = Worksheets("Sheet1").Cells(1, B) Worksheets("Sheet2").Cells(B - 3 + D, 13) = Worksheets("Sheet1").Cells(C + 1, 2) Next D = C * 4 Next 'Sheet2の表の行数を調べる Sheets("Sheet2").Select E = Worksheets("sheet2").Range("F65536").End(xlUp).Row '0欄の確認 For F = E To 1 Step -1 If Worksheets("Sheet2").Cells(F, 6) = 0 Then '0の場合は行を削除する Cells(F, 1).EntireRow.Delete End If Next End Sub カウントするとデータ個数がSheet1で約120件になりSheet2においては、4倍になりますので約480件になります。 そこで Sheet1において12件ごとに、Sheet2,3,4...としたいのです。 Sh1 NO.1~12がSheet2 Sh1 NO.13~24がSheet3 ... 10枚のシートにしたいのですが、このマクロにどのような命令を加えればよろしいでしょうか? お手数ですがよろしくお願いいたします。

  • エクセルVBA  どうしても動きません。

    お世話になります。 なかなか上達しない超初心者です。 ↓↓ですが、Activesheetにすると動くのに、シート名を元々存在するシート”実験"に指定すると動きません(データ内容はまったく同じで、A列に色んな名前が入っていて、重複しているとC列に重複と入力します)。 2日間試行錯誤したのですが、やっぱり動かず・・・ ちなみに、Activateにするとアクティブになるし、CurrentRegionも選択できるのに なんでうごかないんでしょうか・・・ 何卒ご指導くださいませ。よろしくお願いいたします!!!!!! Sub Test2() With Sheets("実験").Range("A1").CurrentRegion Dim i As Long Dim LastRow As Long LastRow = Range("A" & Rows.Count).End(xlUp).Row For i = 1 To LastRow If WorksheetFunction.CountIf(Range("A:A"), Cells(i, 1)) > 1 Then Cells(i, 3) = "重複" End If Next i End With End Sub Sheets("実験")をActivesheetに変えると別のシートがしっかり動いてくれます・・・が、なんとしてでも”実験”シートに動いていただきたいです・・・。

  • EXCEL VBAについて

    EXCEL VBAについて教えてください やりたいことは以下の通りです。 ・全シートJ列1~100行目を検索しアルファベットが含まれるセルが存在すれば 上のセルをコピーする ここまで作ったのですが上手くいきません Sub VBAsample() Dim GYO As Long For GYO = 1 To 100 If Find([a-z], LookAt:=xlPart) Then Cells(GYO, 10).Value = Cells(GYO - 1, 10).Value End If Next GYO End Sub 添削をお願いします

  • Excel VBA でテキストボックスの値をセルA列から検索

    いつもお世話になります。 Private Sub CommandButton3_Click() Dim 行 As String Dim 列 As String Dim 最終行 As String Dim 検索行 As String Dim メッセージ As Integer Dim 一致 As Range Dim myNO As Variant Dim i As Long Sheets(3).Select 最終行 = Range("A2").End(xlDown).Offset(1).Select 行 = ActiveCell.Row 列 = ActiveCell.Column myNO = TextBox2.Value 検索行 = Range("A2").End(xlDown).Select ※・・・Set 一致 = Range("A2:検索検").Findwhat:=TextBox2,lookat:=xlWhole) If 一致 Is Nothing Then MsgBox "データがありません。新規コード入力します。" Cells(行, 列 + 0) = UserForm1.TextBox2.Value Cells(行, 列 + 1) = UserForm1.ComboBox7.Value Else i = Cells(行 - 1, "A") Cells(i, 列 + 0) = UserForm1.TextBox2.Value Cells(i, 列 + 1) = UserForm1.ComboBox7.Value End If End Sub 「エラー1004'Range'メソッドは失敗しました'Global'オブジェクト」とでます。※印が黄色になっています。 ユーザーフォーム1のテキストボックスの値をシート3のA列から検索して、一致すれば、A列の一致セルに上書き入力して、一致が無い場合はA列の空白セルに追加入力したいのです。よろしくお願い致します。

  • エクセルVBA(掛け算)

    いつもおせわになります。 現在、下記のようなコードを書いてますがどうもうまくいきません。よろしくお願いいたします。 M列 = K列 × N列を6行目から最終行目で入れたくて下記のようなコードを書きました。 ところが・・・N列にはデータのない場合があるので、If~を入れてみました。ここまではうまくいったのですが、 O列 = K列 × P列のように数式を入れたい列が他にもあり、又同じコードを下記のように書いたら、P列にデータがないところで止まってしまいます。 '///////////////////////////////////////////// Dim wsS As Worksheet Dim r As Long Dim Srow As Long Set wsS = Worksheets("syukei") Srow = wsS.Range("D65536").End(xlUp).Row With Worksheets("syukei") For r = 6 To Srow If Cells(r, 12) = Noting Then r = r End If Cells(r, 13) = Cells(r, 11) * Cells(r, 12) Next End With With Worksheets("syukei") '↓////////ここらへんで止まる////////// For r = 6 To Srow If Cells(r, 14) = Noting Then r = r End If Cells(r, 15) = Cells(r, 11) * Cells(r, 14) Next End With End Sub 掛け算を入れたい行は、下記のようになっています。 M列=K列×L列 O列=K列×N列 Q列=K列×P列 S列=K列×R列 U列=K列×T列 W列=K列×V列 Y列=K列×X列 よろしくお願いいたします。

  • VBA 条件検索について

    VBAの検索について質問です。 以下のようなものを作ろうと思います。 sheet1とsheet2がありsheet1のA、Bの数値をsheet2の同じA,Bの数値の値の行を検索して, その同じ値の行のsheet1のCの数値の値からsheet2のCの数値を引いた値をsheet3のC列に返すプログラムを作ろうと思います。空白などで同じ値がない場合はsheet3に空欄を返そうと思います。 以下に例をプログラムの実行例を示します。 sheet1 ■ A 列 B 列 C列 1: 7 | 1 | 3 2: 5 | 8 | 2 3: 2 | 3 | 1 4: 9 | 6 | 4 sheet2 ■ A 列 B列 C列 1: 2 | 3 | 4 2: 9 | 6 | 2 3: 7 | 1 | 5 4: 5|   | 3 sheet3 ■ A列 B列 C列 1: 7| 1 | -2 2: 3: 2| 3 | -3 4: 9 | 6 | 2 自分で以下のプログラムを作成してみたのですが空欄が検索できなかったりしてなかなかできません。 どなたか、教えてください。お願いします。 Sub test() Dim sh1 As Object, sh2 As Object, sh3 As Object Dim d1 As String, d2 As String, a As Long Set sh1 =Sheets(“Sheet1”) Set sh2 =Sheets(“Sheet2”) Set sh3 =Sheets(“Sheet3”) For a = 1 To 3000 Step 1 d1 = sh1.Cells(a,1) & sh1.Cells(a,2) d2 = sh2.Cells(a,1) & sh2.Cells(a,2) Do while d2 <>”” If d1 = d2 Then Sh3.Cells(a,1) = sh1.Cells(a,1) Sh3.Cells(a,2) = sh1.Cells(a,2) Sh3.Cells(a,3) = sh1.Cells(a,3) Exit Do End If a= a+1 d2 = sh2.Cells(a,1) & sh2.Cells(a,2) Loop Next End Sub

  • Excel VBAで文字列の部分一致の文字列を表示

    以前、こちらで頭5文字までの一致で文字列を表示するVBAを教えて頂きました。今回はFINDなどの部分一致での文字列を表示することをしたいのですが、ご教示いただけますと幸いです。 下記はSheet1のA3に文字を5文字以内いれるとSheet2のC列からピックアップしてSheet1のA列に文字列を表示する及びSheet2のB列のデータをSheet1のC列に表示させるVBAです。 Sub Test2() Dim Ws1 As Worksheet, Ws2 As Worksheet Dim SData As String, i As Long, VRet As Variant Dim c As Range, LastRow As Long Set Ws1 = Sheets("Sheet1") Set Ws2 = Sheets("Sheet2") SData = CStr(Ws1.Range("A3").Value) If SData = "" Then Exit Sub i = 5 LastRow = Ws1.Cells(Rows.Count, "A").End(xlUp).Row If LastRow < i Then LastRow = i End If Ws1.Range(Ws1.Cells(i, "A"), Ws1.Cells(LastRow, "C")).ClearContents With Ws2 For Each c In .Range(.Cells(1, "C"), .Cells(Rows.Count, "C").End(xlUp)) VRet = InStr(1, CStr(c.Value), SData, vbTextCompare) If VRet = 1 And Len(c.Value) >= 10 Then Ws1.Cells(i, "A").Resize(1, 2).Value = c.Resize(1, 2).Value 'とりあえずSheet2のB列のデータ(C列のデータに同期したデータ)をSheet1のC列に Ws1.Cells(i, "C").Value = .Cells(c.Row, "B").Value i = i + 1 End If Next End With End Sub 宜しくお願い致します。

専門家に質問してみよう