使用 xlFilterValues 恢复自动筛选会引发错误 13 如果 Len(Criteria1(i))>255 类型不匹配?
Posted
技术标签:
【中文标题】使用 xlFilterValues 恢复自动筛选会引发错误 13 如果 Len(Criteria1(i))>255 类型不匹配?【英文标题】:Restoring AutoFilter with xlFilterValues raises error 13 Type mismatch if Len(Criteria1(i))>255? 【发布时间】:2018-09-12 23:51:43 【问题描述】:我继承了一些尝试在 Excel 2010-2016 中 save and restore filters 的 VBA 代码(我正在 Excel 2016 - 32 位、16.0.4549.1000 上进行测试)。我已经知道这是 pretty much impossible to do properly 并且以一种理智的方式(例如 Get Date Autofilter in Excel VBA),但它可能失败的不同方式的数量让我感到惊讶。
特别是一个xlFilterValues
过滤器,它选择值超过254个字符的单元格,似乎无法保存和恢复:
.Criteria1(i)
中的值在读取时被截断为 256 个字符,
如果您保存条件数组 (saved = .Criteria1
) 并稍后尝试通过.AutoFilter Criteria1:=saved ...
恢复它,.AutoFilter
将报告“运行时错误 '13' 类型不匹配”如果有 Len(saved(i) ) >= 256
下面列出了可以在空工作簿中运行的测试用例。
每个人都可以复制吗?对绕过此限制的简单方法有何想法?
Sub test()
Const CRITERIA_LEN = 257 ' 255 or less works, 256 throws error
Dim ws As Worksheet: Set ws = ActiveSheet
Dim filtRng As Range: Set filtRng = ws.Range(ws.Cells(1, 1), ws.Cells(5, 1))
Dim s100 As String: s100 = "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"
Const PREFIX_LEN = 2 ' the length of the "=X" prefix in Criteria1(i)
Dim longStr As String: longStr = Mid(s100 & s100 & s100, 1, CRITERIA_LEN - PREFIX_LEN)
ws.Cells(1, 1).Value2 = "header"
ws.Cells(2, 1).Value2 = "A" & longStr
ws.Cells(3, 1).Value2 = "B" & longStr
ws.Cells(4, 1).Value2 = "C" & longStr
ws.Cells(5, 1).Value2 = "another value"
If Not ws.AutoFilterMode Then
filtRng.AutoFilter
End If
SET_BREAKPOINT_HERE = 1
' after hitting the breakpoint use the autofilter to select the three long values by typing '123' into the autofilter search
Dim fs As Filters: Set fs = ws.AutoFilter.Filters
If Not fs.Item(1).On Then Exit Sub
Debug.Print "Operator = " & fs.Item(1).Operator ' should be xlFilterValues (7)
Debug.Print "Len(.Criteria1(1)) = " & Len(fs.Item(1).Criteria1(1)) ' this is never larger than 256
Debug.Print "Len(.Criteria1(2)) = " & Len(fs.Item(1).Criteria1(2))
Debug.Print "Len(.Criteria1(3)) = " & Len(fs.Item(1).Criteria1(3))
' Save the filter
Dim crit As Variant
crit = fs.Item(1).Criteria1
'crit = Array("=A" & longStr, "=B" & longStr, "=C" & longStr) ' This line has the same effect
ws.AutoFilter.ShowAllData ' reset the filter
' Try to restore
filtRng.AutoFilter Field:=1, _
Criteria1:=crit, _
Operator:=xlFilterValues
' => Run-time error '13' Type Mismatch
End Sub
【问题讨论】:
有趣的事实:我使用的是 Excel 2016(桌面)。运行宏后(没有更改),没有错误。但是,过滤器过滤掉了所有内容——不仅仅是原来的过滤行——所以不再有任何可见的数据。 @Mistella,感谢您的关注!只是为了确认一下,调试输出中有 Operator=7, Len(Criteria1(1/2/3))=256 吗? 是的。它是。我发现有趣的是结果的不同,因为(如果我理解正确的话)你得到一个运行时错误并且宏从未完成。虽然对我来说,宏已完成并过滤,但由于条件与任何“数据”都不匹配,因此这些行都不可见。 @Mistella,对。因此,我们都看到标准在读取时被截断(使工作变得不愉快),但尝试过滤长字符串对我们来说表现不同。我刚刚发现我的 Excel 版本已经快一年了,如果我用不同的版本得到不同的结果,我会更新这个问题。再次感谢! Excel 2016 (Desktop) 代码运行和过滤结果是 3* len 256 & 1* "another value" 的字符串。不得不注释掉 SET_BREAKPOINT_HERE = 1 所以不知道我是否遗漏了什么。 【参考方案1】:我今天也遇到了这个问题。真的很不幸,这有这个限制。我认为我们能做的最好的事情就是以下。
Function MakeValid(ByVal sSearchTerm as string) as string
if len(sSearchTerm) > 255 then
MakeValid = Left(sSearchTerm,254) & "*"
else
MakeValid = sSearchTerm
end if
End Function
Sub Test()
ActiveSheet.ListObjects("Table1").Range.AutoFilter Field:=1, Criteria1:= MakeValid(sSearchTerm), Operator:=Excel.XlAutoFilterOperator.xlFilterValues
End Sub
最终,它的工作方式是通过使用模式搜索绕过问题(因此匹配前 253 个字符,然后从那里搜索任何模式)。这并不总是奏效,事实上它在某些时候肯定不会奏效,但似乎这是我们拥有的最佳选择(除了围绕这个问题设计我们的系统)
似乎这也适用于数组:
Function MakeValid(ByVal sSearchTerm as string) as string
if len(sSearchTerm) > 255 then
MakeValid = Left(sSearchTerm,254) & "*"
else
MakeValid = sSearchTerm
end if
End Function
Sub Test()
Dim i as long
for i = lbound(sSearchTerms) to ubound(sSearchTerms)
sSearchTerms(i) = MakeValid(sSearchTerms(i))
next
ActiveSheet.ListObjects("Table1").Range.AutoFilter Field:=1, Criteria1:= sSearchTerms, Operator:=Excel.XlAutoFilterOperator.xlFilterValues
End Sub
这是一个糟糕的解决方案,但它有点工作
【讨论】:
对我来说,仅当Criteria1
是长度Criteria1:=Array("=foo*", "=bar*", "=baz*") 不会为我选择“foo123”...跨度>
@Nickolay 感谢您提出这个问题。我会检查一下,因为我也担心可能是这种情况,但没有完全测试。以上是关于使用 xlFilterValues 恢复自动筛选会引发错误 13 如果 Len(Criteria1(i))>255 类型不匹配?的主要内容,如果未能解决你的问题,请参考以下文章