我在Excel 2003中遇到一个奇怪的问题,在搜索隐藏的单元格中的值和过滤范围的一部分时,Range.Find方法失败.
要清楚,这是有问题的方法调用:
Cells.Find(SearchString, LookIn:=xlFormulas, LookAt:=xlWhole)
Run Code Online (Sandbox Code Playgroud)
各种Excel网站和论坛上的许多消息来源都声称指定"LookIn:= xlFormulas"将强制Range.Find在隐藏单元格内进行搜索.虽然没有意义,但如果SearchString位于仅隐藏的单元格中,那似乎也是如此.如果单元格既隐藏又是过滤范围的一部分,则会失败.
请注意,过滤器是否隐藏了单元格并不重要.例如,您可以搜索过滤范围的标题(过滤器本身永远不会隐藏),但如果该标题恰好位于您隐藏的列中,则Range.Find将失败.
是否有任何Excel方法可以可靠地搜索单元格而不考虑它们是否恰好被隐藏和/或过滤器的一部分?
将过滤范围的值复制到数组似乎没有问题:然后该数组包含来自过滤和未过滤单元格的值。但是,当我将数组的内容复制回过滤范围时,结果对我来说是不可理解的。
这是我的代码:
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代码,它应该在Excel中保存和恢复当前的AutoFilter状态.我一直在使用这里的代码没有任何问题,但现在我遇到了一个非常严重的问题.让我说明......
假设您有一个(非常简单的)表设置日期过滤:

如果您希望以编程方式使用过滤条件,则会失败:

这在Excel 2010中正在发生.有谁知道解决方法吗?
Microsoft TechNet上其他人描述的同一问题的链接:当运算符为日期的xlFilterValues时,Excel VBA AutoFilter条件这指向Jon von der Heyden的网站以获得解决方案,但该网站提到:
未知(可能是日期TreeView过滤器):到目前为止,我无法找到捕获日期过滤器的方法,其中条件基于"过滤器"下拉列表中"树视图"控件的选择.这些条件不存储在Criteria1或Criteria2属性中.我想,制定标准将涉及循环Range_Field值.虽然这首先要求关闭所有其他字段过滤器,但是工作表函数无法执行某些操作,并且会涉及触发子例程的计时器.我再次选择避免额外的复杂性.
这个问题现在得到了优雅的回答,感谢Chris Neilsen,请看下面的答案.这是我将从现在开始使用的那个.该解决方案可靠地查找工作表中的最后一个单元格,即使单元格被过滤器,组或本地隐藏行隐藏.
讨论可能对一些人有用,所以我也提供了我自己的代码的优化版本.它演示了如何保存和恢复过滤器,使用@ Chis的想法查找最后一行,并在一个简短的Variant数组中记录隐藏行范围,最终从中恢复它们.
还可以在此处下载探索和测试所讨论的所有解决方案的测试工作簿.
这里和其他地方有很多关于在Excel工作表中查找最后一个单元格的讨论.该Range.SpecialCells方法有局限性,并不总能找到真正的最后一个单元格.如果Worksheet.AutoFilters处于活动状态,则尤其如此.下面的代码解决了问题并返回了正确的结果,即使过滤器处于活动状态,单元格被分组和隐藏,或者行或列被隐藏使用隐藏/取消隐藏.但是,该方法并不简单.有人知道一种始终可靠的更好的方法吗?
"真正的最后一个单元格"被理解为包含数据或公式的最后一行与包含它们的最后一列的交集.格式化可能会超出它.
下面的代码在我的Excel 2010应用程序中测试和工作,并要求在VBIDE中引用Scripting.Runtime.它包含内联注释,记录它正在做什么以及为什么.此外,变量名称是故意解释的.对不起,但这让他们很长.
在某些情况下,它可能无法恢复调用时隐藏的确切行.我从未发生过这种情况.
感谢2016年1月3日的3种响应者.
这是继brettdj之后标记问题已经回答的问题.遗憾的是,我不相信这是真的.至少,除非UsedRange在所有情况下都可以信任.尽管SpecialCells的问题很难再现,但是之前对SpecialCells提供的价值观的体验不鼓励对它们的依赖.
brettdj的帖子返回从A1到最后一个使用过的单元格的范围提供了一个解决方案GetRange.它是其中之一,但似乎显然是最好的.我已经测试了它以及该线程中提出的所有解决方案.在我的测试中,当过滤器处于活动状态而没有信任时,它们都没有能够找到最后一个单元格UsedRange. brettdj,声誉很高,显然不这么认为,但在我看来,我确实发现了一个真正的问题.
展示:
请参阅以下测试表.在此视图中公开所有行和列.请注意第19行,其中包含H19中"用过滤器隐藏的行"文本.另请注意,B20第20行和J11第J列有信息.(显然,由于这是一个测试,J20中没有任何内容,其参考是该问题的正确答案):

测试在上面的工作表上运行,但过滤器处于活动状态(由下图中的红色圆圈强调),从视图中删除第19行.在测试期间,柱组J:K被折叠,但是19:20的Row Group仍然可见.
这些是结果(真正的答案是J20):
Gettrange()由brettdj在引用的答案中给出"范围是A1:B20".TrueLastCell()由Gary的学生给出"真正的最后一个单元格是B20"并且有时可能非常昂贵,如果UsedRange到达一个很大空的工作表的末尾,则从非常高的行和列数循环.(此外,答案中的屏幕显示C11,应该是F11.)GetTrueLastCell(WS)通过PatrickK获得正确的答案,J20但它完全依赖于UsedRange,我理解这是不可能的,或者我永远不会开始这个!GetTrueLastCell(WS,,) (通过我,下面的代码虽然很复杂)给出$ 20 $.在不太可能的情况下,这是特定于操作系统,我的测试是在{你不允许笑 - :)} Vista Home Premium.我的理由是它是一台闪电般快速的8核机器上的64Bit操作系统,即使它已经老化了.Excel 2010,32位版本14.0.7166.5000.
为响应chris neilsen的验证请求和测试文件上传,它不再在这里.简短的回答是:在运行Office 2013 15.0.4797.1003以及Vista …
我正在开发一个 Excel 2016 VBA 宏,它将过滤器应用于标题列。然后,用户应用过滤条件。我希望能够在 VBA 中检索用户应用的过滤条件并将其保存到字符串数组中。有没有办法访问过滤条件?