OVH Cloud OVH Cloud

Tester si Doublon/Homonyme

13 réponses
Avatar
b
Salut à tous,
J'ai bien chercher ici et un peu partout, je trouve pas ce que je voudrai !
Cela concerne la vérification de doublons sur NOM, PRENOM et DDN (date de
naissance).
Sachant que ma table contient déjà des doublons qu'il ne faut pas supprimer
:
Je voudrai lors de la saisie, avertir par un Msgbox quand NOM & PRENOM & DDN
existe déjà.
Puis laisser à l'utilisateur le soin de Valider ou pas cet homonyme.
Merci de votre aide.
@ +

b(°!°)rbbu

10 réponses

1 2
Avatar
Michel Walsh
Salut,



If 0 < CurrentDb.OpenRecordset("SELECT COUNT(*) FROM maTable WHERE Nom=""" & Me.Nom & """ AND
Prénom=""" & Me.Prénom & """ AND DDN= " & Format(Me.DDN, "#mm-dd-yyyy#" ) ).Fields(0).Value
Then

... il y a déjà quelqu'un

End If


On peut remplacer la syntaxe par un simple DCount, il va s'en dire. J'ai préfixé les valeurs
candidates par Me, supposant qu'elles provenaient du formulaire qui exécute le code.


Espérant être utile,
Vanderghast, Access MVP


"" wrote in message news:bf8cc7$ecq$
Salut à tous,
J'ai bien chercher ici et un peu partout, je trouve pas ce que je voudrai !
Cela concerne la vérification de doublons sur NOM, PRENOM et DDN (date de
naissance).
Sachant que ma table contient déjà des doublons qu'il ne faut pas supprimer
:
Je voudrai lors de la saisie, avertir par un Msgbox quand NOM & PRENOM & DDN
existe déjà.
Puis laisser à l'utilisateur le soin de Valider ou pas cet homonyme.
Merci de votre aide.
@ +

b(°!°)rbbu




Avatar
Anor
Bonjour Michel, Bonjour 3stone

Pour m'amuser, et parce que je pensais que les fonctions de domaine étaient beaucoup plus lentes
que la méthode des recordsets,
j'ai comparé les performances des 2 méthodes que vous proposez :

Lorsque la méthode :
n = DCount("*", "LaTable", "LeTexte='aerodrome'")
met 6 secondes pour faire X fois le calcul ci-dessus,

la méthode
n = CurrentDb.OpenRecordset("SELECT COUNT(*) FROM LaTable WHERE
LeTexte='aerodrome'").Fields(0).Value
met 8.4 secondes pour faire X fois le calcul.

Voilà, je suis un peu surpris par ce résultat inattendu mais je serais curieux de trouver une
3ème méthode plus rapide ;-)))

PS : je ne vous dirai pas que dans mes tests, X = 1000 car vous allez vous moquer si chez vous,
la même chose met 1 seconde :'-(

--
à+
Arnaud
-------------------------------------------
Conseils d'utilisation, sites recommandés :
http://users.skynet.be/mpfa/
petit à petit, www.anor.fr.st fait son nid
-------------------------------------------
Avatar
Anor
Bonjour 3stone,

.../...
| il est peut probable que dans l'exemple dont il était question, la
| "différence" que tu as mesurée soit remarquée...

tu as raison.

Mais si je suis attentif aux "contre-performances" des fonctions de domaine,
c'est que j'aimerais bien résoudre un jour "un problème" sur une des bases
que j'avais faite il y a un an.

Il y a une table avec des données journalières
une requête qui cumule les résultats par semaine
une "sur-requête" qui fait une runningsum sur les précédents cumuls
et calcule les écarts (qté reçues) entre 2 semaines
(reçu = traité semaine + restant semaine - restant semaine précédente )
un état qui affiche l'évolution du nombre de "reçu" dans un beau graphique "glissant"

Sur des PIII 450, l'état met 10 minutes pour s'afficher !!
J'avais mis en place une table temporaire qui ne se recréait qu'une fois par semaine,
mais cette solution ne me satisfaisait que comme solution transitoire...

Voilà pourquoi si j'intercepte des méthodes plus rapides dans le cas de l'utilisation
de runningsums basées sur des fonctions de domaine, alors j'achète le brevet ;-))

Il est vrai que les utilisateurs ne m'ont jamais fait la moindre remarque sur ce "détail",
mais bon ...

--
à+
Arnaud
-------------------------------------------
Conseils d'utilisation, sites recommandés :
http://users.skynet.be/mpfa/
petit à petit, www.anor.fr.st fait son nid
-------------------------------------------
Avatar
Pierre CFI
Salut les génies

Sur le probléme des boucles, j'ai aussi un cas difficile
Une plage, de l'eau de mer, du soleil, des fruits de mer et une sieste. par
quoi commencer ? sachant que j'ai fais ma communion à 11 ans, par quoi dois
je commencer et quelle sera la durée de la boucle ?
bon courage... forçats :O)))
Avatar
Anor
Bonjour ,


| Salut et merci de suivre,
| Ok, ton code je l'avais déjà tester, mais ce qui me gène c'est le
| AvantMiseàJour !
| Si on revient sur une fiche pour modifier par exemple l'Adresse, ce
| code se déclanche et c'est pas bon ...
.../...

Dans ce cas, tu mets le code de 3stone dans l'événement
"sur avant mise à jour" du contrôle NomP au lieu de le mettre
sur avant mise à jour du formulaire.


--
à+
Arnaud
-------------------------------------------
Conseils d'utilisation, sites recommandés :
http://users.skynet.be/mpfa/
petit à petit, www.anor.fr.st fait son nid
-------------------------------------------
Avatar
Anor
Salut Pierre,


| Sur le probléme des boucles, j'ai aussi un cas difficile
| Une plage, de l'eau de mer, du soleil, des fruits de mer et une
| sieste. par quoi commencer ? sachant que j'ai fais ma communion à 11
| ans, par quoi dois je commencer et quelle sera la durée de la boucle ?

Commence donc par la sieste, mais cette fois ci, pas sous le soleil, et le plus longtemps
possible,
tu en as besoin ;-)))

--
à+
Arnaud
-------------------------------------------
Conseils d'utilisation, sites recommandés :
http://users.skynet.be/mpfa/
petit à petit, www.anor.fr.st fait son nid
-------------------------------------------
Avatar
3stone
Salut Anor et barbbu,



| Ok, ton code je l'avais déjà tester, mais ce qui me gène c'est le
| AvantMiseàJour !
| Si on revient sur une fiche pour modifier par exemple l'Adresse, ce
| code se déclanche et c'est pas bon ...
.../...
Anor>

Dans ce cas, tu mets le code de 3stone dans l'événement
"sur avant mise à jour" du contrôle NomP au lieu de le mettre
sur avant mise à jour du formulaire.




Oui... mais, si l'utilisateur clique dans un autre des trois champs testé
et qu'il sauve... plus rien n'est testé.

Pour "choper" à coup sûr, il faut rester dans l'Avant mise à jour du formulaire.
Mais, on peut vérifier si un des trois champs concernés à été modifier...


If Me.NomP.Value <> Me.NomP.OldValue _
OR Me.Prenom.Value <> Me.Prenom.OldValue _
OR Me.DDN.Value <> Me.DDN.OldValue Then

If DCount(..., ..., ... ) Then

Dim Rep As Integer
Rep = MsgBox("Voulez vous sauver ?", vbYesNoCancel, "Doublons")

Select Case Rep
Case vbNo
Cancel = True
Case vbCancel
Me.Undo
End Select
End If
End If

Deux lignes et une possibilité d'abandon en plus, mais contrôle assuré !


--
A+
Pierre (3stone) Access MVP
--------------------------------------
Une pour tous, tous pour une ;-)
http://users.skynet.be/mpfa/
--------------------------------------

Avatar
Michel Walsh
Salut,


As-tu essayé en ajoutant les options forwardOnly et ReadOnly ? Ces "recordsets" sont plus légers à
contruire... (je n'optimise pas mes réponses, car les optimisations ont souvent le désavantage
d'allourdir la syntaxe), la différence de temps devrait être moindre.


Ce qu'il faut éviter, c'est le traitement des chaînes, de Format( ), etc. Une sous-requête permet
parfois d'économiser de ce coté là. Mais en effet, les fonctions Dxxx sont souvent plus rapides que
les sous-requêtes, toutes autres choses étant égales.



Vanderghast, Access MVP

"Anor" wrote in message news:3f1862c7$0$15338$
Bonjour Michel, Bonjour 3stone

Pour m'amuser, et parce que je pensais que les fonctions de domaine étaient beaucoup plus lentes
que la méthode des recordsets,
j'ai comparé les performances des 2 méthodes que vous proposez :

Lorsque la méthode :
n = DCount("*", "LaTable", "LeTexte='aerodrome'")
met 6 secondes pour faire X fois le calcul ci-dessus,

la méthode
n = CurrentDb.OpenRecordset("SELECT COUNT(*) FROM LaTable WHERE
LeTexte='aerodrome'").Fields(0).Value
met 8.4 secondes pour faire X fois le calcul.

Voilà, je suis un peu surpris par ce résultat inattendu mais je serais curieux de trouver une
3ème méthode plus rapide ;-)))

PS : je ne vous dirai pas que dans mes tests, X = 1000 car vous allez vous moquer si chez vous,
la même chose met 1 seconde :'-(

--
à+
Arnaud
-------------------------------------------
Conseils d'utilisation, sites recommandés :
http://users.skynet.be/mpfa/
petit à petit, www.anor.fr.st fait son nid
-------------------------------------------




Avatar
b
Bonsoir,

Pour mon problème, je m'en suis sorti en mettant du code APRES Insertion qui
signale si le bonhomme est déjà dans la table (avec if...>1),
et une autre code AVANT mise à jour du form (avec if...>0).
Quant au code, c'est à vous que je le dois, bien entendu !
Merci.

b(°!°)rbbu

"" a écrit dans le message de news:
bfbvqk$799$
3stone, Anor et autres, salut,
Ok je teste ça ce week-end et je vous dit tout.
Entre-temps j'ai pondu un truc sur Après Insertion.
Heum ! ça marche, très bien à la première validation du form.
... mais ... faut pas y revenir plus tard et modifier (de manière à
générer

un doublon), là je peux pas empêcher ! ! !
@+
b(°!°)rbbu

"3stone" a écrit dans le message de news:
#
Salut Anor et barbbu,



| Ok, ton code je l'avais déjà tester, mais ce qui me gène c'est le
| AvantMiseàJour !
| Si on revient sur une fiche pour modifier par exemple l'Adresse, ce
| code se déclanche et c'est pas bon ...
.../...
Anor>

Dans ce cas, tu mets le code de 3stone dans l'événement
"sur avant mise à jour" du contrôle NomP au lieu de le mettre
sur avant mise à jour du formulaire.




Oui... mais, si l'utilisateur clique dans un autre des trois champs
testé

et qu'il sauve... plus rien n'est testé.

Pour "choper" à coup sûr, il faut rester dans l'Avant mise à jour du
formulaire.

Mais, on peut vérifier si un des trois champs concernés à été
modifier...




If Me.NomP.Value <> Me.NomP.OldValue _
OR Me.Prenom.Value <> Me.Prenom.OldValue _
OR Me.DDN.Value <> Me.DDN.OldValue Then

If DCount(..., ..., ... ) Then

Dim Rep As Integer
Rep = MsgBox("Voulez vous sauver ?", vbYesNoCancel, "Doublons")

Select Case Rep
Case vbNo
Cancel = True
Case vbCancel
Me.Undo
End Select
End If
End If

Deux lignes et une possibilité d'abandon en plus, mais contrôle assuré !


--
A+
Pierre (3stone) Access MVP
--------------------------------------
Une pour tous, tous pour une ;-)
http://users.skynet.be/mpfa/
--------------------------------------










Avatar
Anor
Bonjour Michel,


| Salut,
| As-tu essayé en ajoutant les options forwardOnly et ReadOnly ? Ces
| "recordsets" sont plus légers à contruire...
.../...

En mettant ces paramètres directement dans ta chaîne SQL :
CurrentDb.OpenRecordset("SELECT COUNT(*) FROM LaTable WHERE LeTexte='blabla'",
dbOpenForwardOnly).Fields(0).Value
le gain de temps est insignifiant (1/10 de seconde pour 1000 boucles).

En utilisant, dans une petite fonction, une chaine SQL simplifiée
chSQL = "SELECT * FROM [LaTable] WHERE [LeTexte] = 'blabla'"
Set rst = bds.OpenRecordset(chSQL, dbReadOnly)
rst.MoveLast
test20 = rst.RecordCount

c'est finalement un peu plus long (1 seconde de plus pour 1000 boucles sur mon PC).

Comme quoi, dans l'aide en ligne ils disent que ces options permettent de gagner du temps =>
nada
Ils disent aussi :
' Open a forward-only-type Recordset object. Only the
' MoveNext and Move methods may be used to navigate
' through the recordset.
Eh bien l'option dbOpenForwardOnly ne permet pas l'utilisation de la méthode MoveLast !!

Mais bon on s'en fiche, le principal est qu'on apprenne de nouvelles choses (moi en tout cas),
en se créant des problèmes intéressants à résoudre, même si en réalité ce ne sont pas des
problèmes ;-)))


--
à+
Arnaud
-------------------------------------------
Conseils d'utilisation, sites recommandés :
http://users.skynet.be/mpfa/
petit à petit, www.anor.fr.st fait son nid
-------------------------------------------
1 2