我正在尝试使用以下VBA代码来做两件事。
到目前为止:
Function UniqueVisible(MyRange As Range) As Integer
Dim ws As Worksheet
Set ws = Worksheets(1)
Dim R As Range
Dim V() As String
ReDim V(0 To MyRange.Count) As String
For Each R In MyRange
If (R.EntireRow.Hidden = False) Then
For Index = 0 To UniqueVisible
If (V(Index) = R.Value) Then
R.Delete
Exit For
End If
If (Index = UniqueVisible) Then
V(UniqueVisible) = R.Value
UniqueVisible = UniqueVisible + 1
End If
Next
End If
Next R
End Function
这很好,如果我用R.Delete
替换MsgBox(R.Row)
,我会得到重复的正确行号。
R.Delete
什么也没做。 R.EntireRow.Delete
什么都不做ws.Rows(R.Row).Delete
什么也没做。更新
这似乎无法正常工作
Function UniqueVisible(MyRange As Range) As Integer
Dim ws As Worksheet
Set ws = Worksheets(1)
Dim R As Range
Dim Dup As Integer
Dup = 0
Dim Dups() As Integer
ReDim Dups(0 To MyRange.Count) As Integer
Dim V() As String
ReDim V(0 To MyRange.Count) As String
For Each R In MyRange
If (R.EntireRow.Hidden = False) Then
For Index = 0 To UniqueVisible
If (V(Index) = R.Value) Then
Dups(Dup) = R.Row
Dup = Dup + 1
Exit For
End If
If (Index = UniqueVisible) Then
V(UniqueVisible) = R.Value
UniqueVisible = UniqueVisible + 1
End If
Next
End If
Next R
For Each D In Dups
ws.Rows(D).Delete
Next D
End Function
答案 0 :(得分:7)
看来你在这里违反了一些规则。
您无法使用功能删除VBA中的行。无论您是在工作表上使用该函数作为用户定义函数(也称为UDF)还是从VBA项目中的子函数调用它,都无关紧要。函数意味着返回一个值,而不是执行修改工作表上的结构(甚至是其自身单元格以外的值)的操作。在您的情况下,它可以返回要由子删除的行号数组。
从底部(或列的右侧)开始并在删除行时进行处理,这被认为是规范的做法。删除行时,从上到下可以跳过行,然后循环到下一行。
这是一个示例,其中一个子调用该函数来收集唯一的,可见的条目的数量以及要删除的行数组。
Sub remove_rows()
Dim v As Long, vDelete_These As Variant, iUnique As Long
Dim ws As Worksheet
Set ws = Worksheets(1)
vDelete_These = UniqueVisible(ws.Range("A1:A20"))
iUnique = vDelete_These(LBound(vDelete_These))
For v = UBound(vDelete_These) To (LBound(vDelete_These) + 1) Step -1 'not that we are working from the bottom up
ws.Rows(vDelete_These(v)).EntireRow.Delete
Next v
Debug.Print "There were " & iUnique & " unique, visible values."
End Sub
Function UniqueVisible(MyRange As Range)
Dim R As Range
Dim uniq As Long
Dim Dups As Variant
Dim v As String
ReDim Dups(1 To 1) 'make room for the unique count
v = ChrW(8203) 'seed out string hash check with the delimiter
For Each R In MyRange
If Not R.EntireRow.Hidden Then
If CBool(InStr(1, v, ChrW(8203) & R.Value & ChrW(8203), vbTextCompare)) Then
ReDim Preserve Dups(1 To UBound(Dups) + 1)
Dups(UBound(Dups)) = R.Row
Else
uniq = uniq + 1
v = v & R.Value & ChrW(8203)
End If
End If
Next R
Dups(LBound(Dups)) = uniq 'stuff the unique count into the primary of the array
UniqueVisible = Dups
End Function
现在,这可能不是我怎么做的。似乎更容易将整个事物写入单个子。但是,了解流程和限制非常重要,所以我希望您可以使用它。
请注意,不有任何错误控制。在处理数组和删除循环中的行时应该存在这种情况。
答案 1 :(得分:3)
在循环遍历行时,您无法删除行。您需要将需要删除的行存储在一个数组中,然后循环遍历该数组,并在遍历行循环后删除这些行。