用很多话来解释一个非常简单的问题:
为什么 VBA 对范围变量中如此少的区域感到不安?
当我尝试对两个范围变量进行并集时,结果仅将第二个变量的一些附加到第一个变量上。
显然我已经达到了大小限制,但如果我能找到它就好了。
========================================
我在 Office 365 中使用 Excel 2405(内部版本 17628.20188)。
测试结果在这里,并附上代码。基本上“设置 Rx3 = Union(Rx1, Rx2)”,x =[1,2,3,4]
Union 在 R11 和 R12 等小型测试范围(每个测试范围有 3 个区域)中工作得很好。 R13 正确等于所有 6 个区域:
Set R11 = ws.Range("$B$49:$C$49,$C$50:$C$53,$B$54:$C$54")
Set R12 = ws.Range("$A$55:$C$55,$C$56:$C$59,$B$60:$C$60")
Set R13 = Union(R11, R12)
R13:
$B$49:$C$49,$C$50:$C$53,$B$54:$C$54,$A$55:$C$55,$C$56:$C$59,$B$60:$C$60
========================================
但是对于我关心的范围(R21 和 R22),结果仅添加 R22 的第一个one区域($A$55:$C$55) 到 R21 的末尾(无错误消息):
Set R21 = ws.Range("$A$4:$C$4,$C$5:$C$8,$B$9:$C$9,$C$10:$C$13,$B$14:$C$14,$C$15:$C$18,$B$19:$C$19,$C$20:$C$23, _
$B$24:$C$24,$C$25:$C$28,$B$29:$C$29,$C$30:$C$33,$B$34:$C$34,$C$35:$C$38,$B$39:$C$39,$C$40:$C$43, _
$B$44:$C$44,$C$45:$C$48,$B$49:$C$49,$C$50:$C$53,$B$54:$C$54")
Set R22 = ws.Range("$A$55:$C$55,$C$56:$C$59,$B$60:$C$60,$C$61:$C$64,$B$65:$C$65,$C$66:$C$69,$B$70:$C$70,$C$71:$C$74, _
$B$75:$C$75,$C$76:$C$79,$B$80:$C$80,$C$81:$C$84,$B$85:$C$85,$C$86:$C$89,$B$90:$C$90,$C$91:$C$94, _
$B$95:$C$95,$C$96:$C$99,$B$100:$C$100,$C$101:$C$104")
Set R23 = Union(R21, R22)
R23:
$A$4:$C$4,$C$5:$C$8,$B$9:$C$9,$C$10:$C$13,$B$14:$C$14,$C$15:$C$18,$B$19:$C$19,$C$20:$C$23,$B$24:$C$24, _
$C$25:$C$28,$B$29:$C$29,$C$30:$C$33,$B$34:$C$34,$C$35:$C$38,$B$39:$C$39,$C$40:$C$43,$B$44:$C$44,$C$45:$C$48, _
$B$49:$C$49,$C$50:$C$53,$B$54:$C$54,$A$55:$C$55
========================================
R31 = R21 没有最后一个区域 $B$54:$C$54,现在 R33 具有从 R32 = R22 附加到 R31 的前两个区域, 55 美元:55 美元加元,56 美元加元:59 美元加元:
Set R31 = ws.Range("$A$4:$C$4,$C$5:$C$8,$B$9:$C$9,$C$10:$C$13,$B$14:$C$14,$C$15:$C$18,$B$19:$C$19,$C$20:$C$23, _
$B$24:$C$24,$C$25:$C$28,$B$29:$C$29,$C$30:$C$33,$B$34:$C$34,$C$35:$C$38,$B$39:$C$39,$C$40:$C$43,$B$44:$C$44, _
$C$45:$C$48,$B$49:$C$49,$C$50:$C$53")
Set R32 = ws.Range("$A$55:$C$55,$C$56:$C$59,$B$60:$C$60,$C$61:$C$64,$B$65:$C$65,$C$66:$C$69,$B$70:$C$70,$C$71:$C$74, _
$B$75:$C$75,$C$76:$C$79,$B$80:$C$80,$C$81:$C$84,$B$85:$C$85,$C$86:$C$89,$B$90:$C$90,$C$91:$C$94,$B$95:$C$95, _
$C$96:$C$99,$B$100:$C$100,$C$101:$C$104")
Set R33 = Union(R31, R32)
R33:
$A$4:$C$4,$C$5:$C$8,$B$9:$C$9,$C$10:$C$13,$B$14:$C$14,$C$15:$C$18,$B$19:$C$19,$C$20:$C$23,$B$24:$C$24, _
$C$25:$C$28,$B$29:$C$29,$C$30:$C$33,$B$34:$C$34,$C$35:$C$38,$B$39:$C$39,$C$40:$C$43,$B$44:$C$44,$C$45:$C$48, _
$B$49:$C$49,$C$50:$C$53,$A$55:$C$55,$C$56:$C$59
========================================
最后,当 R41 是 R21 和 R22 的剪切和粘贴并集时,VBA 会抛出错误:
Set R41 = Range("$A$4:$C$4,$C$5:$C$8,$B$9:$C$9,$C$10:$C$13,$B$14:$C$14,$C$15:$C$18,$B$19:$C$19,$C$20:$C$23, _
$B$24:$C$24,$C$25:$C$28,$B$29:$C$29,$C$30:$C$33,$B$34:$C$34,$C$35:$C$38,$B$39:$C$39,$C$40:$C$43,$B$44:$C$44, _
$C$45:$C$48,$B$49:$C$49,$C$50:$C$53,$B$54:$C$54,$A$55:$C$55,$C$56:$C$59,$B$60:$C$60,$C$61:$C$64,$B$65:$C$65, _
$C$66:$C$69,$B$70:$C$70,$C$71:$C$74,$B$75:$C$75,$C$76:$C$79,$B$80:$C$80,$C$81:$C$84,$B$85:$C$85,$C$86:$C$89, _
$B$90:$C$90,$C$91:$C$94,$B$95:$C$95,$C$96:$C$99,$B$100:$C$100,$C$101:$C$104")
“运行时错误‘1004’:对象‘_Global’的方法‘Range’失败
========================================
如有任何建议,我们将不胜感激!
========================================
```
Sub Foo()
Dim ws As Worksheet
Set ws = Worksheets("DATA")
ws.Activate
Dim R11, R12, R13, R21, R22, R23, R31, R32, R33, R41 As Range
Set R11 = ws.Range("$B$49:$C$49,$C$50:$C$53,$B$54:$C$54")
Set R12 = ws.Range("$A$55:$C$55,$C$56:$C$59,$B$60:$C$60")
Set R13 = Union(R11, R12)
MsgBox "R11: " & vbNewLine & R11.Address
MsgBox "R12: " & vbNewLine & R12.Address
MsgBox "R13: " & vbNewLine & R13.Address
Set R21 = ws.Range("$A$4:$C$4,$C$5:$C$8,$B$9:$C$9,$C$10:$C$13,$B$14:$C$14,$C$15:$C$18,$B$19:$C$19,$C$20:$C$23, _
$B$24:$C$24,$C$25:$C$28,$B$29:$C$29,$C$30:$C$33,$B$34:$C$34,$C$35:$C$38,$B$39:$C$39,$C$40:$C$43, _
$B$44:$C$44,$C$45:$C$48,$B$49:$C$49,$C$50:$C$53,$B$54:$C$54")
Set R22 = ws.Range("$A$55:$C$55,$C$56:$C$59,$B$60:$C$60,$C$61:$C$64,$B$65:$C$65,$C$66:$C$69,$B$70:$C$70,$C$71:$C$74, _
$B$75:$C$75,$C$76:$C$79,$B$80:$C$80,$C$81:$C$84,$B$85:$C$85,$C$86:$C$89,$B$90:$C$90,$C$91:$C$94, _
$B$95:$C$95,$C$96:$C$99,$B$100:$C$100,$C$101:$C$104")
Set R23 = Union(R21, R22)
MsgBox "R21: " & vbNewLine & R21.Address
MsgBox "R22: " & vbNewLine & R22.Address
MsgBox "R23: " & vbNewLine & R23.Address
Set R31 = ws.Range("$A$4:$C$4,$C$5:$C$8,$B$9:$C$9,$C$10:$C$13,$B$14:$C$14,$C$15:$C$18,$B$19:$C$19,$C$20:$C$23, _
$B$24:$C$24,$C$25:$C$28,$B$29:$C$29,$C$30:$C$33,$B$34:$C$34,$C$35:$C$38,$B$39:$C$39,$C$40:$C$43,$B$44:$C$44, _
$C$45:$C$48,$B$49:$C$49,$C$50:$C$53")
Set R32 = ws.Range("$A$55:$C$55,$C$56:$C$59,$B$60:$C$60,$C$61:$C$64,$B$65:$C$65,$C$66:$C$69,$B$70:$C$70,$C$71:$C$74, _
$B$75:$C$75,$C$76:$C$79,$B$80:$C$80,$C$81:$C$84,$B$85:$C$85,$C$86:$C$89,$B$90:$C$90,$C$91:$C$94,$B$95:$C$95, _
$C$96:$C$99,$B$100:$C$100,$C$101:$C$104")
Set R33 = Union(R31, R32)
MsgBox "R31: " & vbNewLine & R31.Address
MsgBox "R32: " & vbNewLine & R32.Address
MsgBox "R33: " & vbNewLine & R33.Address
Set R41 = ws.Range("$A$4:$C$4,$C$5:$C$8,$B$9:$C$9,$C$10:$C$13,$B$14:$C$14,$C$15:$C$18,$B$19:$C$19,$C$20:$C$23, _
$B$24:$C$24,$C$25:$C$28,$B$29:$C$29,$C$30:$C$33,$B$34:$C$34,$C$35:$C$38,$B$39:$C$39,$C$40:$C$43, _
$B$44:$C$44,$C$45:$C$48,$B$49:$C$49,$C$50:$C$53,$B$54:$C$54,$A$55:$C$55,$C$56:$C$59,$B$60:$C$60, _
$C$61:$C$64,$B$65:$C$65,$C$66:$C$69,$B$70:$C$70,$C$71:$C$74,$B$75:$C$75,$C$76:$C$79,$B$80:$C$80, _
$C$81:$C$84,$B$85:$C$85,$C$86:$C$89,$B$90:$C$90,$C$91:$C$94,$B$95:$C$95,$C$96:$C$99,$B$100:$C$100, _
$C$101:$C$104")
End Sub
```
当您使用
Union
时,Excel 会正确定义范围。只有 address
属性有限制。对于定义范围(就像您对R41
所做的那样)如此,对于阅读它也是如此。
您可以通过计算单元格数量等方式轻松检查 Excel 是否正确设置范围。我检查了你的范围 R21..R23
Debug.Print R21.Cells.Count
Debug.Print R22.Cells.Count
Debug.Print R23.Cells.Count
这导致了
63
61
124
请注意,如果 R21 和 R22 具有重叠单元格,则单元格总数可能小于 R21 和 R22 单元格计数的总和,但此处情况并非如此。所以显然 R23 包含 R21 和 R22 的所有单元格(124 = 63+61)。
如果您确实需要字符串形式的地址,请使用如下所示的小函数。它将连接一个范围的所有子范围的所有地址 - 可以使用范围的
Areas
属性来访问子范围。
Function myAddress(r As Range) As String
Dim a As Long
For a = 1 To r.Areas.Count
myAddress = myAddress & IIf(a = 1, "", ",") & r.Areas(a).Address
Next a
End Function
注意
在 VBA 中,如果使用一条 Dim 语句声明多个变量,则需要分别为每个变量提供数据类型。你的发言
Dim R11, R12, R13, R21, R22, R23, R31, R32, R33, R41 As Range
只会将
R41
声明为Range,所有其他的都将是Variant类型。在这种情况下没什么大不了的,因为 Variant 可以容纳“任何东西”,包括 Range 引用。但是,当例程需要 Range 作为参数并且您传递 Variant 时,它可能会导致奇怪的错误。所以你需要写
Dim R11 As Range, R12 As Range, R13 As Range (...)