Requete Access X Filtres [Résolu]

Signaler
Messages postés
13
Date d'inscription
jeudi 5 novembre 2009
Statut
Membre
Dernière intervention
11 janvier 2012
-
Messages postés
14008
Date d'inscription
samedi 29 décembre 2001
Statut
Modérateur
Dernière intervention
28 août 2015
-
Bonjour à tous,

Voilà je cherche a filtrer tout simplement le remplissage d'un listview avec une requête access 2007 qui est liée à des filtres de manière contraignante (Filtre1 et Filtre2 et ...) Dans mon cas j'en souhaiterai 5 ou plus ! Je travail avec VS2010 en VB NET.

Jusque là, j'utilisais la méthodes suivante pour filtrer :

2 filtres représente 4 cas possibles :

If Cas filtre1 "" et Cas Filtre2 ""
then slect
End if

if Cas filtre1 = "" et Cas Filtre2 <> ""
then slect
End if

if Cas filtre1 <> "" et Cas Filtre2 = ""
then slect
End if

if Cas filtre1 <> "" et Cas Filtre2 <> ""
then slect
End if

J'ai fais dans mon cas 4 filtres et cela représente beaucoup de lignes de codes (=16) avec risques d'erreurs ou d'oublis de cas envisageables.

J'avais imaginer un truc du type et une requête magique :

If Filtre1 "" then Filtre1 "*" else Variable1 = Filtre1
If Filtre2 "" then Filtre2 "*" else Variable2 = Filtre2
If Filtre3 "" then Filtre3 "*" else Variable3 = Filtre3
If Filtre4 "" then Filtre4 "*" else Variable4 = Filtre4

(Select * From TABLE WHERE Champ1 Variable1 AND Champ2 Variable2 AND Champ3 = Variable3 AND Champ4 = Variable4 Order By Champ1 ASSC", Base)

Mais bien sure la syntaxe n'est pas bonne, alors je cherche à me simplifier la tache... avant de faire au moins 25 requêtes pour 5 filtres...

Si vous avez une solution simple, je suis preneur

MERCI d'avance à tous, le problème à sans doute déjà été évoqué par le passé mais rien de trouvé pour le moment de probant... et efficace.

A BIENTOT j'espère

10 réponses

Messages postés
14008
Date d'inscription
samedi 29 décembre 2001
Statut
Modérateur
Dernière intervention
28 août 2015
70
Salut

Plusieurs problèmes :

-1- SQL et VB sont des langages distincts et là, tu mélanges les deux alégrement - pas logique.
Tu te sers de VB pour créer une requète (texte) qui sera soumise ta base.
Il faut la traiter comme une chaine de caractère.
Dans ta requète, "WHERE Champ1 = Variable1" n'a aucun sens, SQL n'ayant aucune idée de ce que représente Variable1
Ceci serait plus adapté :
"... WHERE Champ1 = " & Variable1 & " And la suite ..."

-2- Le respect du langage SQL (1ère partie)
Comme répété souvent sur ce forum, les types de champs définis dans la table :
Chaine : doivent être encadrés de '
Date : doivent être encadrés de #
Numérique : Pas d'encadrement
Ainsi, si Champ1 est de type chaine, la syntaxe devrait être :
"... WHERE Champ1 = '" & Variable1 & "' And la suite ..."

-3- Le respect du langage SQL (2ème partie)
Le symbole * n'est pas reconnu comme le "All" de VB.
Il faut utiliser %.
Le symbole _ remplaçant le symbole ? de VB
De plus, ce type de symbole ne peut pas être utilisé avec un = mais avec un Like.
Ceci serait plus adapté :
"... WHERE Champ1 Like '%' And la suite ..."

-4- Pourquoi vouloir ajouter un élément de comparaison s'il ne sert à rien ?
S'il fonctionnait, il ralentirait la requète énormément.
Puisque tu fabriques une chaine de caractère, il te suffit de ne pas écrire de condition lorsque celui-ci n'est pas utilisé.
Exemple :
Dim maRequete As String  = "Select * From TABLE WHERE "
If Filtre1 <> "" Then maRequete += "Champ1 Like '" & Filtre1 & "' And "
If Filtre2 <> "" Then maRequete += "Champ2 Like '" & Filtre2 & "' And "
(...)
' Suppression du dernier And, inutile
' (lignes extraites de l'aide de VB = facile à trouver)
If maRequete.Trim().EndsWith(" And") Then
    Dim DernierePosition As Integer = maRequete.LastIndexOf(" And")
    If DernierePosition >= 0 Then
        maRequete = maRequete.Substring(0, DernierePosition)
    End If
End If

Vala
Jack, MVP VB
NB : Je ne répondrai pas aux messages privés

Le savoir est la seule matière qui s'accroit quand on la partage (Socrate)
Messages postés
13
Date d'inscription
jeudi 5 novembre 2009
Statut
Membre
Dernière intervention
11 janvier 2012

Je corrige ma requête magique qui ne marchera toujours pas mais qui était illogique

If Filtre1 "" then Variable1 "*" else Variable1 = Filtre1
If Filtre2 "" then Variable2 "*" else Variable2 = Filtre2
If Filtre3 "" then Variable3 "*" else Variable3 = Filtre3
If Filtre4 "" then Variable4 "*" else Variable4 = Filtre4

(Select * From TABLE WHERE Champ1 Variable1 AND Champ2 Variable2 AND Champ3 = Variable3 AND Champ4 = Variable4 Order By Champ1 ASSC", Base)
Messages postés
13
Date d'inscription
jeudi 5 novembre 2009
Statut
Membre
Dernière intervention
11 janvier 2012

Salut à toi Jack et grand merci pour ta réactivité

J'étais bien entendu conscient des erreurs de syntaxe de mon exemple mais j'étais surtout à la recherche d'une autre solution que tu viens de me proposer.

Merci également pour ces rappels car je débute et j'ai tendance à confondre ou faire des erreurs de ce type pour le moment...

Je test et reviens vers toi !

ENCORE MERCI !!
Messages postés
13
Date d'inscription
jeudi 5 novembre 2009
Statut
Membre
Dernière intervention
11 janvier 2012

Voilà c'est tout bon ça marche nickel !!! C'est simple et rapide par contre j'ai corrigé semble t'il l'erreur suivante avec le 'WHERE' dans le cas où tous mes filtres sont vides ce qui donne :

Dim maRequete As String = "Select * From TABLE "
If Filtre1 <> "" Then maRequete += "WHERE Champ1 Like '" & Filtre1 & "' And "
If Filtre2 <> "" Then maRequete += "WHERE Champ2 Like '" & Filtre2 & "' And "
(...)
' Suppression du dernier And, inutile
' (lignes extraites de l'aide de VB = facile à trouver)
If maRequete.Trim().EndsWith(" And") Then
    Dim DernierePosition As Integer = maRequete.LastIndexOf(" And")
    If DernierePosition >= 0 Then
        maRequete = maRequete.Substring(0, DernierePosition)
    End If
End If
Messages postés
13
Date d'inscription
jeudi 5 novembre 2009
Statut
Membre
Dernière intervention
11 janvier 2012

J'oubliai MERCI ! et bonne continuation à toi
Messages postés
13
Date d'inscription
jeudi 5 novembre 2009
Statut
Membre
Dernière intervention
11 janvier 2012

Heu non par cohérent de répéter le WHERE à chaque AND...

Ceci à l'air de mieux fonctionner ainsi :

Dim maRequete As String
If Filtre1 "" And Filtre2 "" And Filtre3 = "" And Filtre4 = "" And Filtre5 = "" Then
                marequete = "Select * From TABLE "
            Else
                marequete = "Select * From TABLE WHERE"
                If Filtre1 <> "" Then maRequete += "WHERE Champ1 Like '" & Filtre1 & "' And "
                If Filtre2 <> "" Then maRequete += "WHERE Champ2 Like '" & Filtre2 & "' And "
            End If
' Suppression du dernier And, inutile
' (lignes extraites de l'aide de VB = facile à trouver)
If maRequete.Trim().EndsWith(" And") Then
    Dim DernierePosition As Integer = maRequete.LastIndexOf(" And")
    If DernierePosition >= 0 Then
        maRequete = maRequete.Substring(0, DernierePosition)
    End If
End If



A+
Messages postés
14008
Date d'inscription
samedi 29 décembre 2001
Statut
Modérateur
Dernière intervention
28 août 2015
70
Non, tu aurais 2 Where dans la même syntaxe, ce qui n'est pas possible.
Laisse ma proposition comme elle est et, à la fin, si tu n'as aucun filtre actif, tu ne trouveras pas de " And", alors teste aussi si tu as un "Where", auquel cas, tu le supprimes avec la même technique.
Messages postés
14008
Date d'inscription
samedi 29 décembre 2001
Statut
Modérateur
Dernière intervention
28 août 2015
70
Le Like n'est intéressant que lors de recherche utilisant des caractères génériques, comme % ou _
Si tes filtres sont des textes/chiffres 'fixes', utilise plutôt le =, la requète sera légèrement plus rapide.
Messages postés
13
Date d'inscription
jeudi 5 novembre 2009
Statut
Membre
Dernière intervention
11 janvier 2012

Bonjour Jack !

Bien que le code suivant fonctionne :

Dim maRequete As String
If Filtre1 "" And Filtre2 "" And Filtre3 = "" And Filtre4 = "" And Filtre5 = "" Then
                marequete = "Select * From TABLE "
            Else
                marequete = "Select * From TABLE WHERE"
                If Filtre1 <> "" Then maRequete += " Champ1 Like '" & Filtre1 & "' And "
                If Filtre2 <> "" Then maRequete += " Champ2 Like '" & Filtre2 & "' And "
            End If
' Suppression du dernier And, inutile
' (lignes extraites de l'aide de VB = facile à trouver)
If maRequete.Trim().EndsWith(" And") Then
    Dim DernierePosition As Integer = maRequete.LastIndexOf(" And")
    If DernierePosition >= 0 Then
        maRequete = maRequete.Substring(0, DernierePosition)
    End If
End If


J'ai corrigé selon tes conseils en :
Dim maRequete As String = "Select * From TABLE WHERE "
If Filtre1 <> "" Then maRequete += "Champ1 Like '" & Filtre1 & "' And "
If Filtre2 <> "" Then maRequete += "Champ2 Like '" & Filtre2 & "' And "
(...)
' Suppression du dernier And, inutile
' (lignes extraites de l'aide de VB = facile à trouver)
If maRequete.Trim().EndsWith(" And") Then
    Dim DernierePosition As Integer = maRequete.LastIndexOf(" And")
    If DernierePosition >= 0 Then
        maRequete = maRequete.Substring(0, DernierePosition)
    End If
End If

If maRequete.Trim().EndsWith(" Where") Then
    Dim DernierePosition As Integer = maRequete.LastIndexOf(" Where")
    If DernierePosition >= 0 Then
        maRequete = maRequete.Substring(0, DernierePosition)
    End If
End If



et c'est bien plus simple...

Encore Merci pour tout, je prends bonne note de tous tes conseils.

Bonne continuation à toi
Messages postés
14008
Date d'inscription
samedi 29 décembre 2001
Statut
Modérateur
Dernière intervention
28 août 2015
70
Le code "qui fonctionne" est correct par rapport à celui que tu proposais à 1h09, le 12 où le WHERE était répété.

Tu remarqueras que, que ce soit le "... Where " ou le "... And ", ces deux textes sont suivis d'un espace.
Dans la recherche EndsWith, heureusement qu'il y a le Trim() car la chaine que tu recherches ne comporte pas cet espace final.

Méfiance aussi : je ne sais pas comment se comporte VB lorsque tu dimensionnes deux fois de suite une même variable, DernierePosition en l'occurrence.
Dans ton cas, tu as de la chance, puisque seul un des deux If peut être vrai, mais il faut avoir l’œil à tout.
--> Un ElseIf aurait été préférable (rapidité)
--> Mon côté puritain m'aurait conduit à ressortir le Dim avant le premier If et ré-assignation de la valeur à l'intérieur de chaque If