简体   繁体   English

我究竟做错了什么? 使用Excel VBA删除重复项

[英]What am I doing wrong? Removing duplicates using Excel VBA

I'm new to VBA so this is probably a very obvious mistake. 我是VBA的新手,所以这可能是一个非常明显的错误。

To keep it short, I am trying to delete rows based on two criteria: In Column A, if they have the same value (duplicate) and in Column B, the difference is less than 100, then one row is deleted from the bottom. 为了简短起见,我试图根据两个条件删除行:在A列中,如果它们具有相同的值(重复),而在B列中,相差小于 100,则从底部删除一行。

Example data: 示例数据:

Column A  Column B          
1         300              
1         350     SHOULD be deleted as second column diff. is <100 compared to row above
2         500              
2         700     Should NOT be deleted as second column diff. is not <100

Here is the code I have come up with: 这是我想出的代码:

Sub deduplication()

Dim i As Long
Dim j As Long
Dim lrow As Long

Application.ScreenUpdating = False

With Worksheets("Sheet1")

lrow = .Range("A" & .Rows.Count).End(xlUp).Row

    For i = lrow To 2 Step -1
        For j = i To 2 Step -1
            If .Cells(i, "A").Value = .Cells(j, "A").Value And .Cells(i, "B").Value - .Cells(j, "B").Value < 100 Then
               .Cells(i, "A").EntireRow.Delete
            End If
        Next j
    Next i

End With

End Sub

This largely works, but only if the second criterion is greater than (>) rather than less than (<). 这在很大程度上有效,但前提是第二个条件大于 (>)而不是小于 (<)。 When it is less than, it deletes every row . 小于时,将删除每一行 What am I doing wrong? 我究竟做错了什么? Is there an easy fix? 有简单的解决方法吗?

Thank you 谢谢

Not

If .Cells(i, "A").Value = .Cells(j, "A").Value And .Cells(i, "B").Value - .Cells(j, "B").Value < 100 Then

Here in the second part of the statement, you're just comparing .Cells(j, "B").Value to const 100 ! 在语句的第二部分,您只是将.Cells(j, "B").Value与const 100进行比较!

But

If .Cells(i, "A").Value = .Cells(j, "A").Value And Abs(.Cells(i, "B").Value - .Cells(j, "B").Value) < 100 Then

Abs() may help, else keep just the ( ) Abs()可能有帮助,否则仅保留()

Something like this should work for you: 这样的事情应该为您工作:

Sub tgr()

    Dim ws As Worksheet
    Dim rDel As Range
    Dim rData As Range
    Dim ACell As Range
    Dim hUnq As Object

    Set ws = ActiveWorkbook.Sheets("Sheet1")
    Set hUnq = CreateObject("Scripting.Dictionary")


    Set rData = ws.Range("A2", ws.Cells(ws.Rows.Count, "A").End(xlUp))
    If rData.Row = 1 Then Exit Sub  'No data

    For Each ACell In rData.Cells
        If Not hUnq.Exists(ACell.Value) Then
            'New Unique ACell value
            hUnq.Add ACell.Value, ACell.Value
        Else
            'Duplicate ACell value
            If Abs(ws.Cells(ACell.Row, "B").Value - ws.Cells(ACell.Row - 1, "B").Value) < 100 Then
                If rDel Is Nothing Then Set rDel = ACell Else Set rDel = Union(rDel, ACell)
            End If
        End If
    Next ACell

    If Not rDel Is Nothing Then rDel.EntireRow.Delete

End Sub

Sticking to the format of your code, you can do this using one For loop as well. 坚持使用代码格式,也可以使用一个For循环来执行此操作。

For i = lrow To 3 Step -1
    If .Cells(i, "A") = .Cells(i - 1, "A") And (.Cells(i, "B") - .Cells(i - 1, "B")) < 100 Then
        .Cells(i, "A").EntireRow.Delete
    End If
Next i

Every first j-cycle starts off by comparing a row to itself since you start with j = i . 自从j = i开始,每个第一个j周期都会通过将一行与自身进行比较而开始。 The difference between a value and itself is always zero. 值与其自身之间的差始终为零。 (It also compares row 2 with itself as the very last step.) (最后一步,它还将第2行与其自身进行比较。)

However, if you switch: 但是,如果您切换:

For i = lrow To 2 Step -1
For j = i To 2 Step -1

to: 至:

For i = lrow To 3 Step -1
For j = i - 1 To 2 Step -1`

the code will compare all the various rows without the self-compares. 该代码将比较所有各行,而不进行自我比较。

Another point (which @Proger_Cbsk 's answer brought to mind), is that doing the comparison with just the subtraction .Cells(i, "B").Value - .Cells(j, "B").Value < 100 will sometimes cause unexpected results. 另一点(@Proger_Cbsk的答案浮现在脑海)是,只用减法.Cells(i, "B").Value - .Cells(j, "B").Value < 100有时进行比较导致意外结果。

For example, assume .Cells(i, "B").Value = 1 and .Cells(j, "B").Value = 250 . 例如,假设.Cells(i, "B").Value = 1.Cells(j, "B").Value = 250 We can tell by just looking, that there is a difference of at least 100, so you would expect this part of the expression to evaluate to False. 我们可以看出,两者至少相差100,因此您希望表达式的这一部分的值为False。 However, from straight substitution, you get the expression: 1 - 250 < 100 . 但是,从直接替换中,您可以获得表达式: 1 - 250 < 100 Since 1 - 250 = -249 , and since -249 < 100 , the expression would actually evaluate to True. 由于1 - 250 = -249 ,并且-249 < 100 ,因此该表达式实际上将计算为True。

However, if you were to change .Cells(i, "B").Value - .Cells(j, "B").Value < 100 to Abs(.Cells(i, "B").Value - .Cells(j, "B").Value) < 100 , the expression will now be looking at if the difference is greater or less than 100, instead of looking at if the subtraction result is greater or less than 100. 但是,如果要将.Cells(i, "B").Value - .Cells(j, "B").Value < 100更改为Abs(.Cells(i, "B").Value - .Cells(j, "B").Value) < 100 ,现在表达式将查看差值是大于还是小于100,而不是减法结果是大于还是小于100。

Why not to use the built-in command: 为什么不使用内置命令:

Worksheets("Sheet1").Range("$A:$A").RemoveDuplicates Columns:=1, Header:=xlYes

Range.RemoveDuplicates Method (Excel) Range.RemoveDuplicates方法(Excel)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 我对这个 Excel vba 做错了什么 - What am I doing wrong with this Excel vba 尝试并无法通过VBA在Excel中的列中循环。 我究竟做错了什么? - Trying and failing to loop through a column in Excel with VBA. What am I doing wrong? 在Excel VBA宏中创建一个新行(我做错了什么?) - Creating a new row in Excel VBA macro (what am I doing wrong?) Excel VBA:在for循环中跳转:“ Next for For” –我在做什么错? - Excel VBA: Jump inside a for loop: “Next without For” – What am I doing wrong? Excel VBA Find函数未返回整数值,看不到我在做什么 - Excel VBA Find function not returning an integer value, can't see what I am doing wrong 我正在使用VBA DateSerial函数分隔字符串中的日期,但是当字符串中的年份为&#39;1000&#39;时,Excel Ends Sub会出现。 我究竟做错了什么? - I am using the VBA DateSerial function to separate dates in a string, but Excel Ends Sub when year in string is '1000'. What am I doing wrong? VBA创建数据透视表,类型不匹配? 我究竟做错了什么? - VBA to Create PivotTable, Type Mismatch? What Am I Doing Wrong? VBA将多列转换为两列-我在做什么错? - VBA Transform Many Columns to Two - What am I doing wrong? 我在excel行循环的拆分中做错了什么? - What am I doing wrong in this split for excel rows loop? Excel VBA-删除重复项 - Excel VBA - Removing duplicates
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM