Utiliser la fonction DLookup
A quoi sert la fonction
DLookup
? Comment l’utiliser en Visual Basic ?
Présentation de DLookup
DLookup
(ou RechDom
en français) permet de rechercher une valeur unique dans une table : cette valeur est celle d’un champ précis, pour une ligne précise de la table. Même si elle n’est pas ultra-performante, DLookup a quelques avantages :
- Elle nécessite peu de code (une formule d’une ligne suffit).
- En tant que fonction VBA, elle peut s’employer dans des contextes hors programmation : un champ calculé de requête, ou une zone de texte de formulaire ou d’état par exemple. Elle peut bien sûr être exploitée en VBA si nécessaire…
Utilisation de DLookup
La fonction DLookup
reçoit 3 paramètres, dont le dernier est optionnel :
1 |
=DLookup("[nom d'un champ]", "nom d'une table", "critères") |
- En premier : le nom du champ dont on cherche la valeur. Entre guillemets, et de préférence également entre crochets. Par exemple :
"[Prix HT]"
- En second : le nom de la table ou de la requête dans laquelle on fait la recherche (sans crochets). Par exemple :
"tbl Produits"
- En troisième : un critère facultatif qui permettra de localiser un enregistrement précis. Ce critère est l’équivalent d’une clause WHERE en SQL, sans le mot-clef
WHERE
. Par exemple :"[Numéro Produit] = 1234"
Quelques exemples
- Extraire le premier nom de client trouvé (la variable
strNomClient
est de type String) :
strNomClient = DLookup("[Nom Client]", "tblClients")
- Extraire le prix du produit dont la référence st 1234, de type Numérique :
dblPrix = DLookup("[Prix]", "tblProduits", "[Référence] = 1234")
- La même chose, avec une référence de type Texte :
dblPrix = DLookup("[Prix]", "tblProduits", "[Référence] = 'JB007'")
Combiner les critères
Les critères peuvent être combinés, dans le 3ème argument de DLookup()
. Dans ce cas, ils sont séparés par le mot AND
(Ou) ou le mot OR
(Ou). Par exemple :
- Extraire le nom du premier client dont le nom commence par I et le prénom par H :
strNom = DLookup("[Nom Client]", "tblClients", _
"[Nom Client] LIKE 'I*' AND [Prénom Client] LIKE 'H*'")
DLookup
dans une requête ou sur un formulaire, les mots-clefs AND
et OR
doivent quand même être écrits en anglais, même si les objets graphiques sont en français, et même si le nom de la fonction devient RechDom()
après coup !Gérer les valeurs Null
Il se peut qu’aucune valeur ne soit trouvée dans la table, parce qu’aucun enregistrement ne répond à vos critères, notamment. Dans ce cas, DLookup
renvoie la valeur Null
. Ca veut dire que ce bout de code échoue :
1 2 |
Dim dblPrix As Double dblPrix = DLookup("[Prix]", "tblProduits", "[Numéro Produit] = 1234") |
parce qu’une variable de type Double ne peut pas recevoir de valeur Null
. Aïe. Dans ce cas, vous pouvez :
- Tester le
DLookup
avec la fonctionIsNull()
avant de l’affecter àdblPrix
- Forcer une conversion de la valeur
Null
en 0, de façon à l’affecter directement àdblPrix
. Dans ce 2ème cas, le code devient :
1 2 |
Dim dblPrix As Double dblPrix = Nz(DLookup("[Prix]", "tblProduits", "[Numéro Produit] = 1234"), 0) |
Utiliser des expressions dans DLookup
En fait, le premier argument de DLookup()
peut également être une expression combinant plusieurs champs de table, ou faisant appel à des fonctions VBA. Voici par exemple comment extraire le nom et le prénom d’un client, en les concaténant et en les séparant par un espace (seul le premier client trouvé est extrait) :
1 |
strNomPrenom = DLookup("[Nom Client] & ' ' & [Prénom Client]", "tblClients") |
Ne vaut-il pas mieux utiliser les Recordsets ?
Oui et non (z’êtes bien avancés, avec ça !).
S’il s’agit vraiment de récupérer une seule valeur, DLookup
sera plus courte à écrire. Voici par exemple la formule pour récupérer le champ Prix
d’une table tblProduits
, pour un produit dont la référence (de type Texte) est JB007
:
1 2 3 4 |
Dim dblPrix As Single dblPrix = DLookup("[Prix]", "tblProduits", "[Référence]='JB007'") MsgBox "Le prix est de " & dblPrix |
Et voici strictement la même chose avec un Recordset DAO :
1 2 3 4 5 6 7 8 9 10 |
Dim dblPrix As Single Dim rst As DAO.Recordset Set rst = CurrentDB.OpenRecordset( _ "SELECT [Prix] FROM [tblProduits] WHERE [Référence] = 'JB007'", _ dbOpenSnapshot) dblPrix = rst("Prix") MsgBox "Le prix est de " & dblPrix rst.Close Set rst = Nothing |
Pour récupérer un seul champ, le code du Recordset est un peu long. Mais s’il faut lire plusieurs valeurs, les performances seront meilleures qu’avec une suite de DLookup
. Tout dépend donc de l’usage !
Bjr a tous
Voici mon probleme:
J’ai une table « TableEmeteur » avec un seul enregistrement
Comprenat un champ « nom du beneficiaire »
En cliquant sur « procedure evenementielle » je veux que ma fonction aille recuperer le nom du beneficiaire afin de l’inserer dans le fichier créé.
Mais au lieu de cela je recoit le message :
« Impossible de trouver le champ Impossible de trouver le champ ‘I’ auquel il est fait reference dans votre expression. »
Help please
Voici ma fonction :
Private Sub Commande4_Click()
On Error GoTo Err_Commande4_Click
If Len(Dir(« c:\SERFADIN\SALARYSERFADIN.txt »)) > 0 Then
‘File exists so rename
Set db = CurrentDb
Me.[Nom du Beneficiaire] = DLookup(« [Nom du Beneficiaire] », « TableEmeteur »)
FileCopy « c:\SERFADIN\SALARYSERFADIN.txt « , « c:\SERFADIN\ » & Me.[Nom du Beneficiaire] & « – » & Format(Now, « ddmmyyyyhhnnss ») & « .txt »
Kill « C:\SERFADIN\SALARYSERFADIN.txt »
MsgBox « File Created »
Else
‘File does not exist – Unable to rename
‘MsgBox « File does not exist »
DoCmd.Close acForm, « Bank »
End If
DoCmd.Close acForm, « Bank »
DoCmd.Quit
Exit_Commande4_Click:
Exit Sub
Err_Commande4_Click:
MsgBox Err.Description
Resume Exit_Commande4_Click
End Sub
Je ne vois pas de champ « I » dans le code.
Par contre, quelques pistes :
1. Si l’objectif est d’utiliser une valeur dans un nom de fichier, il n’est pas utile de stocker cette valeur dans un champ de formulaire. Je passerais plutôt par une variable. Ca donnerait quelque chose comme ça (je reprends seulement une partie du code, après le CurrentDb) :
2. CurrentDb n’est pas utile ici (il ne sert pas dans le cas d’un DLookup()), et je vois pas la variable utilisée ailleurs.
Merci ca marche super bien
Bonsoir,
Je m’arrache les cheveux pour refaire quelque chose qui a du être créé des centaines de fois, à savoir une gestion sous VBA Access ‘ADO’ de la gestion des conditions de paiement. Je n’ai rien trouvé me permettant une base de départ. Auriez vous une idée pour que je ne me refasse pas toute la procédure ?
Cordialement
Je n’ai pas ce type d’exemple sous la main.
Une première piste serait de chercher dans les exemples de bases Access.
Sinon, par défaut, une recherche Google…
Bonjour Hervé!
Pourquoi quand je met sur une requête ou un formulaire cette formule =DLookUp(« [Date] », »Temps ») Access me signale une erreur de syntaxe.
Et même quand je copie une formule qui marche à ailleurs. Access me donne le même message.
Doit on paramétrer d’abord la fonction DLookUp()?
Aider moi je veux bien utiliser cette fonction.
Il n’y a rien de particulier à paramétrer. Par contre, je vois que Dlookup() est utilisé dans un formulaire. Ça veut dire que le délimiteur doit être ; à la place de , (sur une machine française en tout cas). Du style :
Après, il faut aussi que la base contienne une table ou une requête qui s’appelle « Temps », laquelle doit contenir un champ qui s’appelle « Date »), vu ce qui est écrit dans le DLookup().
Aidez moi j’ai créer une Base de donnée accès avec une table utilisateur (prénom et nom; userlogin; password; sécurité utilisateur: administrateur ou simple) j’ai une formulaire Utilisateur(Nom Utilisateur, Mot de Passe). Maintenant je veux que si on entre on met son nom utilisateur et mot de passe à verifier sur la table utilisateur et on pourra entrer dans le formulaire menu et affiche le nom d’utilisateur et sa securité utilisateur(administrateur ou simple) JE VEUX LE CODE
Private Sub Commande1_Click()
Dim Db As Database
Dim Rs As Recordset
Set Db = CurrentDb
Set Rs = Db.OpenRecordset(« Utilisateur »)
If IsNull(Me.TxtLoginId) Then
MsgBox « Veuillez Entrer Votre Identifiant S.V.P. », vbInformation, « Identifiant »
Me.TxtLoginId.SetFocus
ElseIf IsNull(Me.TxtPassword) Then
MsgBox « Veuillez Entrer Votre Mot de Passe S.V.P. », vbInformation, « Mot de Passe »
Me.TxtPassword.SetFocus
Else
‘process the job
If Rs.Fields(« UserLogin »).Value = TxtLoginId.Value Then
If Rs.Fields(« Password ») = TxtPassword.Value Then
MsgBox « Identifiant et Mot de Passe sont correctes »
TxtLoginId.Value = « »
TxtPassword.Value = « »
DoCmd.OpenForm « Menu »
Me.Visible = False
Else
MsgBox « Identifiant et Mot de Passe sont Incorrectes », vbInformation, « ACCES AU MENU »
End If
End If
End If
End Sub
Merci de respecter un minimum la Netiquette en postant sur un blog ou un forum. 😉
Re-bonjour,
J’ai une question complémentaire à vous poser. Sans vouloir abuser.
Dans le recordset j’indique WHERE [RefPOL] = ‘POL0001′”,
Cependant y-a-t-il moyen de demander qu’il retourne toutes les valeurs en lien avec la valeur sur laquelle on a cliqué de manière générique plutôt que d’indiquer une référence précise Car cela m’oblige à dupliquer le recordset sur toutes les valeurs séparément.
Grand grand merci,
Je suppose qu’on a récupéré POL0001 dans une variable de type String (
strParametre
). Dans ce cas, on peut écrire :Ouala !
Bonjour,
Tout d’abord un tout grand merci pour ces explications claires et concises.
J’ai malgré tout un petit souci… J’ai crée une base de données comprenant 4 tables (politiques – process – procédures – opérations). Ces tables ont des relations de type plusieurs à plusieurs. Par conséquent j’ai crée 3 tables de jonction (JCTPolitiquesProcess – JCT ProcessProcédures – JCTProcéduresOpérations).
J’ai ensuite crée 1 formulaire Politique auquel est lié un formulaire Process auquel est lié un formulaire Procédure auquel est lié un formulaire Opérations (à chaque fois sur double clic de la référence concernée).
C’est là que le choses se compliquent. Lorsque je double cliquait sur une référence de Politique par exemple, Access me retournait toutes la liste de Process présentent dans la table Process et pas uniquement les process liés à la politique en question.
La formule DLookup ne m’intéressant pas dans ce cas présent, j’ai intégré le recordset ci-dessous, mais il me retourne une erreur de type : Run time error 13 – type mismatch/
Private Sub RefPOL_DblClick(Cancel As Integer)
Dim dblRefPR As Single
Dim rst As DAO.Recordset
Set rst = CurrentDb.OpenRecordset( _
« SELECT [RefPR] FROM [JCTPoliciesProcesses] WHERE [RefPOL] = ‘POL0001′ », _
dbOpenSnapshot)
dblRefPR = rst(« RefPR »)
MsgBox « La RefPR est de » & dblRefPR
rst.Close
Set rst = Nothing
End Sub
Pouvez-vous me dire comment je dois rédiger ce code afin que cela fonctionne. Comme je suis novice dans le domaine je ne comprends pas toutes les subtilités du langage.
Un tout grand merci d’avance
RefPR est un champ de quel type ?
J’ai l’impression qu’il s’agit d’un champ de type Texte, ce qui expliquerait le « Type mismatch ».
Ceci veut dire qu’il faudrait plutôt déclarer la variable équivalente de cette manière :
Et adapter plus bas :
Vu le type d’extraction, un DLookup devrait suffire. Ça donnerait :
En relisant les conditions : si la condition
WHERE
peut renvoyer plusieurs lignes :1. Effectivement, le DLookup() ne fera pas l’affaire.
2. Le code VBA nécessitera une boucle pour parcourir le Recordset.
3. … mais ça ne sera pas très pratique ergonomiquement (pour l’affichage, les mises à jour éventuelles).
4. Au final, est-ce que la piste ne serait pas un sous-formulaire ? 😉
Merci pour votre réponse.
Effectivement la condition where doit pouvoir renvoyer plusieurs lignes.
Et ce serait plus logique que je fasse des sous formulaires vu que je descend à chaque fois d’un niveau.
Comment puis-je faire un sous+formulaire de type datasheet à partir d’un formulaire qui lui aussi est de type datasheet?
Lorsque j’aurais fait ces sous-formulaires, devrais-je encore utiliser un code VBA pour parcourir le recordset? Si oui, est-ce que je dois l’écrire de la façon suivante?:
Dim strSQL As String
strSQL = « SELECT [RefPR], [JCTPoliciesProcesses] WHERE [RefPol] = ‘ » & strParametre & « ‘ »
J’espère ne pas abuser…
En tout cas je vous remercie beaucoup.
Un formulaire en mode Feuille de données (DataSheet) ne peut pas intégrer un autre formulaire (mais je ne pense pas que ce soit un inconvénient : ça ferait une interface graphique chargée). Par contre, on peut faire en sorte d’ouvrir un autre formulaire à partir du sous-formulaire Feuille de données.
La représentation classique est :
1. Un formule en mode Colonne simple (ou Formulaire unique).
2. Un sous-formulaire en mode quelconque (DataSheet étant plus clair pour l’utilisateur).
Dans le cas de formulaire/sous-formulaire, l’affichage est géré par Access, il n’y a pas besoin de Recordset.
Il y aura peut-être une ligne de VBA pour afficher un autre formulaire, si ça se présente.
Bonjour,
Je reviens vers concernant la création de sous formulaires. Cela me semble logique. Cependant je n’y arrive pas. Je ne sais pas si on peut créer des sous-formulaires dans un formulaire de type datasheet et qui sont par ailleurs liés avec une relation plusieurs à plusieurs?
Si cela n’est pas possible, quelle code puis-je utiliser dans des formulaires liés pour que sur double clique sur une référence il ouvre le formulaire lié et ne fasse appaître que les enregistrements liés (via une table de jonction contenant RefPol et RefPR).
Merci de votre compréhension
Pour compléter ma réponse précédente, il est possible de faire apparaître un sous-formulaire basé sur une relation Plusieurs/Plusieurs.
1. Le formulaire principal sera basé sur la table principale à afficher (ou sur une requête s’il y a besoin de tris, de calculs, etc.).
2. Le sous-formulaire sera basé sur une requête qui assemble la table de jonction et la 3ème table.
3. Pour faire simple lors des premiers tests, il vaut mieux que cette requête comporte TOUS les champs des tables.
4. Il faudra ensuite paramétrer les champs pères/fils du sous-formulaire pour relier la clef primaire de la table principale à la clef étrangère de la table de jonction.
Pas facile à expliquer comme ça, mais le principe est là ! 🙂
salut Hervé, j’ai une question. Comment peut-on obtenir la plus grande valeur et par catégorie dans une requête. je m’explique : j’ai une requête ayant un champs Produit : riz, banane, mangue ayant plusieurs enregistrement et un champs Prix donnant le prix de chaque produit je voudrais faire une autre requête qui me donnera la liste de produit le plus chair et le moins chair.
Merci.
C’est le prix mini/maxi de chaque produit que tu cherches, ou le prix mini/maxi global ?
catvando78 > Quelle est la partie qui ne marche pas ?
La table PARAMS existe bien, et elle contient bien un champ ID de type Numérique ?
Bonjour, J’ai un problème avec DLookup que je ne comprends pas, car cela fonctionnait avant puis cela a cessé brusquement et impossible de le rétablir sous peine de message « argument ou appel de procédure incorrect ».
Voici ce dont il s’agit : j’ai un formulaire principal pour les paiements (basé sur requête finances, basée sur tables adhérents et finances), et un sous formulaire (basé sur requête détail_finances basée sur table détail_finances avec calcul Total par Ligne et Total_Déplacement) où, par ligne, on a l’année de l’opération, une liste déroulante pour choisir le type de règlement, puis les champs monétaires correspondants : abonnement, cotisation, hotel, transport, single, etc.
J’étais arrivée à ce que, par DLookup, en Got_Focus, l’année soit cherchée dans une table appelée PARAMS, colonne Valeur, position 6, par le code VBA :
Private Sub Année_GotFocus()
Me.Année = DLookup(« Valeur », « PARAMS », « ID = 6 »)
End Sub
puis pour les autres champs, j’avais écrit les codes du style (je n’en donne que 2)n toujours en Got_Focus :
Private Sub Cotisation€_GotFocus()
If Me.Type = « COTS » Then
Me.Cotisation€ = DLookup(« Valeur », « PARAMS », « ID = 1 »)
ElseIf Me.Type = « COTC » Then
Me.Cotisation€ = DLookup(« Valeur », « PARAMS », « ID = 2 »)
Else: Me.Cotisation€ = 0
End If
End Sub
ou
Private Sub Single€_GotFocus()
If Me.Type = « SINGL » Then
Me.Single€ = DLookup(« Valeur », « PARAMS », « ID = 5 »)
Else: Me.Single€ = 0
End If
End Sub
C’est la 1ère fois que je me sers du VBA, et je ne suis pas très sure d’avoir tout compris. J’ai dû modifier un critère quelque part dans une table ou faire une mauvaise manip, toujours est-il que je n’y arrive plus.
D’avance merci de m’aider.
Salutations, Catherine vd
roman > Euh ? 😉
sar
Anais > Super, content que ça marche ! 🙂
J’avais simplement fait une faute dans la clause where de ma requête, inversion de deux lettres ^^ donc c’est bon, merci tout fonctionne bien depuis hier,
voilà, je fais maintenant un publipostage sous forme de tableaux sous Word, donc votre blog est vraiment clair avec toutes les astuces,
Merci beaucoup
Anais > Que contiennent
MotPasseSaisie
etServiceSelectionne
? Est-ce que ce sont des valeurs existantes dans la tableServiceE
?Notamment, est-ce que ceci affiche le bon critère SQL :
En passant :
LoginX
etNomService
sont bien des champs de la tableServiceE
?Maintenant, la fonction renvoie toujours une valeur nulle même si le login saisi est bon.
Après vérification, l’erreur était loginApplication dans l’écriture de la condition, tout bête 😀
Merci encore, maintenant il faut que je regarde la suite du projet
Bonjour, merci beaucoup de m’avoir répondu.
Bon, c’est bien à l’appel de la fonction DLookUp que l’opération est annulée.
Le message Hello n’est pas lu.
Anais > De quel endroit est appelé le code VBA dont on parle ? Parce que je pense que c’est cet appel qui est considéré comme annulé (sans doute à cause du
DoCmd.Close
). Par contre, si leDLookup()
est correct, ce n’est sans doute pas lui qui génère ce message. J’essaierais de placer unMsgBox "Hello"
juste sous leThen
(et avant leDoCmd.Close
), pour vérifier.Bon, j’ai tout rectifié au niveau des erreurs, mais VBA m’annule tout simplement l’action avec erreur ‘2001’ : opération annulée.
Bon, je viens de rajouter les & & pour les expressions dans la clause de condition.
Bonjour, j’utilise la fonction DLookUp comme ceci :
If IsNull(DLookup(« [LoginX] », « ServiceE », « [LoginX]= ‘MotPasseSaisi’ And [NomService] = ‘ServiceSelectionne' »)) Then
‘ Fermer la boîte de dialogue « Identification »
DoCmd.Close
MsgBox « Le mot de passe saisi est incorrect. », vbExclamation
Mais lorsque je déclenche le processus, il ne me trouve pas loginX qui est bien dans ServiceE.
Merci d’avance.
Anais
Anais > Ce serait effectivement plutôt quelque chose comme :
Bon sang ! Un sujet qui date mais un auteur toujours vivace et qui répond gentiment. Pour ma part, je n’étais venu que chercher une information de fonctionnement. Cependant, il fallait saluer le travail de M. Inisan.
David > On peut faire de cette manière : dans l’événement AfterUpdate du numéro d’article (NumArticle, donc), écrire quelque chose comme :
A aménager. Dans mon exemple :
Bonjour,
je cherches quelques lumières sur un petit problème :
J’ai une base access 2007 avec deux formulaires F_ARTICLE et F_FACTURE
basés respectivement sur deux tables ARTICLE et FACTURE et un sous-formulaire F_DETAIL_FACTURE. Dans ce dernier, bien que le champs NumArticle est lié au champs NumArticle de la table ARTICLE j’ai tout de même choisi, pour des raisons pratiques de reprendre aussi le champs PrixArticle afin qu’il apparaisse dans F_DETAIL_FACTURE
J’aimerais lorsque je renseigne dans celui ci le champs NumArticle le champs PrixArticle reprenne automatiquement la valeur adéquate.
J’ai pensé à RechDom mais je ne sais pas l’intégrer en vba; j’ai également essayé en événement BeforeUpdate comme suit :
Me. [PrixArticle]=[ARTICLE]![PrixArticle]
ça ne marche pas ! auriez vous des pistes ?
Merci pour vos lumières
wiiking73 > En écrivant cela, tu lis seulement le 1er niveau disponible de la table
T_Intervenant
, puisqu’il n’y a pas de filtre. Donc tu extrais un niveau qui ne correspond pas forcément à l’utilisateur.Ce que tu peux faire, par contre, c’est aménager le code précédent (
intNiveau
ayant été déclarée en global) :Ok par contre je n’arrive pas à transformer le champ niveau de ma table en variable globale.
J’utilise
Dim intniveau As integer
intniveau = Dlookup »[Niveau] », « T_Intervenant »)
mais lorsque je change de formulaire ça ne prend pas en compte la variable et du coup les boutons restent apparents.
Merci d’avance
Wiiking73 > Oui. La première chose à faire, peut-être, serait de stocker le nom (login) de l’utilisateur et son niveau dans 2 variables globales, de façon à les utiliser n’importe où dans l’application. Appelons ces variables
strUtilisateur
(de type String) etintNiveau
(de type Integer), par exemple. Il suffit ensuite, dans l’événement «Sur ouverture
» du formulaire, d’écrire quelque chose comme :Dans cet exemple, le bouton est invisible pour les niveaux 1, et visible pour les niveaux 2. On peut bien sûr ajouter autant de boutons et autant de niveaux que nécessaire.
Ouala !
OK ça fonctionne bien . merci 🙂
Encore une petite question, du coup quand j’ouvre le formulaire suivant, il y a plusieurs boutons (maintenance préventive; maintenance curative, stock). Chaque opérateur aura un niveau. 1 pour ouvrir uniquement la maintenance préventive, 2 pour la préventive et curative et 3 pour les 3 boutons.
Les niveaux sont rajoutés dans la table T_Intervenant. Serait il possible de bloquer les boutons selon le niveau de la personne connectée??
Bonjour
Tout d’abord bravo pour ce blog qui m’as deja bien fait avancé dans la conception de ma base.
Je suis en train de (essayé de!!) développer une base de maintenance. Je souhaiterai faire un premier formulaire login/mot de passe. Le login est en liste déroulante et le mot de passe est à completer par le technicien. J’ai fait un code que j’ai mis sur le bouton « valider »:
Dim vPassword As Variant
vPassword = Dlookup(« [Motdepasse] », »T_Intervenant », »Motdepasse = Password »)
‘pas bon
if isnull(vPassword) Then
MsgBox « Login et ou mot de passe incorrect »
else
‘c’est bon et on ouvre le formulaire
Docmd.Openform « ecran principal »
end if
La table T_Intervenant contient le login et le Motdepasse (plus le numéro auto). Password est un texte indépendant sur le formulaire Login/Mot de passe.
Cela fonctionne sauf que si je rentre un mot de passe d’un utilisateur X avec un login d’un utilisateur Y ça marche aussi
Alors please Help!!!
Merci
Wiiking73 > Il faut vérifier à la fois le login et le mot de passe (sinon, on entre dans la base avec l’un ou l’autre). D’autre part, il faut concaténer la condition du DLookup() pour y injecter les valeurs saisies. Ça donnerait :
J’ai supposé que Utilisateur et MotDePasse étaient les champs de la table, et que les valeurs saisies s’appelaient strUser et strPassword. Je mettrais plutôt [Utilisateur] (ou [Login], si c’est le nom du champ dans ta table) en 1er paramètre du DLookup(). Ici, ça n’a pas d’importance réelle, l’intérêt est surtout de vérifier si on récupère quelque chose, mais c’est pour la forme 🙂
A défaut de pouvoir éditer le post qui ne va pas tarder à apparaitre, je retire ma question sur l’apostrophe j’avais zappé la première ligne qui l’expliquait.
.
J’ai finalement réussi à faire ma macro (Voir le bout de code qui suit). La Textbox6 permettant de contrôler que la macro fonctionne (à terme celle ci aura le même type de requête), et j sera réutilisé.
.
Private Sub Commande2_Click()
Dim i As String
Dim j As String
i = Texte0.Value
j = DLookup(« [IDPersonne] », « Personnes », « [Nom]=' » & i & « ‘ »)
Texte6.Value = j
EndSub
.
.
Encore merci pour l’aide apportée.
Tout d’abord, merci pour cette promptitude à la réponse. J’ai peut être voulu être trop synthétique.
.
.
J’aimerais revenir sur ce que tu m’as marqué:
Adaptons : j = DLookup(« [Nom] », « Personnes », « [Nom]=' » & i & « ‘ »)
en: j= DLookup(« [Nom] », « Personnes », « [IDPersonne]=' » & i & « ‘ »)
le double guillemet « » permet bien de sauter une colonne ?
IDPersonne | Nom | Prénom |
53 | Emmare | Jean |
54 | Dupond | Henri |
Pour i=Dupond il devrait me définire j=54 ? (Je viens de tester en parallèle cette syntaxe, et ça bug au niveau du DLookup et j= » »)
.
Quel sens a le signe ‘ ?
.
.
.
Pour dire vrai. j’ai 6 Tables (± imposées par le projet éducatif):
-CmdImg Commande des images
-Evenements Événements auxquels appartiennent les images.
-Images
-Personnes
-Présence
-Tarifs
Dans la table présence, je veux relier l’IDFichier au IDPersonne, et à un IDFichier peu correspondre n IDPersonne.
Ce qui m’intéresse est de venir chercher dans la base personne l’IDPersonne qui correspond au Nom de la personne que j’ai tapé dans mon interface.
.
Le but de la macro à terme (mais je veux aussi me prendre la tête là dessus, mais j’arrivais pas à mettre en place ce DLookUp) est que lorsque je lance une recherche via un critère (Nom,Prénom,Surnom,Evenement) je puisse trouver les photos associées.
.
.
Dans un second temps, il me faudra pouvoir ajouter une/des photos à une commande, édition de facture, bla²… rien de palpitant, et déjà fait sur Excel quelque chose de similaire 🙂
MuadJabbar > Comme le nom est de type texte, il faut le délimiter d’apostrophes. D’autre part, la variable ne doit pas figurer dans le critère, mais elle doit être concaténée. Ce qui donnerait :
j = DLookup("[Nom]", "Personnes", "[Nom]='" & i & "'")
Mais dans ce cas, ça m’amène une question : le
DLookup()
ne sert plus à rien ici, puisqu’on fait une recherche sur un nom qu’on connaît déjà. On va nécessairement retrouveri
. Ou bien…?Je pense en fait qu’il faut peut-être revoir l’analyse des tables. S’il y a des personnes et des images, ça veut dire :
Il faut donc 3 tables pour gérer ça :
Et après, le
DLookup()
ne sera sans doute plus utile : il sera possible de construire un formulaire principal Personnes, avec un sous-formulaires Images.Salut,
Noob spoted 🙂 Après moults errements sur différents forums et sur l’aide de VBA/Access (et ce post), il me semble que la commande Dlookup est la plus adapté à mon cas. Cependant, j’arrive pas à la mettre en pratique
Pour mettre dans le bain, cependant le bouton fait presque rien, je cherche juste à comprendre pourquoi ma syntaxe n’est pas juste
Tables:
-J’ai une interface utilisateur ou je cherche à afficher des photos où M. Dupont est dessus.
– J’ai une table « Personnes »: [IDPersonne],[Nom],[Prénom],…
– J’ai une table « Images »: [IDFichier],[Adresse Fichier],[Evenement],[Personnes sur la Photo],…
Interface:
– J’ai une zone de texte ou je rentre un « [Nom] » (de famille).
– J’ai un bouton qui doit chercher le « [Nom] » dans la Table « Personnes » et afficher une liste des photos où apparait M. Dupont.
– J’ai un cadre image.
Le code associé à ce bouton est le suivant:
Private Sub Commande2_Click()
Dim i As String
Dim j As String
i = Texte0.Value
j = DLookup(Nom],Personnes,i)
‘j = DLookup(« [Nom] », « Personnes », « [Nom]=i ») LIGNE DÉSACTIVÉE
End Sub
Ce programme bug à la ligne du Dlookup, j’analyse les valeurs, je trouve i=Dupont qui est Texte0.Value , et Personnes et Nom sont Vide. (sans les Crochets et Guillemets, j’arrive à lire les valeurs, tandis qu’avec, rien ne s’affiche)
triton > Comme c’est une question sur un autre sujet, le mieux est de continuer la conversation sur les forums du site. Ce sera plus pratique.
Inscris-toi et reposte la question là-bas, on s’y retrouve 🙂
En effet, et un grand merci!J’ai bien compris maitenant à quoi sert exactement la requête et le formulaire(j’avais mal pensé le problème). Sans vouloir abuser, 1 point délicat:
– j’essaie de construire une base de donnée sur l’exemple d’une exploitation agricole. J’ai donc une table « parcelle » avec une série de champs et notemment le champ « variété plantée ». Les valeurs de ce champs se trouvant dans une seconde table « variétés » disposant d’un champ unique « variétés disponibles » listant toutes les variétés possibles. Enfin une troisième table » journal taches journalières » destinée à identifier les taches realisées sur chaque parcelle et variété.
Le problème est que si l’année suivante une variete plantée(golden) est remplacée par une autre (gala) la table « journal… » est(trop) affectée (actualisée): les tâches antérieures qui ont été effectuées sur l’ancienne variété (golden) apparaissent désormais comme si elles avaient été réalisées sur la nouvelle (gala)! Comment résoudre ce problème? D’avance merci!
triton > Sauf cas particulier, les champs Nom et Prénom ne doivent pas se trouver dans la table Tâches. L’une des raisons étant que ça créerait des doublons dans les données, ce qui est à éviter en bases de données. Donc seul le code de l’agent doit se retrouver dans la table des tâches (et il doit y avoir une relation entre Agents et Tâches, sur ce code). Si tu as ensuite besoin de toutes les infos, tu peux créer une requête basée sur les 2 tables. Si tu construis un formulaire sur la requête, tu as toutes tes infos, sans faire appel à DLookup.
Bonjour,
moi aussi je commence avec access et j’ai le doute suivant:
si je dispose de 2 tables, l’une s’appelle « agents » avec les champs: 1-code, 2-nom, 3-prenom et une seconde table « tâches réalisées » avec les champs: 1-code, 2- nom, 3-…….
Pour remplir le champs « code » de la deconde table je fais donc une recherche ds les registres de la première,…et pour simplifier le reste j’aimerai que le champs « nom » de la table « taches » se remplisse seul en fonction du champs « code » rempli.
Je dois utilisé le DLookup?
Merci pour votre aide!
Merci beaucoup!
firefly_459 > Dans ce cas, pas besoin de
DLookup()
qui est une recherche ponctuelle. L’équivalent desRechercheV()
– ouVLookup()
– sur Excel est tout simplement les relations sur Access. Tu peux donc faire ça :A ce stade là, si tu exécutes la requête, tu obtiens la liste des correspondances exactes entre les 2 tables (donc l’inverse de ce que tu cherches, mais on n’est pas loin :-)). Ensuite :
Tu obtiens maintenant toutes les lignes de la table1 (ou table2, selon le choix du dessus), et les correspondances éventuelles de la table2. S’il n’y a pas de correspondance, le champ de la table2 est vide. Pour afficher seulement les lignes de table2 qui ont un souci (donc qui sont vides), tu rajoutes un critère
Null
sous le champ2.Tu peux faire la même opération en inversant le sens de la flèche entre les 2 tables…
Non, elles sont dans deux tables différentes. Mais je peux faire un query pour les mettre l’une à côté de l’autre si c’est plus simple…
firefly_459 > Les colonnes sont dans la même table ?
Bonjour,
Je suis débutant en access. J’ai 2 colonnes de plus ou moins 300 000 données. J’aimerais juste savoir quels sont les données qui sont dans une colonne et pas dans l’autre et vis versa. Une macro avec la fonction DLOOKUP est-elle la solution? où y-a-t-il plus rapide? Comment dois-je m’y prendre pour que le résultat de la macro soit dans une colonne du fichier access? En excel, il y a la fonction VlOOKUP qui répond exactement à ma demande mais là j’ai trop de données pour le faire en excel…
Merci d’avance pour votre réponse
El Bachir > Je ne vois pas bien la structure de la table. Mais s’il faut appliquer 2 conditions, c’est détaillé dans le point « Combiner les critères », plus haut. Si tu cherches une égalité stricte, remplace les
"[champ] LIKE 'I*'"
de l’exemple par des"[champ]
=
valeur
" (attention aux apostrophes, si les champs sont de type Texte).je vous remerier d’avance pour vottre aide ,j’ai un petit probleme avec la fonction dlookup ,je veux renvoyer la valeur d’un champ quirépond à deux condition .mais je ne sais pas comment
exemple :
les chams suivants dans la premiere table:
champs 1)enreg. 2)enreg. 3)enreg.
variété cle cle cl
type de taille fort leger moyen
unité fertilisante 20 10 15
pour renvoyer les valeurs de (unité fertilisante ) qui depond de la variété et de type de taille.
Exactement ce que je cherchais à savoir! tout est dit =D
Merci!! ^^
Clair et précis merci pour le boulot effectué
Je vous remercie pour votre réponse qui a été rapide. Comme je ne suis pas une pro d’Access, j’ai du avancer sur d’autres problèmes qui auraient dus être résolus avant même que je vous pose ma question.
Je pense que je suis dans le dernier cas que vous évoquez: je veux faire un nouvel enregistrement qui comporte la référence d’un contact, mais si je dois vérifier si le nom et le prénom de ce contact sont déjà dans ma table. S’ils sont présents je dois choisir ensuite de conserver cette référence pour mon nouvel enregistrement ou d’en créer un nouveau (personne qui aurait les mêmes noms et prénoms mais qui serait un homonyme).
Comme je ne parviens pas à expliquer le problème que je rencontre actuellement en termes simples, je m’arrête-là… mais pas sans vous remercier pour votre réponse efficace.
> Lavebel : s’il s’agit juste d’éviter les doublons, je jouerais à un niveau plus bas, en définissant un index sur les champs, dans la table (pas un index sur chaque champ, mais un index composé, à l’aide de l’icône Index). Ca garantira que la paire Nom/Prénom sera bien unique, quel que soit le mode d’alimentation de la table. Par exemple, si la table est alimentée via un fichier texte externe, la vérification des noms/prénoms sera déclenchée par le moteur, et les doublons ne passeront pas. Autre avantage : ça ne nécessite aucun code VB…
Maintenant, s’il s’agit de faire une vérification ponctuelle, un
DLookup
peut effectivement convenir. Attention à bien gérer l’enregistrement lui-même aussi. Je m’explique : si je crée un enregistrement avec Nom = Hervé et Prénom = Inisan, il n’existe pas dans la table, ça passe. Maintenant, si je suis en cours de modification du même enregistrement, l’enregistrement existe forcément dans la table, et me sera renvoyé par leDLookup
.On peut s’aider de la propriété booléenne
Me.NewRecord
pour détecter si on est sur enregistrement nouveau ou pas (du style : siMe.NewRecord
, lancer leDLookup
, sinon ne rien faire).Je cherche à vérifier si le Nom et le Prénom d’un client que je saisis dans une formulaire sont identiques à d’autres champs Nom et Prénom existants déjà dans la même table. Dlookup est-il la bonne façon de faire? Et si oui, comment puis-je faire apparaître « sur le même écran de formulaire » tous les enregistrements identiques existants? Oui, moi aussi je suis un bleu en access mais je trouve que votre site, lui au moins , a le mérite d’être très clair. Bravo!!
Si l’objectif est d’éviter des valeurs identiques dans un champ, ce n’est pas par
DLookup()
qu’il faut procéder (on pourrait, mais ça fait du code à ajouter, et ce n’est pas la meilleure solution). La solution « naturelle » est d’ouvrir la table en mode Création, de se placer sur le champ concerné, et de lui ajouter un index sans doublons (en bas de l’écran). Ce sera le moteur de base de données qui gèrera les contraintes, automatiquement.Salut,
C’est très bien expliqué. Mais je ne sais pas si c’est la bonne manip que je dois faire (je suis un bleu en access !). Parce que j’ai essayé et la formule ne marche pas.
Voilà, je cherche à paramètrer un champ de ma table afin qu’il n’y ai pas de répétition par rapport à toutes les valeurs antérieures de ce même champ lors de la saisie (valide si). Problème classique sans doute mais je suis un débutant…
juste un peti commentaire pour vous dire que c’est agréable e lire votre blog 🙂