Cut*_*ter 5 excel vba excel-2010
将过滤范围的值复制到数组似乎没有问题:然后该数组包含来自过滤和未过滤单元格的值。但是,当我将数组的内容复制回过滤范围时,结果对我来说是不可理解的。
这是我的代码:
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
Run Code Online (Sandbox Code Playgroud)
它应该给出以下结果。在这里,当宏将数组复制到其中时,该范围未被过滤。

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

首先,过滤后的单元格不会更新。然后,B 列中的大多数单元格从数组的第一列获取值 (4、5、6),而其他一些单元格则从数组的第二列正确获取值 (10)。最后两行充满#N/A 错误。这应该是这样的吗?我正在使用 Office 2010。
我真的希望了解 VBA 内部工作原理的人能够对您的问题提供更多见解。我可以分享以下内容:
首先,它正在按预期工作。但是,我不知道为什么会这样设计,也不知道分配过程中究竟发生了什么。
有很多案例都会产生类似的问题。例如,如果您打开过滤器(某些行被隐藏)并尝试向下填充(拖动)公式,您将看到类似的结果,因为隐藏的行未填充,但它们确实会影响(相对)引用在公式。另一方面,如果您手动复制并粘贴到筛选范围,数据将粘贴到隐藏行(如您所愿)。
似乎作为自动筛选范围一部分的任何引用范围实际上都是不连续的*。使用 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
Run Code Online (Sandbox Code Playgroud)
当所有行都可见时它起作用。当 Sheet2 上的过滤器创建隐藏行时,结果是“运行时错误‘1004’:...复制区域和粘贴区域的大小和形状不同。” 另一方面,使用“手动”/剪贴板方法适用于隐藏行:
r1.Copy
r2.PasteSpecial (xlPasteValues)
Run Code Online (Sandbox Code Playgroud)
由于将数组分配给范围会绕过剪贴板(如第一个块中所示),因此我们应该收到错误(而不是最终得到错误的结果)。
我知道的唯一解决方案是循环遍历范围并为每个单元格分配一个值:
For i = 1 to LastRow
For j = 1 to LastCol
Sheet1.Cells(i,j).Value = myArr(i,j)
Next
Next
Run Code Online (Sandbox Code Playgroud)
或者(更好)删除自动筛选器,将数组分配给范围,然后重新应用筛选器。
*从技术上讲,它是连续的,因此最好说该范围由多个范围/区域组成,尽管使用 .Address 并不表明这一点,并且当您尝试循环 Range.Areas 时只有一个区域