I. Objectif

Ce très court tutoriel a pour objectif de donner une méthode de débogage lors de requêtes écrites par du code VBA.

Nous nous situons dans le cas fréquent où le développeur souhaite ouvrir un recordset / modifier une requête / modifier un Recordsource par le Code.

Le codage VBA ne permet pas de vérifier la validité d'une expression SQL qui ne sera évaluée qu'à l'exécution.

II. Constat de bogue (bug)

Nous avons une procédure de recherche multicritères (cf. mon tutoriel) qui hélas ne fonctionne pas.

Image non disponible


Et lorsque nous modifions un critère de recherche rien ne se passe, le débogage serait identique si nous avions un message d'erreur.

Image non disponible


Que faire ?

III. Utilisation du Debug.Print

Nous insérons dans le code, après la dernière mise à jour de la chaîne SQL, la ligne suivante :

 
Sélectionnez
Debug.Print SQL

Nous l'insérons à cet endroit :

Image non disponible


Ce qui signifie que nous demandons à l'objet Debug d'afficher la valeur de notre variable SQL.

Cet affichage se fera dans la fenêtre Exécution d'Access, elle-même située dans la fenêtre VBA.

Image non disponible


Pour les versions 97 et inférieures, la fenêtre débogage est une fenêtre indépendante, pour les versions 2000 et ultérieures, elle apparaît dans VBA.

Dans tous les cas : Ctrl + G permet de la mettre au premier plan.

Si vous êtes familier avec le SQL ou que l'erreur est criante, le Debug.Print peut suffire à trouver l'erreur.

Cependant dans certains cas, la lecture du SQL ne permet un débogage immédiat, nous allons donc passer par une requête.

L'utilisation de Debug.Print fait partie de l'éventail des outils de débogage, la partie suivante va tenter d'en brosser les principaux.

IV. Généralisation à l'utilisation des outils de débogage

Cette partie vise à présenter de manière synthétique l'éventail des outils d'aide au débogage.

IV-A. Définition de point d'arrêt

Les points d'arrêts sont utiles dans le cas d'une procédure au bogue muet.

C'est à dire, un traitement qui ne produit aucune erreur visible, mais qui ne donne pas le résultat escompté.

Pour insérer un point d'arrêt, vous pouvez au choix :

. cliquer dans la marge grise
. appuyer sur F9
. le faire dans le menu Débogage

Image non disponible


Visuellement, la ligne est surlignée en rouge, avec un point rouge dans la marge grise.

Cela signifie que lors de l'exécution le code va s'arrêter sur cette ligne, soit avant l'exécution de celle-ci.

La ligne va être surlignée en jaune, comme sur l'image suivante :

Image non disponible


Access vous rend la main pour effectuer votre débogage, et ce de plusieurs manières différentes.

Vous pouvez survoler avec la souris, le nom des variables, dans notre cas, la souris survole la Variable SQL.

Image non disponible


Mais vous pouvez tout aussi bien évaluer des expressions dans la fenêtre exécution : avec la fontion Print suivie du nom de la variable.

Image non disponible


Vous pouvez également corriger à chaud (pendant l'exécution) le code qui suit votre point d'arrêt.
Pour relancer le traitement après vos modifications, il vous suffit de cliquer sur le bouton "continuer" en forme de lecture, ou d'appuyer sur la touche F5 :

Image non disponible

IV-B. Le mode pas à pas

Ce mode est accessible depuis un point d'arrêt, ou un bogue rencontré sur lequel vous avez cliqué sur Débogage.

Image non disponible


Le mode est accessible par le menu ou par la touche F8.

Ce mode est utile quand vous n'avez pas identifié la ligne de code qui pose problème.
Vous allez pouvoir parcourir chaque ligne de votre code pour l'évaluer.

Dans les faits, Access va nous rendre la main sur chaque ligne en la surlignant en jaune.
Ce qui nous laisse la possiblité de modifier le code de la ligne surlignée ou le code des lignes suivantes.

Pour passer à la ligne suivante, il suffit d'appuyer sur F8.

IV-C. Les espions

Sous ce titre "aventureux" se cache une fonctionnalité de débogage qui permet d'afficher directement la valeur d'une expression.

Cet affichage a lieu dans une fenêtre dédiée (les affichages varient selon que l'application soit sous 97 ou sous 2000 et ultérieures).

Cas pratique :
. nous définissons un espion sur l'expression SQL
. nous définissons un point d'arrêt sur la première ligne de code
. nous allons faire du pas à pas pour regarder comment notre espion évolue.

Pour définir un espion :

1- nous sélectionnons une expression :
. soit un nom de variable
. soit une portion de code : égalité qui renverra un True ou False, ou une fonction

2- Clic droit : Ajouter un espion

Image non disponible


puis

Image non disponible


une ligne dans le volet "Espions" apparaît.

Image non disponible


A l'exécution, examinons les valeurs que prend notre espion durant le mode pas à pas.

sur la première ligne (notre point d'arrêt) :

Image non disponible


Puis dans le mode pas à pas :

Image non disponible


Nous pouvons ainsi suivre l'évolution en lecture directe de l'évaluation d'une expression.

NB : Les valeurs prises par les espions ne peuvent excéder 255 caractères.

V. Débogage par une requête de test

Revenons maintenant à notre cas principal, c'est à dire le débogage d'une requête écrite par le code VBA.

V-A. Par copier-coller

C'est une méthode "manuelle".

Nous allons chercher le SQL qui a été affiché dans la fenêtre Exécution, nous le copions et nous allons le coller dans une requête vierge.

Nous créons une nouvelle requête.

Image non disponible
en mode création


Pour que la requête soit vierge, nous n'ajoutons aucune table.

Image non disponible
cliquons sur Fermer pour n'ajouter aucune table


Enregistrons notre requête : qryTest

Image non disponible


Nous passons en mode SQL.

Image non disponible


Et nous n'avons plus qu'à coller le SQL.

Nous reviendrons sur l'analyse plus tard.

V-B. Par le code

Nous insérons les lignes suivantes :

Image non disponible


La première ligne permet d'attribuer dynamiquement à une requête notre chaîne SQL.

La seconde ligne ouvre en mode modification la requête de test.

Ce qui fait qu'à l'exécution de la sub, la requête de test va s'ouvrir en mode création en affichage QBE.

Image non disponible


Ce mode d'affichage est un des plus visuels, surtout lorsque nous ne sommes pas experts en SQL.

V-C. Résolution du bogue

Dans ce cas précis, nous identifions l'erreur : le critère ="*Visual*" n'est pas valide, il faut utiliser Comme (Opérateur Like en SQL).

Après correction, nous repassons en mode d'affichage SQL :

Image non disponible


Il nous suffira de nous inspirer du SQL valide pour corriger notre procédure VBA.

VI. Frequently Abominable Queries (FAQ)

VI-A. Confusion Chaine SQL et Variable

 
Sélectionnez
If Not Me.chkFamille Then
    SQL = SQL & "And Medias!Famille = 'Me.cmbRechFamille' "
End If

Le Debug.Print vous montrera que votre requête va rechercher les Familles dont la valeur est la chaîne "Me.cmbRechFamille".

Vous devez sortir Me.cmbRechFamille de la chaîne pour qu'Access évalue la valeur, et c'est cette valeur qui sera dans votre chaîne SQL.

 
Sélectionnez
If Not Me.chkFamille Then
    SQL = SQL & "And Medias!Famille = '" & Me.cmbRechFamille & "' "
End If

VI-B. Variable vide

Cette fois votre code est irréprochable, mais le Debug.Print révèle ceci :

 
Sélectionnez
.... WHERE Medias!Famille = '' ....


Votre variable est Null, les causes possibles peuvent être :

. Contrôle situé sur un formulaire non accessible / non ouvert / dont le chemin d'accès est erronné

. Erreur de libellé sur le nom

. Erreur de typage de la variable

Assurez vous que la variable prend bien une valeur, si votre application comporte la possibilité d'un Null, prévoyez le grâce à la fonction Nz().

VI-C. Type de données

Votre code semble exact, mais hélas il n'est pas approprié avec les normes de l'implémentation SQL d'Access.

Pour rappel :

 
Sélectionnez
' Gestion d'une Date : format US entre ##
WHERE [Table]![MonChampDate] = #mm/dd/yyyy#
' Gestion d'un chaîne : entre quotes ' '
WHERE [Table]![MonChampChaine] = 'Quelquechose'
' Gestion d'un numérique : ne rien mettre
WHERE [Table]![MonChampNumerique] = 2005

VI-D. Espaces manquants ou superflus

Le Debug.Print va vous permettre d'identifier à l'oeil nu ce genre d'erreur.

 
Sélectionnez

SQL = SQL & "WHERE [MaTable]![MonChamp] = '" & maVariable & "'"
SQL = SQL & "AND [MaTable]![MonChamp] = '" & maVariable & "'"

ce code d'apparence correcte va donner un SQL de ce type

 
Sélectionnez
WHERE [MaTable]![Monchamp] = 'Toto'AND ...

Le remède :

 
Sélectionnez

SQL = SQL & "WHERE [MaTable]![MonChamp] = '" & maVariable & "' "
SQL = SQL & "AND [MaTable]![MonChamp] = '" & maVariable & "' "



Ensuite le cas d'un espace superflu à l'intérieur d'un critère, suite à une faute d'inattention :

 
Sélectionnez

SQL = SQL & "WHERE [MaTable]![MonChamp] = ' " & maVariable & " ' "
SQL = SQL & "AND [MaTable]![MonChamp] = '" & maVariable & "' "

va donner :

 
Sélectionnez
WHERE [MaTable]![Monchamp] = ' Toto ' AND ...

VI-E. Présence de Simple Quote (') ou Double Quote (") dans la variable

Nous avons vu que l'implémentation SQL d'Access requiert la mise entre quotes ' ' d'une chaîne en critère.

Ce codage est cependant mis en échec quand la valeur de la variable contient un quote.

Exemple :

 
Sélectionnez

SQL = SQL & "WHERE [MaTable]![MonChamp] = '" & maVariable & "' "

Si maVariable vaut : "l'écureuil"

 
Sélectionnez
WHERE [MaTable]![Monchamp] = 'L'écureuil' AND ...

Ce qui vous vaut une belle erreur.

Le remède est de doubler ce Quote.

Pour les versions 2000 et ultérieures, il suffit d'utiliser la fonction Replace().

 
Sélectionnez

SQL = SQL & "WHERE [MaTable]![MonChamp] = '" & Replace(maVariable, "'", "''") & "' "

Pour les versions 97 et antérieures, il faut faire de même en utilisant une fonction Replace() de substitution (disponible dans la FAQ)

Vous rencontrerez le même type de problème si vous délimitez vos chaînes par des double quotes (") et si la variable contient un double quote.

La solution est là aussi de doubler ce caractère, toujours avec la fonction Replace()

VI-F. Autres

Cette liste des FAQ n'est pas exhaustive, n'hésitez pas à me contacter pour que j'ajoute d'autres types d'erreurs fréquentes.

VII. Conclusion

Cet article vous a, je l'espère, donné quelques pistes pour mieux écrire vos requêtes via VBA et dans le cas où les problèmes subsistent les déboguer.

J'adresse un grand merci à toute l'équipe de rédaction d'Access pour leurs relectures et leurs pertinentes suggestions d'améliorations.

Un remerciement tout particulier pour Argyronet qui a superbement magnifié les copies d'écran.