从 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.Intersect
和 Range.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
这看起来应该很容易执行,但我一直找不到合适的命令或技巧。
在我的宏中,我在循环中使用范围和新行之间的联合系统地生成行范围:
Set DesiredRange = Union(DesiredRange, ActiveSheet.Cells(Val(ParsedText(Count)), 1).EntireRow)
但是,为了使这个联合起作用,我必须先将 DesiredRange
设置为某个范围,这样联合才不会出错。
我遇到的问题是我需要排除某些行号,但是这些行是从允许用户输入他们想要的任何内容的用户表单文本框中选择的(我已经在错误控制中编码所以传递的值是有效的),因此他们可以假设第一个值(因此我用来初始化范围的值)是一个被排除的行。
我希望这里有人可以提供一个解决方案,让我可以完成所有操作,然后从范围中删除第一个添加的行(如果它在排除的类别(第 1 到 7 行)内)。如果没有,我想我可能有一个解决方法(但我的一部分是问这个问题更多的是为了教育而不是解决问题)
谢谢!
我想你想要像 Range.Except
这样的函数来补充 Range.Intersect
和 Range.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