Défi VBA, venez participer nombreux !

delphi_jb

XLDnaute Nouveau
Bonjour à toutes et à tous :cool:

Voila, comme le titre le suggère, j'ai un petit défi algorithmique qui pourrait
en même temps être utiles dans certain cas. N'hésitez pas à participer ! :eek:


Voici l’annoncé:

But:
Créer une FONCTION PERSONNALISE qui ferait une comparaison textuel entre
deux cellules, et retournerais "VRAI" ou "FAUX".

VRAI: considère que les cellules sont similaires l'une l'autre
FAUX: considère que les cellules ne sont pas similaires


Défis:
la société A encode ses clients comme ceci: Nom, Prénom
la société B encode ses clients comme ceci: Prénom1 Prénom2, Nom
la société C encode ses clients comme ceci: Nom Prénom1 Prénom2 Prénom3

la fonction devrai pouvoir distinguer qu'il s'agit du même client, malgré la
différence textuel et syntaxique du client !



Voila je pense qu'on peut aller très loin, comme par exemple palier aux fautes de frappe
sur un nom de client, ne pas tenir compte de la casse... C'est vous qui voyez !
(moi par exemple, je mettrais 1 ou 2 paramètres supplémentaires pour la fonction, pour
"featurer" la demande, comme par exemple "minimum X mots exactes pour considérer une similarité, etc.

A vos claviers !



:cool: Bonne chance :cool:
 
Dernière édition:

delphi_jb

XLDnaute Nouveau
Re : Défi VBA, venez participer nombreux !

Bonjour,
bah.. montre nous déjà le code que tu as commencé... et où tu bloques...
bon après midi
@+
Je créerais une fonction comme ceci:

comparer(A,B,C,D)

A= "texte" ou cellule (élément à comparer 1)
B= "texte" ou cellule (élément à comparer 2)
C= nombre entre 1 et 5 (nombre de mot minimum pour qu'une comparaison soit considéré comme VRAI)
D= nombre entre 1 et 2 (nombre de faute de frappe par mot, c'est une espèce de tolérance)

PS: Je ne bloque pas, j'ai pas encore commencé en fait, je suis à l'étude du système ^^


Question bête : je suppose que la société A encode ses clients comme ceci : Nom, Prénom1 et ne tient pas compte des autres prénoms (?).
justement, la fonction, pour être intéressent, devrais avoir une grande flexibilité quand au entrées...

exemple (dans la forme de mon étude perso)
A= Jérome Durant
B= Durant Mickael Jerome
C= 2
D= 0

fonctionne pas, car le "0" indique aucune tolérence sur un caractere.
Or, "Jérome" et "Jerome" ce n'est pas la même chose...

Par contre:
A= Jérome Durant
B= Durant Mickael Jerome
C= 2
D= 1

"1" indique qu'une variante ou différence sur "1" caractère est admis.
donc il retournera VRAI.

Voila ;-)
 

jp14

XLDnaute Barbatruc
Re : Défi VBA, venez participer nombreux !

Bonsoir
Salut Pierrot93


Ci dessous un essai pour répondre en partie à la question.

La fonction compare les deux chaines. Les chaines de caractères sont modifiées : suppression des caractères accentués et passage en majuscule.

Code:
Option Explicit
Option Base 0
Function CompareText(Texte1 As Range, Texte2 As Range) As String
Dim Nom1() As String, Nom2() As String, Nom1O() As String
Dim MotIdentique As String
Dim ValTrouv As Byte
Dim i As Byte, j As Byte, k As Byte
Dim Nom1T As String
Dim Nom2T As String
Dim TabCorres1 As Variant
Dim TabCorres2 As Variant



If Texte1.Value = "" Then
    CompareText = "Erreur"
    Exit Function
End If

If Texte2.Value = "" Then
    CompareText = "Erreur"
    Exit Function
End If
Nom1T = Texte1.Value
Nom2T = Texte2.Value
TabCorres1 = Array("é", "è", "ç", "à", "ù", "ï", "ä", "ü", "î", "ê")
TabCorres2 = Array("e", "e", "c", "a", "u", "i", "a", "u", "i", "e")
For i = 0 To UBound(TabCorres1)
    Nom1T = Replace(Nom1T, TabCorres1(i), TabCorres2(i))
Next i
For i = 0 To UBound(TabCorres1)
    Nom2T = Replace(Nom1T, TabCorres1(i), TabCorres2(i))
Next i

Nom1 = Split(UCase(Nom1T))
Nom2 = Split(UCase(Nom2T))
Nom1O = Split(Texte1.Value)
For i = LBound(Nom1) To UBound(Nom1)
    For j = LBound(Nom2) To UBound(Nom2)
        If Nom1(i) = Nom2(j) Then ' indépendance de la casse
             MotIdentique = MotIdentique & " " & Nom1O(i)
        End If
    Next j
Next i
CompareText = Trim(MotIdentique)

End Function

A tester et à modifier pour affiner le résultat.

JP
 
Dernière édition:

delphi_jb

XLDnaute Nouveau
Re : Défi VBA, venez participer nombreux !

je viens de tester ça fonctionne (ca me le rend en minuscule mais j'ai pas été voir dans le code)
Il renvoie une chaîne épuré de tout caractères spéciaux et/ou accentués.
Sans retourner la chaîne épuré dans le tableur, on peut s'en servir comme
base pour commencer à travailler dans le code.
Le fait d'éliminer automatiquement les accentuations comme critères de
comparaison est pour moi une bonne chose, car ça permettra à tout un chacun
d'utiliser la fonction simplement, juste... pour cette fonctionnalité.


Prémices et préparation:
* nettoyage du code et partir sur une base saine (merci jp14)
* dissocier tout les mots de la chaîne A dans un array, "argA()"
* dissocier tout les mots de la chaine B dans un array, "argB()"
* Énumérer, vérifier et placer les arguments en variable "argC" et "argD"


Voici un schémas logique. 4 syntaxes possibles:

==> COMPARE(A;B) <==
Simple comparatif de chaine. Il renvoie VRAI si la chaine A et la chaine B
sont identique sur tout les caractères numériques et alphabétique, en
acceptant une total souplesse sur les accentuations

==> COMPARE(A;B;C) <==
supplément "C": tient compte d'un nombre de mot requis minimum de 1 à 10:
1-10: signifie que 1-10 mot(s) doivent être identiques entre les chaines
pour retourner VRAI.

==> COMPARE(A;B;;D) <==
supplément "D": ne tient pas compte du nombre minimum de mot requis, mais
par contre, renvoie VRAI seulement si maximum 1-10 différences de caractère
sont constaté entre les deux chaines.

==> COMPARE(A;B;C;D) <==
supplément "C" et "D":
- tient compte du nombre de faute de frappe par mot
- tient compte du nombre de mot


un gros travail sera porté sur le fait de pouvoir assouvir tout les cas de figure, ainsi que
sur la sécurité et la vérification de ce qu'on met comme argument.
(pas question de mettre en argument "argC=toto", faut se prémunir.

On avance ^^
 
Dernière édition:

eriiic

XLDnaute Barbatruc
Re : Défi VBA, venez participer nombreux !

Bonsoir,

Pour compléter, après avoir supprimé accents et casse, tu pourrais utiliser la distance de Damerau-Levenshtein.
Mais bon, c'est bien parce que c'est dans le sujet mais ça risque d'être très chronophage...
Disons que c'est plus pour que tu connaisses cette possibilité.
Voir classeur exemple

eric
 

Pièces jointes

  • Distance de Damerau-Levenshtein.xls
    45 KB · Affichages: 184

delphi_jb

XLDnaute Nouveau
Re : Défi VBA, venez participer nombreux !

je viens de regarder le fichier, c'est pas mal du tout.

résumé de la méthode Damerau-Levenshtein:
c'est un algorithme qui vérifie la similarité entre deux chaines de caractère.
Elle définis en fait le nombre d'opération à faire sur la chaîne "A" afin d'avoir
une parfaite similarité sur la chaîne "B". Les opérations sont:

- ajout de caractère
- suppression de caractère
- remplacement de caractère
- transposition de caractère



Voici un exemple:
"voiture" et "voitures"
l'opération à faire ici pour que ces deux chaines soit similaire est un ajout de caractère:

(ajout du "s" en fin de chaîne A) = chaîne B
Nous avons donc 1 opération. les chaines était donc fortement similaires...

2 opérations = similarité moyenne
3 opérations = similarité faible
etc (à nous d'interpréter convenablement ces chiffres)

Le problème de cette méthode pour notre cas, c'est sont fonctionnement
sur 1 seul caractère / opération. Cela revietn a dire qu'elle ne tient pas
compte des subtilités du language humain, et donc de ses erreurs courants.

voici un exemple:
dupont <==> dupond
Ceci est une erreur courantes EN FRANCAIS car:
1- les deux orthographes existent
2- le "t" se subtitue facilement au "d" en langue francaise.

Mieux, regardez ce cas de figure:
Jérémie <==> Jérémy
la méthode Damerau-Levenshtein aurait retourné 2 opérations, alors qu'au fond de
nous même, nous savons tous que si on devait évaluler cette erreur, elle ne dépasserai
pas le niveau 1 car c'est une faute courantes dans notre langue.


Je pense donc qu'a terme, il faudra construire une méthode Damerau-Levenshtein normale, mais
amélioré par un "dictionnaire des fautes courantes" (qui dépend donc fortement de la langue
humaine utilisé).

Et ce dictionnaire, on peut le construire en créant une page Web qui demanderais au gens
de taper un texte et de vérifier les fautes courantes des utilisateurs. Voila ;-)
 

herve62

XLDnaute Barbatruc
Supporter XLD
Re : Défi VBA, venez participer nombreux !

Bonjour
Mutzik .. tu me retires aussi la même idée lorsque je lisais le début et je la voit ici à la fin !!!
J'ai eu un cas similaire ... faire un tri "Usine à gaz" .... alors qu'en changeant de critère c'était tout simple
Ayant été dans "Achats> fournisseurs" et "Ventes> clients" , j'ai toujours vu à 100% un Numéro client ou fournisseur
Car ce qui m'est arrivé de voir : la même entité , nom .etc mais adresse de livraison différente donc on distinguait par un code !!
 

david84

XLDnaute Barbatruc
Re : Défi VBA, venez participer nombreux !

Bonjour,

sujet peut-être intéressant mais qui sent l'usine à gaz...les règles de départ doivent être bien précisées, ce qui ne me semble pas être le cas pour l'instant : seule l'idée de base est posée (et encore !).

Peut-être que le fait d'utiliser du ReExp pourrait aider mais sans fichier exemple produit par toi (avec une demande comme la tienne cela me semble indispensable que ce soit toi qui le fournisse) avec :
- des exemples concrets et explicites au regard de ta problématique (pas des exemples basiques que tu complexifieras par la suite, mais le type de cas précis que tu devras traiter),
- le résultat attendu inscrit manuellement à côté avec les explications sur le pourquoi du comment
je ne me lance pas.
A+
 

eriiic

XLDnaute Barbatruc
Re : Défi VBA, venez participer nombreux !

Bonjour à tous,

Le problème de cette méthode pour notre cas, c'est sont fonctionnement
sur 1 seul caractère / opération. Cela revietn a dire qu'elle ne tient pas
compte des subtilités du language humain, et donc de ses erreurs courants.
80% des erreurs de frappe ont une distance de 1. Voir comment tu as écrit "revient" ;-)

Mieux, regardez ce cas de figure:
Jérémie <==> Jérémy
la méthode Damerau-Levenshtein aurait retourné 2 opérations
Tu peux simplifier l'écriture avant la comparaison :
Remplacer tous les y par des i, la distance tombe à 1.

De la même façon convertir les sons identiques à la même écriture :
au, eau -> o
un, ain, ein, aim, eim -> in
an -> en, amp -> emp, amb -> emb
sh, sch -> ch
etc

Le problème restera le temps de calcul. Si tes listes à comparer sont un peu longues ça va devenir terrible...
C'est sûr que si tu avais un n° de client unique sur tes listes le pb n'existerait pas.

eric
 

delphi_jb

XLDnaute Nouveau
Re : Défi VBA, venez participer nombreux !

Je comprends que la demande est floue. Je vais fournir un exemple plus concret:


But: définir les clients simulaires entre la base A et B

Base A
Client 277
Nom: jean baptiste durieu

Base B
Client CH44
Nom: durieux jean-baptiste

==> COMPARE(A;B) // les deux nom donc
==> retourne Vrai, il a détecté qu'il s'agissait de la meme chaîne.

Dans ce cas ci, vérifier la similarité des clients entre deux base de deux sociétés différentes peut s'avérer fastidieuse car la convention d'écriture des noms peut être différentes. Ici je parle de clients, mais ça peut être des produits, des références, des dates... Tout caractee alpha-numérique en fait. Voilà :)
 

Discussions similaires

Membres actuellement en ligne

Aucun membre en ligne actuellement.

Statistiques des forums

Discussions
312 508
Messages
2 089 143
Membres
104 050
dernier inscrit
Pepito93100