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 quelles 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 "son nom est " & rst.Fields("Nom").Value

rst.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 "son nom est " & rst.Fields("Nom").Value
...

End Sub

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

Erreur 3061 Trop peu de paramètres. 1 attendu.
Erreur 3061 Trop peu de paramètres. 1 attendu.

La seule solution à ce problème est que les paramètres de provenant de l’IHM, du Form, soient 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ée 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 issus de l’IHM ou qu’ils sont hétérogènes ; issus de plusieurs sources (VBA, résultat de requête, IHM…).

Commencez 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.

Le menu Parameters.
Le menu Parameters.

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 et 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'apelle " & rst.Fields("Nom").Value

rst.Close
qry.Close

Set qry = Nothing
Set rst = Nothing
Set db = Nothing

End Sub

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 vous gagnez du temps.

Laisser un commentaire

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