【问题标题】:Find all duplicates in a column of a certain value and return values from the next column查找某个值的列中的所有重复项,并从下一列返回值
【发布时间】:2020-05-16 02:31:48
【问题描述】:

我正在尝试做一些看起来像这样的东西:

在右侧的表格中,所有的唯一记录都将存储在某个区域中。但是,某些记录可能存在于更多区域,并且可以从 A 列和 B 列中的列表中获取此信息。宏应获取 D 列中的每个唯一记录并在 A 列中搜索它,每次找到它时,应该复制 B 列中的位置/区域并粘贴到表中唯一记录的旁边。我想我可以通过循环来做到这一点,但是我在下面的代码中创建的内容并没有真正起作用。

第二个挑战是让它明白,在一个位置已经复制到表中,新找到的位置需要粘贴到同一条唯一记录的下一个空闲单元格中。

我知道我的代码有点吓人,但即使只是关于我应该看哪个方向的建议,我也很感激......提前致谢!

Sub searcharea()

    Dim UC As Variant, UCrng As Range, ra As Range

    Set UCrng = Range("F2:F6")

    For Each UC In UCrng

        Set ra = Cells.Find(What:=UC, LookIn:=xlFormulas, _
        LookAt:=xlPart, SearchOrder:=xlByColumns, SearchDirection:=xlNext, _
        MatchCase:=False, SearchFormat:=False).Activate

        ra.Offset(0, 1).Copy Destination:=Range("E2")

    Next

End Sub

【问题讨论】:

    标签: excel vba loops


    【解决方案1】:

    我建议遍历所有行(A + B 列),例如:

    For i = 1 to Rows.Count
    'DoStuff
    Next i
    

    对于每一行,如果 A 的值不存在,则将其复制到 D 中。 您可以像这样访问这些值:

    Cells(i, "A").Value
    Cells(i, "B").Value
    

    用于查找列中的值,see here。如果您发现重复项,请使用另一个循环来检查您的特定行中的哪一列(E、F、G、..)是第一个空列,并且超过了那里 B 列的值。

    【讨论】:

    • 嗨,保罗,我不确定我明白了...我需要遍历 D 列,对于每个列,在 A 列中查找所有重复项。因此我尝试使用 find 方法。我还需要复制表中的 B 列值而不是 A 列值。
    • 好吧,我误解了你的问题。您可以使用 For 循环遍历所有行,并提取 D 列的值。通过我发布的链接,您可以在 A 列中搜索 D 列的每个值。下一步是粘贴列的值B 在 D 后面的第一个空列中。我希望这能澄清我的答案。
    【解决方案2】:

    试试看:

    Option Explicit
    
    Sub test()
    
        Dim LastRowA As Long, LastRowD As Long, i As Long, rngColumn As Long
        Dim rng As Range
    
        With ThisWorkbook.Worksheets("Sheet1")
    
            LastRowD = .Cells(.Rows.Count, "D").End(xlUp).Row
    
            .Range("D2:J" & LastRowD).ClearContents
    
            LastRowA = .Cells(.Rows.Count, "A").End(xlUp).Row
    
            For i = 2 To LastRowA
    
                LastRowD = .Cells(.Rows.Count, "D").End(xlUp).Row
    
                Set rng = .Range("D1:D" & LastRowD).Find(.Range("A" & i).Value, LookIn:=xlValues, lookat:=xlWhole)
    
                If Not rng Is Nothing Then
                    rngColumn = .Cells(rng.Row, .Columns.Count).End(xlToLeft).Column
                    Cells(rng.Row, rngColumn + 1).Value = .Range("B" & i).Value
                Else
                    .Range("D" & LastRowD + 1).Value = .Range("A" & i).Value
                    .Range("E" & LastRowD + 1).Value = .Range("B" & i).Value
                End If
    
            Next i
    
        End With
    
    End Sub
    

    【讨论】:

    • 感谢@error1004 我会在周末前试一试!我会回来的反馈:)
    【解决方案3】:

    我认为这段代码会做你想做的事。请尝试一下。

    Option Explicit
    
    Sub SortToColumns()
        ' Variatus @STO 30 Jan 2020
    
        Dim WsS As Worksheet                    ' Source
        Dim WsT As Worksheet                    ' Target
        Dim Rng As Range
        Dim Fn As String, An As String          ' File name, Area name
        Dim Rls As Long
        Dim Rs As Long
        Dim Rt As Long, Ct As Long
    
        With ThisWorkbook                       ' change as required
            Set WsS = .Worksheets("Sheet1")     ' change as required
            Set WsT = .Worksheets("Sheet2")     ' change as required
        End With
    
        With WsT
            ' delete all but the caption row
            .Range(.Cells(2, 1), .Cells(.Rows.Count, "A").End(xlUp)).EntireRow.ClearContents
        End With
    
        Application.ScreenUpdating = False
        With WsS
            ' find last row of source data
            Rls = .Cells(.Rows.Count, "A").End(xlUp).Row
    
            For Rs = 2 To Rls                   ' start from row 2 (row 1 is caption)
                Fn = .Cells(Rs, "A").Value
                An = .Cells(Rs, "B").Value
                If FileNameRow(Fn, WsT, Rt) Then
                    ' add to existing item
                    With WsT
                        Ct = .Cells(Rt, .Columns.Count).End(xlToLeft).Column
                        Set Rng = .Range(.Cells(Rt, "B"), .Cells(Rt, Ct))
                    End With
                    With Rng
                        Set Rng = .Find(An, .Cells(.Cells.Count), xlValues, xlWhole, xlByRows, xlNext)
                    End With
                    ' skip if Area exists
                    If Rng Is Nothing Then WsT.Cells(Rt, Ct + 1).Value = An
                Else
                    ' is new item
                    WsT.Cells(Rt, "A").Value = Fn
                    WsT.Cells(Rt, "B").Value = An
                End If
            Next Rs
        End With
        Application.ScreenUpdating = True
    End Sub
    
    Private Function FileNameRow(Fn As String, _
                                 WsT As Worksheet, _
                                 Rt As Long) As Boolean
        ' Rt is a return Long
        ' return True if item exists (found)
    
        Dim Fnd As Range
        Dim Rng As Range
        Dim R As Long
    
        With WsT
            R = .Cells(.Rows.Count, "A").End(xlUp).Row
            Set Rng = .Range(.Cells(2, "A"), .Cells(R, "A"))
            Set Fnd = Rng.Find(Fn, Rng.Cells(Rng.Cells.Count), xlValues, xlWhole, xlByRows, xlNext)
    
            If Fnd Is Nothing Then
                Rt = Application.Max(.Cells(.Rows.Count, "A").End(xlUp).Row + 1, 2)
            Else
                Rt = Fnd.Row
                FileNameRow = True
            End If
        End With
    End Function
    

    【讨论】:

    • 感谢@variatus,我会在周末前试一试!我会回来的反馈:)
    猜你喜欢
    • 1970-01-01
    • 2015-03-23
    • 1970-01-01
    • 2023-03-23
    • 1970-01-01
    • 2023-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多