简体   繁体   English

Excel VBA查找重复项并发布到其他工作表

[英]Excel VBA Find Duplicates and post to different sheet

I keep having an issue with some code in VBA Excel was looking for some help! 我一直在寻找VBA Excel中的某些代码问题,以寻求帮助!

I am trying to sort through a list of names with corresponding phone numbers, checking for multiple names under the same phone number. 我正在尝试对具有相应电话号码的名称列表进行排序,以检查同一电话号码下的多个名称。 Then post those names to a separate sheet. 然后将这些名称发布到单独的工作表中。

So far my code is: 到目前为止,我的代码是:

Sub main()
    Dim cName As New Collection
    For Each celli In Columns(3).Cells
    Sheets(2).Activate
        On Error GoTo raa
            If Not celli.Value = Empty Then
            cName.Add Item:=celli.Row, Key:="" & celli.Value
            End If
    Next celli
        On Error Resume Next
raa:
    Sheets(3).Activate
    Range("a1").Offset(celli.Row - 1, 0).Value = Range("a1").Offset(cName(celli.Value) - 1, 0).Value
    Resume Next
End Sub

When I try to run the code it crashes Excel, and does not give any error codes. 当我尝试运行代码时,它使Excel崩溃,并且没有给出任何错误代码。

Some things I've tried to fix the issue: 我尝试解决此问题的一些方法:

  • Shorted List of Items 短项清单

  • Converted phone numbers to string using cstr() 使用cstr()将电话号码转换为字符串

  • Adjusted Range and offsets 调整范围和偏移

I'm pretty new to all this, I only managed to get this far on the code with help from other posts on this site. 我对这一切还很陌生,只有在本网站其他帖子的帮助下,我才设法在代码上做到了这一点。 Not sure where to go with this since it just crashes and gives me no error to look into. 不知道该去哪里,因为它只是崩溃了,没有错误可查。 Any ideas are appreciated Thank you! 任何想法表示赞赏,谢谢!

Updated: 更新:

Option Explicit
Dim output As Worksheet
Dim data As Worksheet
Dim hold As Object
Dim celli
Dim nextRow

Sub main()
    Set output = Worksheets("phoneFlags")
    Set data = Worksheets("filteredData")

    Set hold = CreateObject("Scripting.Dictionary")
        For Each celli In data.Columns(3).Cells
            On Error GoTo raa
            If Not IsEmpty(celli.Value) Then
                hold.Add Item:=celli.Row, Key:="" & celli.Value
            End If
        Next celli
        On Error Resume Next
raa:
    nextRow = output.Range("A" & Rows.Count).End(xlUp).Row + 1
    output.Range("A" & nextRow).Value = data.Range("A1").Offset(hold(celli.Value) - 1, 0).Value
    'data.Range("B1").Offset(celli.Row - 1, 0).Value = Range("B1").Offset(hold
    Resume Next
End Sub

Update2: UPDATE2:

Used hold.Exists along with an ElseIf to remove the GoTo 's. 使用hold.ExistsElseIf一起存在以删除GoTo Also changed it to copy and paste the row to the next sheet. 还对其进行了更改,以将行复制并粘贴到下一张纸上。

Sub main()
    Set output = Worksheets("phoneFlags")
    Set data = Worksheets("filteredData")
    Set hold = CreateObject("Scripting.Dictionary")

    For Each celli In data.Columns(2).Cells
        If Not hold.Exists(CStr(celli.Value)) Then
            If Not IsEmpty(celli.Value) Then
                hold.Add Item:=celli.Row, Key:="" & celli.Value
            Else
            End If
        ElseIf hold.Exists(CStr(celli.Value)) Then
            data.Rows(celli.Row).Copy (Sheets("phoneFlags").Cells(Rows.Count, 1).End(xlUp).Offset(1, 0))
            'output.Range("A" & nextRow).Value = data.Range("A1").Offset(hold(celli.Value) - 1, 0).Value
        End If
    Next celli
End Sub

When developing code, don't try (or be afraid of) errors as they are pointers to help fix the code or the logic. 开发代码时,请勿尝试(或担心)错误,因为它们是有助于修复代码或逻辑的指针。 As such, don't use On Error unless it is absolutely indicated in the coding algorithm (*). 因此,除非在编码算法(*)中有绝对指示,否则请不要使用On Error using On Error when not necessary only hides errors, does not fix them and when coding it is always better to avoid the errors in the first place (good logic). On Error不必要时使用On Error只会隐藏错误,不能修复它们,而在编码时始终最好一开始就避免错误(良好的逻辑)。

When adding to the Dictionary, first check to see if the item already exists. 在添加到词典中时,首先检查该项目是否已经存在。 The Microsoft documentation notes that trying to add an element that already exists causes an error. Microsoft文档指出,尝试添加已经存在的元素会导致错误。 An advantage that the Dictionary object has over an ordinary Collection object in VBA is the .exists(value) method, which returns a Boolean . Dictionary对象相对于VBA中的普通Collection对象的一个​​优点是.exists(value)方法,该方法返回Boolean

The short answer to your question, now that I have the context out of the way, is that you can first check ( if Not hold.exists(CStr(celli.Value)) Then ) and then add if it does not already exist. 现在,有了我的上下文,对您的问题的简短回答是,您可以先检查( if Not hold.exists(CStr(celli.Value)) Then ),然后添加(如果不存在)。

(*) As a side note, I was solving an Excel macro issue yesterday which took me most of the day to nut out, but the raising of errors and the use of debugging code helped me make some stable code rather than some buggy but kind-of-working code (which is what I was fixing in the first place). (*)作为附带说明,我昨天解决了一个Excel宏问题,这使我花了整整一天的时间来解决问题,但是错误的产生和调试代码的使用帮助我制作了一些稳定的代码,而不是一些有问题的bug工作代码(这是我首先修复的问题)。 However, the use of error handling can be a short cut in some instances such as: 但是,在某些情况下,使用错误处理可能是捷径,例如:

Function RangeExists(WS as Worksheet, NamedRange as String) As Boolean
Dim tResult as Boolean
Dim tRange as Range
    tResult = False ' The default for declaring a Boolean is False, but I like to be explicit
    On Error Goto SetResult ' the use of error means not using a loop through all the named ranges in the WS and can be quicker.
        Set tRange = WS.Range(NamedRange) ' will error out if the named range does not exist
        tResult = True
    On Error Goto 0 ' Always good to explicitly limit where error hiding occurs, but not necessary in this example
SetResult:
    RangeExists = tResult
End Function

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM