为什么我的行重复删除冻结

时间:2016-05-17 00:21:04

标签: arrays vba

Sub foo()
    Dim lastUsedRowDiff As Long
    Dim lastUsedColumnDiff As Long
    Dim myWrkbook As Workbook
    Dim mySheet As Worksheet
    Dim columnArray() As Integer
    Dim p As Integer

    lastUsedRowDiff = ActiveSheet.UsedRange.Columns.Count
    lastUsedColumnDiff = ActiveSheet.UsedRange.Columns.Count
    ReDim columnArray(1 To lastUsedColumnDiff)
    For p = 1 To lastUsedColumnDiff
        p = columnArray(p)
    Next
    ActiveSheet.Range(Cells(1, 1), Cells(lastUsedRowDiff,               lastUsedColumnDiff)).RemoveDuplicates _
    Columns:=Array(columnArray)

End Sub

1 个答案:

答案 0 :(得分:0)

我可能写的不只是支持建议,而是作为这个主题的教育。请仔细阅读,因为有关于“RemoveDuplicates”的重要信息。

我在整个代码中发表了评论,以解释我所看到的情况。 “为什么会冻结”核心问题的答案是因为你有一个无限循环。

Sub foo()
    Dim lastUsedRowDiff As Long
    Dim lastUsedColumnDiff As Long
    Dim myWrkbook As Workbook
    Dim mySheet As Worksheet
    Dim columnArray() As Integer
    Dim p As Integer

    'If you are finding the last used row and col you should also find the 
    'first used row as it may not always be 1
    'Dim LngFirstUsedCol     As Long
    'Dim LngFirstUsedRow     As Long
    'LngFirstUsedCol = ActiveSheet.UsedRange.Column
    'LngFirstUsedRow = ActiveSheet.UsedRange.Row

    'If this is for the row, it should take .Rows.count, not 'Columns.Count
    'lastUsedRowDiff = ActiveSheet.UsedRange.Rows.Count
    lastUsedRowDiff = ActiveSheet.UsedRange.Columns.Count
    lastUsedColumnDiff = ActiveSheet.UsedRange.Columns.Count

    'Also, the title of your varible refers to the difference but later they 
    'are used as the actual address
    'i.e. I have a range that has 1 column in it, but it is on column E (5), 
    'your code would return 1 which is right as I only have 1 column, but 
    'when using that as an address if refers to column A (1) which is not 
    'right We would need the address to be roughly: -
    ''First Used Column' + 'Used Column Count'

    'I am assuming this is trying to build an array of all the columns?
    'But is saying:-
    '   From P (which starts at 1) to the number of the last used column
    '       set P to 0
    '   Move to the next P (i.e. Increment it to back up to 1)
    'This is why you are stuck in a loop, turning them around would get past 
    'the issue to an extent
    ReDim columnArray(1 To lastUsedColumnDiff)
    For p = 1 To lastUsedColumnDiff
        p = columnArray(p)
        'columnArray(p) = p
    Next

    'The above code looks to include every column, by simply omitting the 
    ''Columns' parameter from the 'RemoveDuplicates' function, it would by 
    'default select all columns, so you could remove the For loop too
    'You did not need to place 'Array' around your array as it is already 
    'an array
    ActiveSheet.Range(Cells(1, 1), Cells(lastUsedRowDiff, lastUsedColumnDiff)).RemoveDuplicates Columns:=Array(columnArray)
    'ActiveSheet.Range(Cells(1, 1), Cells(lastUsedRowDiff, lastUsedColumnDiff)).RemoveDuplicates

    'In addition to the above, you should used the first row and column as 
    'well and not assume it is A1 (Cells(1,1))
    'ActiveSheet.Range(Cells(LngFirstUsedRow, LngFirstUsedCol), Cells(lastUsedRowDiff, lastUsedColumnDiff)).RemoveDuplicates

    'Finally as mentioned prior, you are using the difference as the address 
    'in error
    'ActiveSheet.Range(Cells(LngFirstUsedRow, LngFirstUsedCol), Cells(LngFirstUsedRow + (lastUsedRowDiff - 1), LngFirstUsedCol + (lastUsedColumnDiff))).RemoveDuplicates

    'Orrrr this whole proc can be reduced to a single line of three words
    ActiveSheet.UsedRange.RemoveDuplicates

End Sub

最后,这很重要,请阅读Richard Michaels中关于RemoveDuplicates的this thread所述内容。基本上,在VBA中它不是一个安全的函数,我建议手动编写代码来删除重复项或确保它保持在单个列范围的安全参数内,而不是传递Columns变量。