Recherche de mot entier

Comment trouver un mot entier dans une requête Access ? Par exemple, dans une phrase comme « Bonjour, aujourd'hui, c'est le jour de Noël !« , je souhaite vérifier si la phrase contient le mot « jour« .

Un critère comme [Le champ] LIKE '*jour*' semble une bonne idée, mais le critère m’extrait les mots Bonjour, Aujourd'hui et Jour. Alors que je ne souhaite extraire que le mot Jour. Une phrase comme « Bonjour, c'est Noël » serait considérée comme valide, et je n’en veux pas. Comment faire ?

Le problème des délimiteurs

Avec un peu d’astuce, on peut imaginer des critères du style :
[Le champ] LIKE '* jour *'

avec des espaces autour du mot jour. Dans ce cas, Bonjour et Aujourd'hui sont effectivement éliminés.

Mais comment faire s’il y a un point, une virgule ou un tiret avant/après le mot « jour » ? Du genre : « Ce jour-là...« . Le nombre de variantes devient lourd à gérer, et on sent que ça va donner un critère SQL long comme un jour sans ordinateur. 🙂

Les expressions régulières à la rescousse

C’est ici qu’il faut se rabattre sur les expressions régulières, dont il a été question dans d’autres articles du blog. Consultez notamment l’article Valider la saisie d’une adresse e-mail pour voir comment inscrire la bibliothèque VBScript Regular Expressions dans votre projet VBA.

La fonction VBA

Une fois la bibliothèque activée, recopiez cette fonction dans un module standard de votre base de données :

Quelques explications :

  • Si votre mot est jour, on va effectuer une recherche par l’expression régulière bjourb.
  • Le b détecte les limites (boundaries en anglais) d’un mot. Une limite pouvant être un espace, une tabulation, un tiret, un début de chaîne, une fin de chaîne.
  • En résumé, on cherche le mot jour compris entre des limites quelconques, mais pas collé à une autre portion de texte !

Tester la fonction

Pour tester la fonction rapidement :

  1. Faites apparaître la fenêtre Exécution (CTRL + G).
  2. Tapez-y des choses comme ça, en validant chaque ligne par [Entrée] :

La fonction renvoie Vrai quand la phrase inspectée contient le mot entier, et Faux sinon.
Vous remarquerez que les majuscules/minuscules ne sont pas importantes dans la recherche. Si vous souhaitez faire la distinction, remplacez re.IgnoreCase = True par re.IgnoreCase = False dans le listing plus haut.

Mettre la fonction en application

Tout ça devient plus intéressant dans une requête : je reprends ma base de films, et je voudrais trouver tous les films dont le résumé contient le mot « Elu« . Première approche :

On obtient :

Le problème des 2 premiers films est que leur résumé contient le mot « celui« , qui répond au critère. Aménageons la requête en ajoutant un champ calculé qui fait appel à la fonction VBA du dessus :

Cette fois, ça marche : seul Matrix sort dans les résultats. On a trouvé l’Elu !

Vous aimerez aussi...

9 réponses

  1. Hervé Inisan dit :

    Cinesra > Est-ce que tu peux poster ici un exemple de chaque requête (pour voir s’il y a quelque chose de particulier) ?

    Les 2 mots sont-ils placés de la même manière dans le champ ?

  2. Cinesra dit :

    Bonjour Hervé,

    J’ai réussi à régler tous mes problèmes mis à part un tout petit détail:

    Sais-tu pourquoi quand je recherche le mot « impureté » par exemple, la recherche fonctionne mais quand je recherche « émeraude », la recherche ne trouve rien (alors que l’enregistrement contenant le mot « émeraude » existe bel-et-bien?

    Merci beaucoup d’avance

  3. Cinesra dit :

    Bonjour Hervé,

    J’ai trouvé la solution d’une de mes 2 questions (la seconde, celle d’hier) il suffit d’écrire:

    Me.RecordSource = « SELECT * FROM MaTable WHERE (RechercheMot(Nz([MonChamp], »), ‘MotAChercher’) = True); »

    • gki dit :

      Bonjour Cinesra, tout cela est excellent. Toutefois après essai avec Access 2010 la formulation : Me.RecordSource = “SELECT * FROM MaTable WHERE (RechercheMot(Nz([MonChamp],”), ‘MotAChercher’) = True);” entraine une erreur de syntaxe ; je ne suis pas encore assez expert en guillemets et virgules alors la « bonne » syntaxe serait bienvenue ! Si je n’en demande pas trop.
      Avec mes remerciements anticipés.
      gki

    • gki dit :

      Bonjour, J’ai trouvé une syntaxe correcte avec une variable de travail :
      Dim copiecritère As String
      copiecritère = Forms![recherche sur descriptif seul].Critère
      Me.RecordSource = « SELECT * FROM [inventaire1] WHERE (RechercheMot(Descriptif, ‘ » & copiecritère & « ‘) = True); »
      Merci d’annuler ma demande précédente et merci pour toutes ces suggestions.
      Salutations
      gki

  4. Cinesra dit :

    Rebonjour Hervé,

    Encore une petite question concernant ton code (j’attends cependant toujours ta réponse pour pouvoir rechercher dans tous les champs d’une table à la fois).

    Je viens de remarquer un détail plutôt gênant concernant ta fonction RechercheMot: lorsque qu’on recherche un mot dans le champ d’une table et que ce champ est vide pour certain enregistrements, la fonction RechercheMot retourne une erreur!! Évidemment une solution serait de mettre une valeur par défaut dans les champs à rechercher mais je trouve que ça fait un peu « mauvaise programmation », que c’est un peu lourd (d’autant que mettre des valeurs par défaut à la place d’un vide risque de faire gonfler le poids de ma base de données, non?).

    Merci beaucoup d’avance pour une solution!!

  5. Hervé Inisan dit :

    Cinesra > On doit pouvoir faire de plusieurs manières. Par exemple, juxtaposer les RechercheMot() avec les mots-clefs Et / Ou :

    Sinon, on peut aussi retoucher le code même de la fonction pour qu’elle change l’expression régulière. En construisant une chaîne du style bElub|bchevalb le résultat vaudra True si on trouve Elu ou cheval.

  6. Cinesra dit :

    Bonjour Hervé,

    Comment modifier ton code pour permettre de chercher plusieurs mots à la fois, avec soit un « ET » entre chaque mot, soit un « OU »???

    Merci d’avance

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *