在另一个循环中循环查找下一个循环&找

时间:2018-04-11 07:06:13

标签: excel vba excel-vba

我使用循环从Sheet 2中的Sheet 1中找到与供应商最接近的名称。

Dim LastRow As Long
LastRow = Sheets("BBB").Range("A" & Rows.Count).End(xlUp).Row

Dim i As Integer
For i = 2 To LastRow
Dim ra As Range
Dim a, k As Integer
a = Len(Sheets("BBB").Range("A" & i))   

Do
Set ra = Sheets("AAA").Cells.Find(What:=Left(Range("A" & i), a), LookIn:=xlValues, LookAt _
        :=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _
        False, SearchFormat:=False)


a = a - 1

Loop Until Not ra Is Nothing Or a = 3

If ra Is Nothing Then
Sheets("BBB").Range("C" & i).Value = a
Else
Sheets("BBB").Range("B" & i).Value = ra.Value

效果很好,但现在我觉得有可能在“AAA”表中出现了两次

实施例: 板材BBB供应商:“SICK” 如果Sheet AAA有2个供应商:“SICK”和“NOSICKHERE LTD” 我的代码只能找到两个供应商中的一个,但不会同时返回两个。

如何使用findnext查找所有出现的内容? 有谁看到更好的解决方案?

我尝试在“next i”之前的代码底部使用以下内容,但是我没有使用findnext

Dim firstCellAddress As String
firstCellAddress = ra.Address

k = 1
Do

    Set ra = Sheets("AAA").Cells.FindNext()
    Sheets("BBB").Cells(i, 2 + k).Value = ra.Value

    k = k + 1

Loop While firstCellAddress <> ra.Address

如果我的问题太难理解,请告诉我

2 个答案:

答案 0 :(得分:1)

这会生成所需的输出。

Option Explicit

Public Sub GetMatches()

    Dim wb As Workbook, wsSource As Worksheet, wsSearch As Worksheet, masterDict As Object, arr() As Variant, i As Long
    Set wb = ThisWorkbook
    Set wsSource = wb.Worksheets("BBB")
    Set wsSearch = wb.Worksheets("AAA")
    Set masterDict = CreateObject("Scripting.Dictionary")

    With wsSource
        arr = Intersect(.Columns(1), .UsedRange)
        For i = 1 To UBound(arr, 1)
            If Not masterDict.exists(arr(i, 1)) Then masterDict.Add arr(i, 1), GetAllMatches(arr(i, 1), wsSearch)
        Next i
    End With

    Dim key As Variant
    For Each key In masterDict.keys
        Debug.Print masterDict(key)
    Next key
End Sub

Public Function GetAllMatches(ByVal findString As String, ByVal searchRng As Worksheet) As String

    Dim foundCell As Range
    Dim concatenatedString As String
    concatenatedString = vbNullString
    With Intersect(searchRng.Columns(1), searchRng.UsedRange)

        Set foundCell = .Find(findString)
        concatenatedString = foundCell

        Dim currMatch As Long
        currMatch = 0

        For currMatch = 1 To WorksheetFunction.CountIf(.Cells, "*" & findString & "*") - 1

            Set foundCell = .Find(What:=findString, After:=foundCell, _
                                  LookIn:=xlValues, LookAt:=xlPart, SearchOrder:=xlByRows, _
                                  SearchDirection:=xlNext, MatchCase:=False)

            If Not foundCell Is Nothing Then
                concatenatedString = concatenatedString & "," & foundCell
            Else
                concatenatedString = foundCell
            End If
        Next currMatch
    End With    
    GetAllMatches = concatenatedString    
End Function

<强> TESTDATA:

TestData

AAA:

| Absinthe    |
| Antibiotics |
| Random      |
| Antisocial  |
| Antipodean  |
| Motorcycle  |
| Random      |
| Random      |
| Motorbike   |
| Random      |
| Motown      |

BBB:

| Ab   |
| Moto |

<强>输出:

Output

答案 1 :(得分:1)

下面的代码将遍历表B中的所有值并输出它的结果。 我已经为我的例子重复使用了QHarr的值

Option Explicit
Public Sub findValue()
    Dim firstAddress As String
    Dim c As Range, rng As Range, v As Range
    Dim tmp As Variant
    Dim j As Long

    With ThisWorkbook
        With .Sheets("AAA")
            Set rng = .Range(.Cells(1, 1), .Cells(.Cells(.Rows.Count, 1).End(xlUp).Row, 1))
        End With

        With .Sheets("BBB")
            For Each v In .Range(.Cells(1, 1), .Cells(.Cells(.Rows.Count, 1).End(xlUp).Row, 1))
                ReDim tmp(1 To rng.Rows.Count)
                j = LBound(tmp)

                Set c = rng.Find(what:=v, LookIn:=xlValues, lookat:=xlPart, MatchCase:=False)
                If Not c Is Nothing Then
                    firstAddress = c.Address
                    Do
                        tmp(j) = c.Value2
                        j = j + 1
                        Set c = rng.FindNext(c)
                    Loop While c.Address <> firstAddress And Not c Is Nothing
                    If j > 0 Then
                        ReDim Preserve tmp(LBound(tmp) To j - 1)
                        Debug.Print v & ": " & Join(tmp, ",")
                        v.Offset(0, 1).Value2 = Join(tmp, ",")
                    End If
                End If
            Next v
        End With
    End With
End Sub
Sheet("AAA")

Sheet("AAA")

Sheet("BBB") before running code

Sheet("BBB") Before Running code

Sheet("BBB") After code run

Sheet("BBB") After code run

Immediate Window after code run

Immediate window after code run