从 VBA 中的联合生成的行范围中删除一行

Removing a row from a Range of Rows generated by Unions in VBA

这看起来应该很容易执行,但我一直找不到合适的命令或技巧。

在我的宏中,我在循环中使用范围和新行之间的联合系统地生成行范围:

Set DesiredRange = Union(DesiredRange, ActiveSheet.Cells(Val(ParsedText(Count)), 1).EntireRow)

但是,为了使这个联合起作用,我必须先将 DesiredRange 设置为某个范围,这样联合才不会出错。

我遇到的问题是我需要排除某些行号,但是这些行是从允许用户输入他们想要的任何内容的用户表单文本框中选择的(我已经在错误控制中编码所以传递的值是有效的),因此他们可以假设第一个值(因此我用来初始化范围的值)是一个被排除的行。

我希望这里有人可以提供一个解决方案,让我可以完成所有操作,然后从范围中删除第一个添加的行(如果它在排除的类别(第 1 到 7 行)内)。如果没有,我想我可能有一个解决方法(但我的一部分是问这个问题更多的是为了教育而不是解决问题)

谢谢!

我想你想要像 Range.Except 这样的函数来补充 Range.IntersectRange.Union 但据我所知 VBA 没有内置这样的函数,你会必须自己编码。类似下面的内容将执行您想要的操作并自动从 Union 中排除不需要的行。变量 strRowsToExclude 可能会从您的表单传递给方法:

Sub Test()

    Dim rngTarget As Range
    Dim strRowsToExclude As String
    Dim varRowsToExclude As Variant
    Dim intCounter1 As Integer
    Dim intCounter2 As Integer
    Dim blnDoNotAdd  As Boolean

    Set rngTarget = Nothing
    strRowsToExclude = "1,4,45,87,88,99"
    varRowsToExclude = Split(strRowsToExclude, ",")

    For intCounter1 = 1 To 100
        blnDoNotAdd = False
        For intCounter2 = 0 To UBound(varRowsToExclude)
            If intCounter1 = Val(varRowsToExclude(intCounter2)) Then
                blnDoNotAdd = True
            End If
        Next intCounter2
        If blnDoNotAdd = False Then
            If rngTarget Is Nothing Then
                Set rngTarget = Sheet1.Cells(intCounter1, 1).EntireRow
            Else
                Set rngTarget = Union(rngTarget, Sheet1.Cells(intCounter1, 1).EntireRow)
            End If
        End If
    Next intCounter1

    rngTarget.Select

End Sub

你可以这样做:

Option Explicit

Sub main()
    Dim desiredRng As Range, forbiddenRows As Range, cell As Range
    Dim rowsStrng As String
    Dim i As Long

    With ActiveSheet
        Set forbiddenRows = .Range("1:1, 3:5, 7:7, 9:11") '<~~ set forbidden rows, you can use multiple rows sintax            
        For i = 1 To 10 '<~~ this is your "Union" loop, 
            ' do stuff to get to following line
            Set cell = .Cells(Val(ParsedText(Count)), 1)
            If Intersect(cell, forbiddenRows) Is Nothing Then rowsStrng = rowsStrng & cell.Row & ":" & cell.Row & "," '<~~ add row index only if not forbidden
        Next i
        If rowsStrng <> "" Then Set desiredRng = .Range(Left(rowsStrng, Len(rowsStrng) - 1))
    End With
End Sub

扩展 Rory 的评论:

Dim DesiredRange As Range, rng As Range

'...in your loop
Set rng = ActiveSheet.Cells(Val(ParsedText(Count)), 1).EntireRow
If DesiredRange Is Nothing Then
    Set DesiredRange = rng
Else
    Set DesiredRange = Application.Union(DesiredRange, rng)
End If