将数组复制到过滤范围会产生不合理的结果

时间:2012-04-15 02:30:10

标签: excel excel-vba excel-2010 vba

将过滤范围的值复制到数组似乎没有问题:然后数组包含来自过滤和未过滤单元格的值。但是,当我将数组的内容复制回过滤范围时,结果对我来说是不可理解的。

这是我的代码:

Sub test()
    Dim rangecopy() As Variant

    rangecopy() = Range(Cells(2, 1), Cells(14, 3)).Value
    For c = LBound(rangecopy, 1) To UBound(rangecopy, 1)
        rangecopy(c, 1) = c
        rangecopy(c, 2) = c * 10
        rangecopy(c, 3) = c * 100
    Next
    Range(Cells(2, 1), Cells(14, 3)).Value = rangecopy()
End Sub

应该给出以下结果。这里,当宏将数组复制到它时,范围是未过滤的。

Imgur

如果范围按列D过滤(“NO”被过滤掉),结果如下:

Imgur

首先,不更新过滤的单元格。然后,来自B列的大多数单元格从数组的第一列(4,5,6)获取值,而其他一些单元格正确地从数组的第二列获取值(10)。最后两行填充#N / A错误。这应该是那样的吗?我正在使用Office 2010。

1 个答案:

答案 0 :(得分:1)

我真的希望有了解VBA内部工作原理的人能够提供更多有关您问题的见解。我可以分享以下内容:

首先,它按预期工作。但是,我不知道为什么这是设计,也不知道在分配过程中究竟发生了什么。

有很多情况会产生类似的问题。例如,如果您打开过滤器(某些行被隐藏)并尝试填充(拖动)公式,您将看到类似的结果,因为未填充隐藏的行,但它们会影响(相对)引用在公式。另一方面,如果手动复制并粘贴到过滤范围内,数据将粘贴到隐藏的行中(如您所愿)。

似乎引用的任何范围都是Autofilter范围的一部分,实际上是非连续的*。使用Range.Address并不总是显示这一点,也不会通过Range.Areas循环。如果我们修改您的示例,我们可以看到“真正的”错误在哪里:

Dim r1 as range
Dim r2 as range

Set r1 = Sheet1.Range("A1:B5") 'some numbers in a range
Set r2 = Sheet2.Range("A2:B6") 'same-size range underneath a filtered header

r1.Copy Destination:=r2

当所有行都可见时,它会起作用。当Sheet2上的过滤器创建隐藏行时,结果为“运行时错误'1004':...复制区域和粘贴区域的大小和形状不同。”另一方面,使用“手动”/剪贴板方法适用于隐藏行:

r1.Copy    
r2.PasteSpecial (xlPasteValues)

由于将一个数组分配给一个范围会绕过剪贴板(如第一个程序段),我们应该收到一个错误(相反,你最终会得到错误的结果)。

我所知道的唯一解决方案是遍历范围并为每个单元格分配一个值:

For i = 1 to LastRow
  For j = 1 to LastCol
    Sheet1.Cells(i,j).Value = myArr(i,j)
  Next
Next

或(更好)删除自动过滤器,将数组指定给范围,然后重新应用过滤器。

*从技术上讲它是连续的,所以最好说范围由几个范围/区域组成,尽管使用.Address并不表示这一点,当你尝试循环Range.Areas时只有一个区域