Formulaire de recherche prêt à l'emploi 2ème partie.
Date de publication : 4/11/2005 , Date de mise à jour : 13/07/2006
Par
Fabrice CONSTANS (autres articles)
Cet article est le deuxième de la série consacrée à la recherche dans Microsoft
ACCESS. Au terme du
précédent article
nous avions créé un formulaire de recherche générique. Dans
celui-ci nous allons agrémenter notre formulaire de plusieurs fonctions importantes.
I. Avertissement
II. Conseils importants sur la programmation
III. Présentation des nouvelles fonctionnalités
IV. Comment éviter les sorties intempestives en mode run-time
V. Visualisation/exécution du code SQL généré
IV.A. Visualiser le code SQL
IV-C. Tester un code modifié
VI. Gestion des chaînes SQL
V-A. Table et contrôles
V-B. Les codes VBA
V-B-1. Alimentation de la liste des requête
V-B-2. Sauvegarde de la chaîne SQL
V-B-3. Chargement SQL
V-B-4. Suppression de requête
VI. Traitement d'autres opérateurs logiques
VIII. Traitement des NULL
VII-A. L'affichage des boutons d'options.
VII-B. Le traitement
VII-B-1. Les booléens (oui/non)
VII-B-2. Les numériques et dates
VII-B-3. Les textes
VII-C. Mode d'emploi pour le Null
IX. Formulaire d'édition
IX-B. Le code VBA
X. Le compteur
X-A. Le code VBA
XI. Sélection de champs
XI-A. Contrôle liste
XI-B. Le Code VBA
XI-B-1. Remplir la liste
XI-B-2. Récupérer la sélection
XI-B-3. Exploiter la sélection
XI-C. Comment utiliser la sélection multiple ?
XII. Conclusion
XIV. Remerciements
I. Avertissement
 |
L'utilisation de la touche F1
est vivement conseillée à tous les stades de
l'utilisation d'ACCESS. L'amélioration constante
de l'aide en fait un partenaire de choix dans
l'apprentissage permanent d'ACCESS.
Personnellement, je ne peux m'en passer, ne
serait-ce que pour mémoire.
|
II. Conseils importants sur la programmation
Suite à des remarques sur le tutoriel précédent, je tiens
à donner quelques conseils sur la manière de nommer certains
objets dans Microsoft ACCESS comme les formulaires, états, tables
et champs.
Même si l'utilisation d'espaces dans les noms de tables et de champs
est autorisée dans Microsoft ACCESS, il est fortement déconseillé de le faire.
En effet chaque fois qu'un nom comporte au moins un espace il faut l'entourer
de crochets []. Dans le QBE (générateur de requête) ces crochets peuvent
être insérés automatiquement. Mais le QBE peut interpréter également le nom comme
une chaîne de caractères ou au pire provoquer une erreur.
Dans le code VBA il faut toujours le faire manuellement ce qui ralenti l'écriture
du code et peut causer des erreurs.
 |
Remplacez l'espace par l'underscore _.
Lisez l'excellent tutoriel
d' Argyronet
sur les conventions d'écriture dans VBA.
|
Pour éviter des problèmes avec les espaces et autres caractères veuillez
appliquer cette modification dans Cmd_recherche_click()
| Code à modifier |
strTable = Me.cbo_Table
strField = Me.cbo_Champ
|
| Code modifié |
strTable = "[" & Me.cbo_Table & "]"
strField = "[" & Me.cbo_Champ & "]"
|
III. Présentation des nouvelles fonctionnalités
Les fonctionnalités ajoutées sont les suivantes :
- Visualisation du code SQL généré
- Gestion du code SQL
- Traitement des opérateurs logiques principaux (AND, OR)
- Traitement de la valeur Null
- Ouverture d'un formulaire de visualisation
- Choix des champs à visualiser dans la liste de résultat

L'état précédent du formulaire.
IV. Comment éviter les sorties intempestives en mode run-time
En environnement Run-time la moindre erreur non traitée se solde par
une sortie sauvage. Dans l'état actuel de notre formulaire si un utilisateur
clique sur le bouton Rechercher sans avoir défini la table ou le champ, la sortie
est inévitable.
Pour l'éviter il vaut mieux faire quelques tests.
Ouvrez le code sur bouton Rechercher.
Recherchez le code suivant qui est en début de procédure.
A la suite insérez le code de contrôle suivant.
| Code à insérer |
If IsNull(Me.cbo_table) Or IsNull(Me.cbo_champ) Then
MsgBox "Vous devez renseigner la table et le champ pour effectuer une recherche !", vbExclamation + vbOKOnly, "Recherche"
Exit Sub
End If
|
Ici nous contrôlons que les 2 listes de choix (table et champ) contiennent
bien une sélection. Sinon nous adressons un petit message à l'utilisateur
et sortons de la procédure.
V. Visualisation/exécution du code SQL généré
Notre moteur de recherche étant opérationnel nous pouvons regarder
et pourquoi pas manipuler la chaîne SQL générée. Avec un contrôle
texte pour visualiser et modifier la chaîne SQL et un bouton pour
l'exécuter nous pourrons facilement mettre en oeuvre cette fonctionnalité.
IV.A. Visualiser le code SQL
Rajoutez le contrôle suivant :
| Zone texte / Affichage de la syntaxe SQL |
| Propriété |
Valeur |
| Nom |
txt_ChaineSQL |
| Barre défilement |
Verticale |
| Légende de l'étiquette |
Chaîne SQL |
Prévoyez un contrôle de la largeur de la liste de résultat lst_resultat
et de 3 à 4 lignes pour avoir un bon confort de lecture.
 |
La propriété Rowsource d'un contrôle est limitée à 1024 caractères.
Un objet requête peut contenir une chaîne SQL d'environ 64 000 caractères.
Un contrôle texte peut contenir 65 535 caractères au maximum.
Nous ne pouvons donc pas générer des chaînes SQL de plus 1024 caractères.
|
Sélectionnez le bouton Rechercher
Editez l'évènement Sur clic
Placez-vous à la fin du code juste avant le End Sub.
Insérez le code suivant :
| Code à insérer |
Me.txt_chaineSQL.Value = strSql
|
Faites un petit test... Toujours pas de vaudou ni de magie.
Nous affectons simplement la chaîne SQL contenu dans strSQL dans
notre contrôle texte.
IV-C. Tester un code modifié
Toujours à l'aide de quelques instructions nous allons démontrer
que nous pouvons visualiser le résultat d'une chaîne SQL modifiée.
Rajoutez le contrôle suivant :
| Bouton de commande / Teste la syntaxe SQL |
| Propriété |
Valeur |
| Nom |
cmd_testSQL |
| (Evènement) Sur clic |
[Procédure Evènementielle] |
| Légende de l'étiquette |
> |
Dans la procédure événementielle Sur Clic, insérez le code suivant :
| Code à insérer |
If IsNull(Me.txt_chaineSQL) Then Exit Sub
Me.lst_resultat.RowSource = Me.txt_chaineSQL
Me.lst_resultat.Requery
|
Sauvegardez et passez en mode Formulaire pour faire un test.
Faites une recherche simple, sur un champ texte en utilisant l'option
Contenir la valeur
VI. Gestion des chaînes SQL
Nous sommes souvent ammenés à faire les mêmes recherches et il peut être
très pratique de pouvoir rappeler des chaînes SQL précédemment créées, surtout
si celles-ci comportent plusieurs conditions.
Au stade actuel nous pouvons facilement concevoir un système de gestion
des chaînes SQL.
Nous allons utiliser l'objet Requête pour stocker nos chaînes, cela nous
permettra de pouvoir générer directement des requêtes.
Pour une gestion simple nous aurons besoin d'une zone de liste déroulante
(combo) pour afficher la liste des requêtes, d'un bouton de sauvegarde et
un de suppression.
 |
Notez que nous pourrions également utiliser le stockage dans un champ
Mémo d'une table.
|
V-A. Table et contrôles
Nous allons utiliser le même système qui nous a servi à faire l'inventaire
des tables pour réaliser celui des requêtes. Pour cela nous avons
besoin de créer une table, par chance la structure de celle-ci est
identique à tbl_TempLstTbl. Nous allons en faire une copie.
Dans la liste des tables, sélectionnez la table tbl_TempLstTbl
faites un Ctrl+C ou clic-droit/copier pour faire
la copie de l'objet puis un Ctrl+V ou clic-droit/coller pour faire
apparaitre le panneau suivant.

Le panneau
Entrez le nom suivant tbl_TempLstQry et choisissez le
bouton d'option Structure seulement.
Validez à l'aide du bouton Ok ou appuyer sur la touche
Entrée.
La table est créée. Nous pouvons passer aux contrôles.
Commencez par une zone de liste déroulante. Créez-la
suivant les propriétés suivantes :
| Zone liste modifiable / liste des requêtes |
| Propriété |
Valeur |
| Nom |
cbo_Query |
| Origine source |
Table/Requête |
| Contenu |
tbl_TempLstQry |
| Légende de l'étiquette |
Requêtes |
Créez ensuite les 3 boutons de commande nécessaires,
Sauver SQL, Supprimer SQL et Charger SQL.
| Bouton de commande / Sauver SQL |
| Propriété |
Valeur |
| Nom |
cmd_saveSQL |
| Légende |
Sauver SQL |
| (Evènement) Sur clic |
[Procédure Evènementielle] |
| Bouton de commande / Supprimer SQL |
| Propriété |
Valeur |
| Nom |
cmd_suppSQL |
| Légende |
Supprimer SQL |
| (Evènement) Sur clic |
[Procédure Evènementielle] |
| Bouton de commande / Charger SQL |
| Propriété |
Valeur |
| Nom |
cmd_LoadSQL |
| Légende |
Charger SQL |
| (Evènement) Sur clic |
[Procédure Evènementielle] |
Voici notre formulaire avec les nouveaux contrôles.

Avec les nouveaux contrôles...
V-B. Les codes VBA
V-B-1. Alimentation de la liste des requête
La zone de liste modifiable cbo_Query est alimentée de la même
manière que pour la zone liste cbo_Table qui contient les noms de tables .
Nous modifions la fonction lf_GetTableList() pour faire l'inventaire des
requêtes.
Insérez le code suivant :
| Code à insérer |
Function lf_GetQueryList()
Dim qrs As QueryDefs
Dim rst As Recordset
Dim strSql As String
Dim i As Integer
DoCmd.SetWarnings False
strSql = "Delete tbl_TempLstQry.*"
strSql = strSql + " FROM tbl_TempLstQry;"
DoCmd.RunSQL strSql
Set qrs = CurrentDb.QueryDefs
Set rst = CurrentDb.OpenRecordset("tbl_TempLstQry")
For i = 0 To qrs.Count - 1
If qrs(i).Name Like "USER_*" Then
rst.AddNew
rst.Fields(0) = qrs(i).Name
rst.Update
End If
Next
lf_GetQueryList = rst.RecordCount
rst.Close
Set rst = Nothing
Set qrs = Nothing
DoCmd.SetWarnings True
End Function
|
Dans ce code nous pouvons constater que :
Nous remplaçons l'objet Tabledefs par Querydefs.
Nous remplaçons la table tbl_TempLstTbl par tbl_TempLstQry.
Nous ne recensons que les requêtes commençant par "USER_". Ceci permet de faire
la différence entre les requêtes utilisateurs et celles qui pourraient
être présente dans l'application.
Cette liste doit être toujours à jour, nous devons donc l'alimenter
à l'ouverture du formulaire puis après chaque action d'ajout
et de suppression de requête "USER_".
Ouvrez le code du formulaire et dans la procédure Form_Open
(propriété Sur Ouverture) insérez avant le End Sub le code suivant :
| Code à insérer |
lf_GetQueryList
me.cbo_query.Requery
|
V-B-2. Sauvegarde de la chaîne SQL
La sauvegarde ne représente pas une grosse difficulté technique
puisqu'il existe une méthode, cependant la procédure
n'est pas constituée que de la sauvegarde.
Elle doit :
- demander le nom de la nouvelle requête à l'utilisateur
- vérifier que ce nom ne soit pas déjà attribué
- sauvegarder la chaîne sous la forme d'une requête.
Créer le code évenementiel Sur clic pour le bouton cmd_saveSQL
insérez le code suivant.
| Code à insérer |
If IsNull(Me.txt_chaineSQL) Then
MsgBox "La chaine SQL est vide. Sauvegarde inutile.", vbExclamation + vbOKOnly, "erreur"
Exit Sub
End If
Dim strQuery As String
strQuery = "USER_" & InputBox("Insérez le nom de la requête à créer (245 caractères max.):" _
& vbCrLf & "Ce nom sera précédé de USER_ .", "Nom de requête")
If IsNull(DLookup("Nom", "tbl_TempLstQry", "Nom=""" & strQuery & """")) Then
CurrentDb.CreateQueryDef strQuery, Me.txt_chaineSQL
lf_GetQueryList
Me.cbo_Query.Requery
MsgBox "Sauvegarde de " & strQuery & " effectuée.", vbInformation + vbOKOnly, "information"
Else
MsgBox "Ce nom de requête existe déjà.", vbExclamation + vbOKOnly, "Erreur"
End If
|
Dans ce code 4 parties particulières sont à commenter :
Inputbox() : Cette fonction affiche une fenêtre comprenant un
bouton OK, un bouton Annuler, une zone de saisie et une zone de texte.
Elle invite l'utilisateur à saisir une valeur. Celle-ci est renvoyée
lors de l'appui sur le bouton OK.
vbcrlf: Cette constante contient le code retour chariot (cr ou carriage return)
et le saut de ligne (lf ou line feed), elle permet dans un texte de passer
à la ligne.
Dlookup("champ","table","condition") : Cette fonction VBA existe également sous le
nom de Rechdom("champ";"table";"condition") pour l'interface ACCESS.
Elle renvoie une valeur unique recherchée dans une
table ou une requête.
- champ est le champ contenant la valeur à renvoyer.
- table est la table ou la requête de sélection dans laquelle la recherche est effectuée.
- condition est une condition Where sans le mot clef WHERE.
CurrentDb.CreateQueryDef : Cette méthode permet de créer
une requête à partir d'une chaîne de caractère SQL valide.
CurrentDB est l'objet database courant.
Pour plus d'information veuillez consulter l'aide ACCESS.
V-B-3. Chargement SQL
Si le chargement d'une syntaxe SQL contenu dans une requête ne comporte
pas de problème majeur, la chaîne SQL est cependant composée de caractères parasites.
En effet la syntaxe est "polluée" par un saut de ligne constitué des codes
Carriage Return (13) et Line Feed (10).
Ouvrez les propriétés du bouton Charger SQL.
Créez un évènement sur la propriété Sur clic.
Insérez le code suivant :
| Code à insérer |
Dim strQuery As String
strQuery = Replace(CurrentDb.QueryDefs(Me.cbo_Query).Sql, Chr(13) & Chr(10), " ")
Me.txt_chaineSQL = strQuery
Me.lst_resultat.RowSource = strQuery
|
Nous remplaçons le CR et LF par un espace grâce à la fonction Replace. (disponible
à partir de la version 2000 uniquement).
V-B-4. Suppression de requête
La suppression ne pose aucun problème particulier, il faut
simplement veiller à demander une confirmation à l'utilisateur et
à rafraîchir la liste de requête.
Insérez simplement le code suivant dans la procédure événementielle
du bouton Supprimer SQL.
| Code à insérer |
If MsgBox("Voulez-vous vraiment supprimer la requête " & Me.cbo_Query & " ?", _
vbExclamation + vbOKCancel, "Avertissement") = vbOK Then
DoCmd.DeleteObject acQuery, Me.cbo_Query
lf_GetQueryList
Me.cbo_Query.requery
End If
|
VI. Traitement d'autres opérateurs logiques
Après l'ajout de ces nouvelles fonctionnalités nous allons étoffer
les possibilités de la recherche imbriquée en ajoutant la gestion
d'un autre opérateur logique.
Commencez par créer un contrôle zone liste déroulante avec les propriétés
suivantes :
| Zone liste modifiable / liste des opérateurs logiques |
| Propriété |
Valeur |
| Nom |
cbo_operateur |
| Origine source |
liste valeurs |
| Contenu |
"AND";"OR" |
| Valeur par défaut |
"AND" |
| Légende de l'étiquette |
Opérateur logique |
 |
Très important : Renommez l'étiquette en lbl_operateur car nous aurons
besoin de nous y référer ultérieurement.
|
Le code est très simple à modifier puisqu'il suffit de remplacer
le AND existant par la référence de la zone de liste.
Repérez la ligne suivante vers la fin de la procédure du bouton Rechercher.
| Code à remplacer |
strSql = strSql & " AND " & strCriteria & "));"
|
Remplacez-le par celui-ci.
| Nouveau code |
strSql = strSql & " " & Me.cbo_operateur & " " & strCriteria & "));"
|
Voilà c'est tout pour le traitement des opérateurs. Remarquez que
nous n'utilisons que les opérateurs les plus courant.
Il y a cependant une petite chose à rajouter pour que notre fonctionnalité
soit totalement fini. Il s'agit d'afficher ou de cacher la liste cbo_operateur
suivant l'état du bouton d'option opt_rechcourante.
| Opt_Rechcourante / liste des opérateurs |
| Propriété |
Valeur |
| Valeur par défaut |
Non |
| Sur clic |
[Procédure Evènementielle] |
Insérez le code suivant dans la procédure de l'évènement Sur Clic:
| Code à insérer |
If Me.Opt_rechcourante = True Then
Me.cbo_operateur.Visible = True
Me.lbl_operateur.Visible = True
Else
Me.cbo_operateur.Visible = False
Me.lbl_operateur.Visible = False
End If
|
Positionnez-vous sur la procédure Form_open.
Il y a un moyen très rapide pour se déplacer d'une procédure à l'autre
sans passer par la fenêtre des propriétés.
Dans la barre de menu située au dessus de la zone contenant le code VBA
il y a 2 zones liste déroulante.
Celle de gauche indique l'ensemble des objets gérés par le module, dans notre cas
il s'agit du formulaire de recherche.

Notez que tous les items sont en gras.
Cliquez sur Form
Celle de droite contient l'ensemble des évènements de l'objet sélectionné dans la liste
de gauche.

Ceux en gras existe dans le code.
Cliquez sur Open.
Le curseur se positionne sur la procédure Form_Open qui
correspond à la propriété événementielle Sur ouverture du formulaire.
Insérez le code suivant :
Ici nous faisons appel à la procédure précédemment créée qui cache où fait
apparaître la zone liste et son étiquette.
Faites un test, sauvez le formulaire, fermez-le puis réouvrez-le.
Cliquez ensuite sur le bouton d'option de la recherche courante à
plusieurs reprises...

Nuit...

Jour...
VIII. Traitement des NULL
Tant attendue, cette fonctionnalité nécessite des modifications dans
les boutons d'options de recherche et dans le traitement des types
de champs du bouton de recherche.
Un test sur la zone texte txt_critere
nous permettra de déterminer si l'utilisateur recherche les Null.
VII-A. L'affichage des boutons d'options.
Seules les options de recherche des valeurs booléennes (Oui/non)
doivent être modifiées. Nous découvrirons pourquoi dans le traitement
de la construction de la chaîne SQL.
Ouvrez le code VBA cbo_champ AfterUpdate comme nous l'avons
appris dans le chapitre précédent.
| Le code d'origine |
Case Is = dbBoolean
Me.lbl_TypeChamp.Caption = "Oui/Non"
Me.lbl_Etiq1.Caption = "Oui"
Me.lbl_Etiq2.Caption = "Non"
Me.lbl_Etiq3.Visible = False
Me.lbl_Etiq4.Visible = False
Me.lbl_Etiq5.Visible = False
Me.opt_Ope3.Visible = False
Me.opt_Ope4.Visible = False
Me.opt_Ope5.Visible = False
Me.txt_Critere.Visible = False
|
Vous remarquez que les options 3 et 4 sont inutilisées. Nous allons
nous en servir pour traiter la valeur Null et Non Null.
Faites les modifications suivantes.
| Le code une fois modifié |
Case Is = dbBoolean
Me.lbl_typeChamp.Caption = "Oui/Non"
Me.lbl_etiq1.Caption = "Oui"
Me.lbl_etiq2.Caption = "Non"
Me.lbl_etiq3.Caption = "Est Null"
Me.lbl_etiq4.Caption = "N'est pas Null"
Me.lbl_etiq5.Visible = False
Me.opt_Ope5.Visible = False
Me.txt_critere.Visible = False
|
Nous affichons dans les étiquettes 3 et 4 leur texte respectif.
Passons au traitement.
VII-B. Le traitement
Nous devons modifier directement la procédure cmd_recherche_Click.
Affichez-la en sélectionnant cmd_recherche dans la liste de gauche.
Comme il n'y a qu'une procédure pour ce contrôle, nous y accédons
directement, pas besoin de faire un choix dans la liste de droite.
VII-B-1. Les booléens (oui/non)
Recherchez le code suivant.
| Le code d'origine |
Case dbBoolean
If intOpeChamp = 1 Then
strCriteria = strTable & "." & strField & "=-1"
ElseIf intOpeChamp = 2 Then
strCriteria = strTable & "." & strField & "=0"
Else
strCriteria = strTable & "." & strField & "=Null"
End If
|
Voici la modification à faire. Nous avons remplacé les tests conditionnels
(if, elseif, else et endif) par une structure Select Case.
| Le code une fois modifié |
Case dbBoolean
Select Case intOpeChamp
Case 1
strCriteria = strTable & "." & strField & "=-1"
Case 2
strCriteria = strTable & "." & strField & "=0"
Case 3
strCriteria = "ISNULL(" & strTable & "." & strField & ")"
Case 4
strCriteria = "NOT ISNULL(" & strTable & "." & strField & ")"
End Select
|
VII-B-2. Les numériques et dates
La modification est plus importante pour le numérique.
Repérez le code suivant, il se trouve immédiatement après le
traitement booléen.
| Le code d'origine |
Case dbByte To dbBinary, dbLongBinary, dbBigInt To dbVarBinary, dbNumeric To dbTimeStamp
strCriteria = Me.txt_Critere
If InStr(1, Me.txt_Critere, ",") > 0 Then strCriteria = Replace(Me.txt_Critere, ",", ".", 1)
If intTypChamp = dbDate And IsDate(Me.txt_Critere) Then strCriteria = "#" & Me.txt_Critere & "#"
If Not IsNull(Me.txt_Critere) Then
Select Case intOpeChamp
Case 1
strCriteria = strTable & "." & strField & "=" & strCriteria
Case 2
strCriteria = strTable & "." & strField & ">=" & strCriteria
Case 3
strCriteria = strTable & "." & strField & "<=" & strCriteria
Case 4
strCriteria = strTable & "." & strField & "<>" & strCriteria
End Select
End If
|
Faites les modifications suivantes.
| Le code une fois modifié |
Case dbByte To dbBinary, dbLongBinary, dbBigInt To dbVarBinary, dbNumeric To dbTimeStamp
If Not IsNull(Me.txt_critere) Then
strCriteria = Me.txt_critere
If InStr(1, Me.txt_critere, ",") > 0 Then strCriteria = Replace(Me.txt_critere, ",", ".", 1)
If intTypChamp = dbDate And IsDate(Me.txt_critere) Then strCriteria = "#" & Me.txt_critere & "#"
End If
Select Case intOpeChamp
Case 1
If IsNull(Me.txt_critere) Then
strCriteria = "ISNULL(" & strTable & "." & strField & ")"
Else
strCriteria = strTable & "." & strField & "=" & strCriteria
End If
Case 2
strCriteria = strTable & "." & strField & ">=" & strCriteria
Case 3
strCriteria = strTable & "." & strField & "<=" & strCriteria
Case 4
If IsNull(Me.txt_critere) Then
strCriteria = "NOT ISNULL(" & strTable & "." & strField & ")"
Else
strCriteria = strTable & "." & strField & "<>" & strCriteria
End If
End Select
|
Dans le début du code, nous pouvons remarquer que les modifications
à apporter au critère - le remplacement de la virgule par le point et
l'ajout des dièses - ne sont à faire que pour des valeurs autres que Null.
Sans ce test préalable des erreurs se produiront.
Dans la seconde partie du code nous traitons les Null dans les
options 1 (=) et 4 (<>) toujours en testant le contenu de la zone
texte txt_critere.
VII-B-3. Les textes
Le traitement texte est similaire à celui du numérique.
Recherchez le code suivant, il vient immédiatement après le traitement
précédent.
| Code d'origine |
Case dbText, dbMemo, dbChar
Select Case intOpeChamp
Case 1
strCriteria = strTable & "." & strField & " Like """ & Me.txt_critere & """"
Case 2
strCriteria = strTable & "." & strField & " Like """ & Me.txt_critere & "*"""
Case 3
strCriteria = strTable & "." & strField & " Like ""*" & Me.txt_critere & "*"""
Case 4
strCriteria = strTable & "." & strField & " Like ""*" & Me.txt_critere & """"
Case 5
strCriteria = "NOT " & strTable & "." & strField & "
|