0

我有一个包含产品表的 ADO 记录集。我有一个用于过滤表格的产品列表 - 像这样动态构建一个过滤器(但更长):

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' "

但我遇到了负面过滤器(查找排除项目的过滤器)的问题。由于ADO Recordset Filter 中嵌套 OR 的限制,不允许执行以下操作:

rs2.Filter = "productType <> 'product A' " _
+ "and (productType <> 'product B' or expiry <> 16/08/2013) " _
+ "and productType <> 'product C' "

有替代解决方案吗?例如某种方式来获得过滤器的补充(即只是它排除的行)?

我应该强调 - 要包含的产品列表是动态构建的,在编写代码时它对我不可用。

4

1 回答 1

0

I work with ADO quite a bit and I have found only two solutions to work around this limitation in ADO.

The first solution is usually the best one. Just build this filter/where into an SQL statement and query the data source again.

The second option is inefficient but works OK on smaller recordsets. It's a function I wrote that returns a Filtered recordset. What you have to do is call it several times, one time for each working filter (if that makes any sense) so that you end up with the results you want. I don't know how this would work with a connected recordset. I only ever use it with disconnected recordsets.

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
于 2013-09-26T02:56:51.413 回答