我有一个包含产品表的ADO Recordset。 我有一个用于过滤表的产品列表 - 动态构建像这样的过滤器(但更长):
rs.Filter = "productType = 'product A' " _
+ "or productType = 'product B' " _
+ "or productType = 'product C' "
这对我来说很好,我将过滤后的行复制到一个单独的工作表中,一切正常。
然后新项目要求意味着我还需要获取排除的项目。很好,我做了一些布尔代数,并使用相反的过滤器运行相同的查询:
rs2.Filter = "productType <> 'product A' " _
+ "and productType <> 'product B' " _
+ "and productType <> 'product C' "
这也很好。我将排除的项目复制到另一个工作表中,所以现在我同时包含已包含和已排除的项目。
但是新要求意味着我必须应对特殊情况 - 产品B仅包含在特定日期。现在,这适用于正面过滤器,可以找到包含项目:
rs.Filter = "productType = 'product A' " _
+ "or (productType = 'product B' and expiry = 16/08/2013) " _
+ "or productType = 'product C' "
但是我遇到了负面过滤器(找到排除项目的问题)的问题。由于restriction on nested OR's in ADO Recordset Filter:
,不允许以下内容rs2.Filter = "productType <> 'product A' " _
+ "and (productType <> 'product B' or expiry <> 16/08/2013) " _
+ "and productType <> 'product C' "
有替代解决方案吗? 例如。某种方式来获得过滤器的补充(即只是它排除的行)?
我应该强调 - 要包含的产品列表是动态构建的,在编写代码时我无法使用。
答案 0 :(得分:0)
我与ADO合作很多,我发现只有两种解决方案可以解决ADO中的这种限制。
第一种解决方案通常是最好的解决方案。只需将此过滤器/ where构建到SQL语句中并再次查询数据源。
第二个选项效率低,但在较小的记录集上运行正常。这是我写的一个返回Filtered记录集的函数。你需要做的就是多次调用它,每次调试一次(如果有意义的话),这样你最终得到你想要的结果。我不知道这对连接的记录集有什么用处。我只使用断开连接的记录集。
Public Function GetFilteredRecordset(ByRef rsSource As ADODB.Recordset, _
ByVal sWhere As String, _
Optional ByVal sOrderBy As String, _
Optional ByVal LockType As ADODB.LockTypeEnum = adLockUnspecified) As ADODB.Recordset
Dim sOriginalOrderBy As String
sOriginalOrderBy = rsSource.Sort
rsSource.Filter = sWhere
If sOrderBy <> "" Then
If Left(LCase(sOrderBy), 8) = "order by" Then sOrderBy = Trim(Right(sOrderBy, Len(sOrderBy) - 8))
rsSource.Sort = sOrderBy
End If
Dim objStream As ADODB.Stream
Set objStream = New ADODB.Stream
rsSource.Save objStream, adPersistXML
Dim rsF As ADODB.Recordset
Set rsF = New ADODB.Recordset
rsF.Open objStream, , , LockType
rsSource.Filter = ""
rsSource.Sort = sOriginalOrderBy
objStream.Close
Set objStream = Nothing
Set GetFilteredRecordset = rsF
End Function