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

私は ADO をかなり使用していますが、ADO でこの制限を回避する解決策は 2 つしか見つかりませんでした。

通常、最初のソリューションが最適です。この filter/where を SQL ステートメントに組み込み、データ ソースに対して再度クエリを実行するだけです。

2 番目のオプションは非効率的ですが、小さなレコードセットでは問題なく機能します。Filtered レコードセットを返すのは、私が書いた関数です。あなたがしなければならないことは、あなたが望む結果になるように、機能するフィルターごとに1回(それが意味がある場合)、それを数回呼び出すことです。これが接続されたレコードセットでどのように機能するかわかりません。切断されたレコードセットでのみ使用します。

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 に答える