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

3 réponses

1 2
Avatar
Michel Walsh
Salut,


C'est quand même intéressant.


Personnellement, j'avais un test similaire (trouver le rang de chaque enregistrement) sur 1 million
d'enregistrements:
-----------------------
MythDxxxVBA
Ranking through SQL 22.941780046966849986003811657
Ranking through DCOUNT 1.2852934422409992775620148477
Ranking through VBA 0.7951645264511197788769860759
---------------------- les temps sont en secondes

Le code utilisé est le suivant (il faut une table Iotas, un champ, Iota, avec des valeurs
numériques). Puisque le temps est grand, de l'ordre de la seconde, je ne boucle pas, j'utilise les
compteurs de performance, car je suis certain, alors, de mesurer mon temps d'exécution, et non, en
plus, les processus plus prioritaires qui seraient survenus pendant que mon code s'exécutait.
Définitivement, les fonctions Dxxx ONT LEUR PLACE.


========== Option Compare Database
Option Explicit

Private Type LARGE_INTEGER
lowpart As Long
highpart As Long
End Type

Private Declare Function QueryPerformanceCounter Lib "kernel32" (lpPerformanceCount As
LARGE_INTEGER) As Long
Private Declare Function QueryPerformanceFrequency Lib "kernel32" (lpFrequency As LARGE_INTEGER) As
Long
----------
Public Function LargeToDec(Arg As LARGE_INTEGER) As Variant
LargeToDec = Arg.lowpart + 2 * CDec(Arg.highpart) * 2 ^ 31
End Function
----------
Public Function MyCount(Optional Arg As Variant) As Long
Static x As Long
If IsMissing(Arg) Then
x = 0
Else
MyCount = x
x = x + 1
End If
End Function
--------
Public Sub MythDxxxVBA()

Dim result As Long
Dim freq As LARGE_INTEGER
Dim starting As LARGE_INTEGER
Dim ending As LARGE_INTEGER
Dim dfreq As Variant
Dim rst As ADODB.Recordset

QueryPerformanceFrequency freq
dfreq = LargeToDec(freq)

Set rst = New ADODB.Recordset
QueryPerformanceCounter starting
rst.Open "SELECT Iota, (SELECT COUNT(*) FROM Iotas As b WHERE b.Iota>=b.Iota) As Rank FROM
Iotas As a", CurrentProject.Connection, adOpenKeyset, adLockOptimistic, adCmdText
rst.MoveLast
QueryPerformanceCounter ending
Debug.Print "Ranking through SQL", (LargeToDec(ending) - LargeToDec(starting)) / dfreq
rst.Close

QueryPerformanceCounter starting
rst.Open "SELECT Iota, DCOUNT('*', 'Iotas', 'Iota>=' & Iota) FROM Iotas ",
CurrentProject.Connection, adOpenKeyset, adLockOptimistic, adCmdText
rst.MoveLast
QueryPerformanceCounter ending
Debug.Print "Ranking through DCOUNT", (LargeToDec(ending) - LargeToDec(starting)) / dfreq
rst.Close

QueryPerformanceCounter starting
MyCount 'Initialize to 0
rst.Open "SELECT Iota, MyCount(Iota) As Rank FROM Iotas ", CurrentProject.Connection,
adOpenKeyset, adLockOptimistic, adCmdText
rst.MoveLast
QueryPerformanceCounter ending
Debug.Print "Ranking through VBA", (LargeToDec(ending) - LargeToDec(starting)) / dfreq
rst.Close

End Sub

=================
À noter que le processus de la saisie de temps est fort simple,

QueryPerformanceCounter starting


au début de ce que je désire chronométrer,

QueryPerformanceCounter ending

en fin de chrono,


(LargeToDec(ending) - LargeToDec(starting)) / dfreq


pour convertir, en secondes, l'intervalle de temps écoulé entre les deux saisies. En
principe, il faudrait enlever le temps d'exécution de QueryPerformanceCounter lui-même, mais c'est
d'environ de 10 à la moins 5 à 10 à la moins 7 seconde... (dépendant du MHz du CPU) ...
négligeable.





Vanderghast, Access MVP


"Anor" wrote in message news:3f1ba679$0$2197$
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
-------------------------------------------




Avatar
Anor
Bonjour Michel,

.../...
| j'utilise les compteurs de performance, car je suis certain,
| alors, de mesurer mon temps d'exécution, et non, en plus, les processus plus
| prioritaires qui seraient survenus pendant que mon code s'exécutait.
| Définitivement, les fonctions Dxxx ONT LEUR PLACE.

oui j'obtiens à peu près le même rapport de force !!
Ta méthode de chronométrage est intéressante....

| pour convertir, en secondes, l'intervalle de temps écoulé
| entre les deux saisies. En principe, il faudrait enlever le temps
| d'exécution de QueryPerformanceCounter lui-même, mais c'est d'environ
| de 10 à la moins 5 à 10 à la moins 7 seconde... (dépendant du MHz
| du CPU) ... négligeable.
|

il faut toujours laisser la porte ouverte aux maniaques :

Au Temps global mesuré, incluant donc 1 temps d'exécution,
retirer 2 fois le temps d'exécution qu'on mesurera à vide ;-))

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


Précision impostante, je crois que je n'ai pas été clair, mais pas du tout.

Un "compteur de précision" est un compteur comme un autre, en ce sens qu'il ramasse
également le temps passé sur les processus plus hautement prioritaire qui auraient pu survenir,
mais comme, en général, il s'effectue sur un temps court, disons de l'ordre de la milliseconde, il
est moins sujet de ramasser un "accident" de parcours qu'un processus de chronométrage qui serait
basé sur une boucle pour une durée plus longue, disons de la seconde. En effet, un processus qui
dure longtemps a plus de chance de se tasser pour laisser la place à un processus plus important,
qu'un processus de courte durée. C'est dans cette optique que je mentionnais que les compteurs de
précision sont moins sujet, moins succeptible de chronométrer autre chose que mon processus, mais
ce n'est pas une qualité qui leur est intrinsèque. Mon commentaire pouvait laisser croire que les
compteurs de précision ne comptait que ce qui se passe sur le filet d'exécution sur lequel ils sont
demandés. Ce n'est pas le cas.

Vanderghast, Access MVP
1 2