Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/mercurial/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在VBA中设置和使用空范围?_Vba_Excel - Fatal编程技术网

如何在VBA中设置和使用空范围?

如何在VBA中设置和使用空范围?,vba,excel,Vba,Excel,我希望以以下方式使用空范围: Set NewRange=Union(EmptyRange,SomeRange) 我曾尝试使用Nothing、empty和Null将empty范围设置为空范围,但出现了“运行时错误'5'无效过程调用或参数”,如果语句或有其他关键字执行此任务,我似乎必须使用 我可以使用: If EmptyRange Is Nothing Then Set NewRange = SomeRange Else Set NewRange = Union(EmptyRange,

我希望以以下方式使用空范围:

Set NewRange=Union(EmptyRange,SomeRange)

我曾尝试使用
Nothing
empty
Null
empty范围设置为空范围,但出现了“运行时错误'5'无效过程调用或参数”,如果
语句或有其他关键字执行此任务,我似乎必须使用

我可以使用:

If EmptyRange Is Nothing Then
   Set NewRange = SomeRange
Else
   Set NewRange = Union(EmptyRange, SomeRange)
End If
而不是建设:

Set NewRange = Union(EmptyRange, SomeRange)
Union()
方法至少需要2个命名范围。它将两个命名范围合并为一个主范围。如果您的真正目标是将
某个范围
空范围
相结合,那么您应该只写:

Set NewRange = SomeRange
使用
Union()
方法毫无意义,因为
Union()
需要两个定义的范围


我使用了一个额外的变量来解决这个问题。如果EmptyRange为Nothing,我没有使用,但是如果我的计数器j=0,那么NewRange=SomeRange。这是我的密码:

Public Sub copyLineData(line_array As Variant)
' Copys data from the line into the right sheet

Dim i As Integer
Dim j As Integer
Dim line As String
Dim rgn_data As Range
Dim rgn_selected As Range

Dim table_data As ListObject

Set rgn_data = getDynamicRangeFromSheet(Worksheets("Data"), "A1")
Set table_data = Sheets("Data").ListObjects.Add(xlSrcRange, rgn_data, xlListObjectHasHeaders:=xlYes)

' Get the selected rows
For i = 0 To ArrayLen(line_array) - 1
    line = line_array(i)
    ' Make selection
    table_data.Range.AutoFilter Field:=1, Criteria1:=line
    ' Copy data
    j = 0
    For Each Row In table_data.DataBodyRange.Rows
        If Row.EntireRow.Hidden = False Then
            If j = 0 Then
                Set rgn_selected = Row
            Else
                Set rgn_selected = Union(Row, rgn_selected)
            End If
             j = j + 1
        End If
    Next Row
    ' Copy selection
    rgn_selected.Copy Destination:=Sheets(line).Range("A1")
Next i
' Remove selection
table_data.Range.AutoFilter
' Convert back to range
table_data.Unlist
End Sub

当我需要组合多个
范围
对象时,我使用此函数来替代
应用程序.Union
,其中“零个或多个”范围可能是

Function union(ParamArray rgs() As Variant) As Range
  Dim i As Long
  For i = 0 To UBound(rgs())
    If Not rgs(i) Is Nothing Then
      If union Is Nothing Then Set union = rgs(i) Else Set union = Application.union(union, rgs(i))
    End If
  Next i
End Function
用法示例:

Sub demo_union()
  Dim rg1 As Range, rg2 As Range, rg3 As Range, newRg As Range
  Set rg1 = Range("A1")
  Set rg3 = Range("C3")
  Set newRg = union(rg1, rg2, rg3)
  newRg.Select
End Sub

下面是一个变体,不会在返回范围内复制重叠单元格

通常,当将重叠范围(例如,
A1:B2
B2:C3
)与
Application.Union
(或上述函数)组合时,结果将具有重叠单元格的多个副本

例如,使用,

↑ ...返回8单元格:
A1
B1
A2
B2
B2
C2
B3
C3

(每个循环的
将有8次迭代。)

函数union2(如下)通过只返回唯一的单元格来解决此问题,并且还处理空范围(不会产生令人讨厌的模糊的
“无效过程调用或参数”

↑ ...返回7单元格:
A1
B1
A2
B2
C2
B3
C3


对于每个
循环将有7次迭代。)

投反对票,没有任何评论?没有投反对票,但您的答案表明问题毫无意义,而事实并非如此。例如,如果您将单元格收集到循环中的某个范围内,您可能希望从空集开始,并开始在每次迭代中添加单元格。显然,你需要一个if结构来完成这项工作,它不那么优雅。
Application.Union([A1:B2], [B2:C3]).Cells.Count '8 cells (repeats B2)
Debug.Print union2([A1:B2], [B2:C3]).Cells.Count '7 cells