2013-08-28 2 views
0

У меня есть набор записей ADO, содержащий таблицу продуктов. У меня есть список продуктов, используемых для фильтрации таблицы - динамически строит фильтр, как это (но больше):Получите дополнение отфильтрованных элементов с помощью набора записей 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' " 

, но я проблемы с отрицательным фильтром (тот, чтобы найти исключенные элементы). Ниже не допускается из-за 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.

Первое решение, как правило, самое лучшее. Просто создайте этот фильтр/где в SQL-запрос и снова запросите источник данных.

Второй вариант неэффективен, но работает ОК на небольших наборах записей. Это функция, которую я написал, которая возвращает Filtered recordset. То, что вам нужно сделать, это вызвать его несколько раз, один раз для каждого рабочего фильтра (если это имеет смысл), чтобы вы получили нужные результаты. Я не знаю, как это будет работать с подключенным набором записей. Я использую его только с отключенными наборами записей.

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 
Смежные вопросы