ACCESS : Erreur 3061, Trop peu de paramètres 1 requis

Ce message est assez commun lorsque vous manipulez des requêtes dans VBA. Nous allons voir pourquoi cela s’affiche et quels sont les solutions à y apporter. Dans l’exemple suivant tout est correct , aucune erreur n’est déclenchée.

Sub getName() 
Dim db As dao.Database 
Dim rst As dao.Recordset 

Set db = CurrentDb 

Set rst = db.OpenRecordset("SELECT [Nom] FROM " & _ "tCONTACT WHERE Nom='Martin';", dbOpenSnapshot) 
MsgBox "Il s’appelle " & rst.Fields("Nom").Value 

rst.Close
db.close
Set rst = Nothing 
Set db = Nothing 
End Sub

Lorsqu’on utilise cette requête avec un paramètre issue d’un formulaire comme ci-dessous :

Sub getName()

 ... 

Set rst = db.OpenRecordset("SELECT [Nom] FROM " & _ "tCONTACT WHERE Nom=forms.fChercher.txt_nom;", dbOpenSnapshot) 
MsgBox "Il s’appelle " & rst.Fields("Nom").Value 

... 
End Sub

Voici le message Erreur 3061 Trop peu de paramètres… qui apparaît :

La seule solution a ce problème est que les paramètres de l’interface soit interprétés non plus par le moteur de base de données comme avec ce code mais directement par VBA.

1ère Solution :

La partie IHM est directement interprété par VBA qui n’envoie que la valeur au moteur de base de données.

Set rst = db.OpenRecordset("SELECT [Nom] FROM tCONTACT " & _ 
       "WHERE Nom=""" & Forms.fChercher.txt_nom & """;", dbOpenSnapshot)

C’est ceci qui est envoyé au moteur de base de données :

SELECT [Nom] FROM tCONTACT WHERE Nom="Martin";

2ème Solution :

Set rst = db.OpenRecordset("SELECT [Nom] FROM tCONTACT " & _ 
          "WHERE Nom=Eval('Forms.fChercher.txt_nom');", dbOpenSnapshot)

Ici c’est un peu différent, c’est la fonction VBA Eval() qui fait la liaison entre le moteur de base de données et l’interface (formulaire). Eval() résout l’expression Forms. et renvoi sa valeur.

3ème Solution :

Celle-ci est un peu plus complexe car elle nécessite l’écriture d’une fonction utilisateur.

Set rst = db.OpenRecordset("SELECT [Nom] FROM tCONTACT " & _ 
         "WHERE Nom=fDonneNom();", dbOpenSnapshot)

Dans un module standard écrivez cette fonction :

Public Function fDonneNom() As Variant
    fDonneNom = Forms.fChercher.txt_nom 
End Function

Ce cas est plutôt à envisager lorsque la valeur renvoyée est le résultat d’une opération complexe comme un calcul, une concaténation…

Public Function fDonneNom() As String 
    fDonneNom = Forms.fChercher.txt_nom 
End Function

4ème Solution

Cette solution est à envisager surtout si vous avez de nombreux paramètres à passer issue de l’IHM ou qu’ils sont hétérogènes ; issue de plusieurs sources (VBA, résultat de requête, IHM…).

Commencer par modifier la requête en utilisant la clause PARAMETERS. Vous pouvez utiliser le QBE (Query By Exemple), autrement dit, l’éditeur de requêtes de Microsoft Access, en Mode Création pour créer cette clause et l’alimenter.

Remplissez le tableau qui apparaît avec un paramètre par ligne et réglez son type (texte, date, entier…). Une fois ceci effectué placez vos paramètres sur la ligne de critères. Si vous basculer en mode SQL, voici ce que vous pourrez observer :

PARAMETERS [txt_nom] Text ( 255 ), [NumSociete] Long; 

SELECT tContact.Nom, tContact.Prenom, tContact.IdSociete FROM tContact WHERE (((tContact.Nom) Like [txt_nom]) AND ((tContact.IdSociete)=[NumSociete]));

 La clause PARAMETERS est ses arguments sont terminés par un point-virgule. Coté VBA voici comment utiliser les PARAMETERS de cette requête.

Sub getName() 
Dim db As DAO.Database 
Dim qry As DAO.QueryDef 
Dim rst As DAO.Recordset 
Dim sql As String 

Set db = CurrentDb 'composition de la requete SQL 
sql = "PARAMETERS [txt_nom] Text ( 255 ), [NumSociete] Long; " 
sql = sql & " SELECT tContact.Nom, tContact.Prenom, " 
sql = sql & " tContact.IdSociete" 
sql = sql & " FROM tContact" 
sql = sql & " WHERE tContact.Nom Like [txt_nom] " 
sql = sql & " AND tContact.IdSociete=[NumSociete];" 

'creation de la requete 
Set qry = db.CreateQueryDef("rqtemporaire", sql) 
'affectation des valeurs aux parametres 
qry.Parameters("txt_nom") = Forms.FChercher.txt_nom 
qry.Parameters("NumSociete") = Forms.FChercher.numSociete 

'composition du recordset 
Set rst = qry.OpenRecordset(dbOpenSnapshot) 
'Resultat 
MsgBox "Il s’appelle " & rst.Fields("Nom").Value 
rst.Close qry.Close 
Set qry = Nothing 
Set rst = Nothing 
Set db = Nothing 

End Sub

Conclusion

Comme vous le voyez il faut passer par un objet Query pour accéder aux Parameters, puis faire un recordset à partir de ce dernier. C’est plus complexe mais lorsque vous avez de nombreuses valeurs à passer à la requête cela fait gagner du temps.

Laisser un commentaire

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