【问题标题】:How can i find and comment duplicates for large data in excel vba?如何在 excel vba 中查找和评论大数据的重复项?
【发布时间】:2019-07-02 16:45:13
【问题描述】:

我有一个代码可以根据第一列查找和突出显示(整行)重复项。现在我正在尝试复制最后找到的评论并将其粘贴到找到的副本:

在此示例中,应将第 8 行中的注释“Controle 1:OK”复制并粘贴到第 10 行。 但我的代码总是复制第一个注释“Controle 1: NOK”并将注释粘贴到第 8 行和第 10 行。

我是 Excel VBA 的新手,只是有一个线索(将所有找到的 cmets 放在一个数组中并接受最后一条评论),但不知道如何实现它。

有人知道如何做到这一点吗?

我正在使用 Excel 365。

 Sub sbFindDuplicatesInColumn()

    Dim lastRow As Long             
    Dim matchFoundIndex As Long
    Dim iCntr As Long               
    Dim comment As String

    lastRow = Range("A65000").End(xlUp).Row

    For iCntr = 1 To lastRow
    If Cells(iCntr, 1) <> "" Then
        matchFoundIndex = WorksheetFunction.Match(Cells(iCntr, 1), Range("A1:A" & lastRow), 0)
        comment = Cells(matchFoundIndex, 3).Value
        If iCntr <> matchFoundIndex Then

             Cells(iCntr, 3).Value = comment
             Range(Cells(iCntr, 1), Cells(iCntr, 3)).Font.Color = RGB(255, 40, 0)

       End If
    End If

    Next
End Sub

【问题讨论】:

  • 第 8 行似乎不是重复的。我没有看到重复。
  • 我使用第一列(Material-No)搜索重复项。材料号出现 3 次(第 5、8 和 10 行)。第 8 行和第 10 行的材料编号与第 5 行的材料编号重复
  • 啊....我误读了,因为您的意思是根据第一列中的重复项突出显示整行。
  • 没问题。我已经编辑了我的问题:D
  • Dim matchFoundIndex As ...是的,什么?

标签: excel vba duplicates


【解决方案1】:

简化对此的输入:

这就是你得到的,使用下面的代码:

Option Explicit

Sub TestMe()

    Dim wks As Worksheet: Set wks = Worksheets(1)
    Dim myLastRow As Long: myLastRow = lastRow(wks.Name)
    Dim matchRow As Long

    Dim myRow As Long
    For myRow = 1 To myLastRow
        With wks
            If .Cells(myRow, 1) <> "" Then
                matchRow = WorksheetFunction.Match(.Cells(myRow, 1), .Range("A1:A" & myLastRow), 0)
                If myRow <> matchRow Then
                    .Cells(myRow, 2) = .Cells(matchRow, 2)
                    .Cells(myRow, 2).Interior.Color = vbRed
                End If
            End If
        End With
    Next myRow

    Debug.Print myLastRow

End Sub

Function lastRow(wsName As String, Optional columnToCheck As Long = 1) As Long

    Dim ws As Worksheet
    Set ws = Worksheets(wsName)
    lastRow = ws.Cells(ws.Rows.Count, columnToCheck).End(xlUp).Row

End Function

它检查列A 上的重复项,每当找到重复项时,如果它不是第一个重复项,它就会获取第一个重复项的注释。这是检查它是否是第一个重复 - If myRow &lt;&gt; matchRow Then

【讨论】:

  • 我不想简化我的输入。这个想法是复制每个副本的最后一个现有评论并将其粘贴到最后一个副本中。
  • 运行您的代码确实会发现重复项,但没有添加任何 cmets
  • @ATI - 输入的简化是作为样本完成的。了解它的工作原理后,您可能会找到进一步编辑它的方法。
  • @peakpeak - 它已将 cmets 添加为红色。使用 .Cells(myRow, 2) = .Cells(matchRow, 2) 行。还是我错过了什么?
  • @Vityata 谢谢你的回答。我会尝试用你的代码来解决这个问题。
【解决方案2】:

也许是这样的。
它应该循环所有行并在“A”列中查找重复项。如果发现重复并且在重复行中没有评论,则复制最后一个已知评论。
如果找到重复但已经有评论,则此评论将成为新的“最后已知”以供进一步重复。

Option Explicit

Sub Dupes()

Dim Ws As Worksheet
Dim LastRow As Long, i As Long, j As Long, DupCounter As Long, DupPos As Long
Dim MatNo As String, Comment As String
Dim Found As Boolean
Dim ArrDuplicates() As Variant 'Declare dynamic array 

Set Ws = ThisWorkbook.Sheets(1)

'Redimennsion/change size of declared array 
ReDim ArrDuplicates(1 To 2, 1 To 1)

DupCounter = 1

With Ws
    'find last row with data in column "A" 
    LastRow = .Cells(.Rows.Count, 1).End(xlUp).Row
    'Loop all rows from 1 to last 
    For i = 1 To LastRow
        'reset variables for each loop 
        Found = False
        DupPos = 0
        MatNo = .Cells(i, 1)
        Comment = .Cells(i, 3) 'Column 3 is column "C" if other 
                              'column to be used just change the number 
        'Search array with previous data and look for duplicates 
        For j = LBound(ArrDuplicates(), 2) To UBound(ArrDuplicates(), 2)
           'If material number currently checked found in array 
            If MatNo = ArrDuplicates(1, j) Then
                'If comment for current row is empty, take comment from array 
                If Trim(Comment) = "" Then
                    Comment = ArrDuplicates(2, j)
                End If
                'remember position of source data in array (first occurence
                'of material number)
                DupPos = j
                'set "Found" marker 
                Found = True
                'leave loop 
                Exit For
            End If
        Next j

        'if no duplicate found 
        If Not Found Then
            'redimension array. "Preserve" keyword added to keep values
            'already existing in array
            ReDim Preserve ArrDuplicates(1 To 2, 1 To DupCounter)
            'insert new data to array ((first occurance of material number) 
            ArrDuplicates(1, DupCounter) = MatNo
            ArrDuplicates(2, DupCounter) = Comment
            DupCounter = DupCounter + 1 'increase counter used to redimension array 
        Else  'if material number found in array 
            'if commnet variable is same as comment in array 
            'This means that comment of current row was empty  
            If Comment = ArrDuplicates(2, DupPos) Then
                .Cells(i, 3) = Comment 'put comment in current row and column 3 "C"
            Else
                'Commnet in current row was not empty and different than last one 
                'replace "last known comment" in array for material number 
                'with new one from current row 
                ArrDuplicates(2, DupPos) = Comment
            End If
            'change font colour 
            .Cells(i, 3).Font.Color = vbRed
        End If
    Next i
End With

End Sub

编辑:添加了一些 cmets

Check also ReDim Statement

【讨论】:

  • 感谢您的回答。这段代码工作正常。现在我试图理解代码,一些问题:“ReDim ArrDuplicates(1 To 2, 1 To 1)”、“ReDim Preserve ArrDuplicates(1 To 2, 1 To DupCounter)”这些代码行有什么作用?如果我想将 C 列中的 cmets 列更改为 G 列,那么哪些代码行需要修改?
  • 添加了一些 cmets。
  • 感谢 cmets !!这段代码运行良好。谢谢。
猜你喜欢
  • 2019-03-29
  • 2017-10-24
  • 1970-01-01
  • 1970-01-01
  • 2014-02-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-28
相关资源
最近更新 更多