Extraire une valeur sur la base d'une table de référence
Bonjour.
Je souhaiterais extraire des prénom d'une chaine de caractère, en m'appuyant sur une base de prénom référent.
En gros, j'ai un listing de prénom :
- Anne
- Ariane
- Amélie
- Paul
- Pauline
- ...
Une suite de chaines texte :
- Mme Ariane Tartampion
- Mr. Paul Dupont
- Edouard Durand
- Anne.Durien@xxx.com
- ...
=> Je voudrais avoir une colonne où je retrouve, à côté du champ texte complet, le prénom extrait.
Difficultés complémentaires :
- Certains prénoms (type "Paul" et "Pauline" commencent pareil, donc il faut réussir à vérifier que c'est le bon prénom complet
- Parfois il y a un espace entre les mots, parfois nom (cf l'exemple avec l'email)
- Parfois il y a des "Pauline Martin" qui ont donc deux "prénoms" identifiables. On partirait du principe que ce serait le premier prénom le bon
Y'a-t-il une solution pas trop complexe pour me dépatouiller de ce sujet ?
Je ne sais pas trop par où commencer à chercher !
Merci
Salut,
Oui, en VBA c'est possible. Il faut séparer le nom et prénom et inscrire le prénom dans la cellule correspondante.
Peut-tu mettre un fichier qu'on puisse voir ? (Enlève les informations confidentiel).
Cdlt,
Merci.
Toutes les infos sont confidentielles, donc j'ai fait un faux fichier d'exemple
J'ai mis le début de la liste de prénom : je la terminerai si je trouve une solution technique à mon problème.
j'ai mis des exemples de chaines de valeurs que je pourrais être amené à traiter, et le prénom qui doit en être extrait à droite.
Re,
Je pense que tu peux abandonner, désolé mais les données de base n'ont aucune cohérences. Il est impossible, de mon point de vue et sauf erreur de ma part, d'extraire un prénom à partir de tel données brutes.
Si cela se présentait seulement sous la forme de "NOM PRENOM" ou "NOM PRENOM PRENOM" sa serait possible. Cependant, dans ton exemple les valeurs de bases sont trop complexes (<adriano.tarti@gmail.com>; ?windows-1252?Q?Aristide?;).
Un ordinateur ne peut pas reconnaître un prénom juste parce que s'en est un, pour lui c'juste une chaîne de caractères ^^.
Cdlt,
Bonjour,
une proposition qui devrait convenir pour 99,9% des cas
Sub aargh()
With Sheets("baseprenoms")
n = .Cells(Rows.Count, 1).End(xlUp).Row
.Range("A1:A" & n).Copy .Range("B1")
.Range("C1").Formula = "=upper(B1)"
.Range("C1").Copy .Range("C2:C" & n)
.Range("D1").Formula = "=len(C1)"
.Range("D1").Copy .Range("D2:D" & n)
.Range("B1:D" & n).Sort key1:=.Range("D1"), order1:=xlDescending, Header:=xlNo
Set ws = Sheets("data")
k = 2
While ws.Cells(k, 1) <> ""
For i = 1 To n
If InStr(UCase(ws.Cells(k, 1)), .Cells(i, 3)) <> 0 Then ws.Cells(k, 2) = .Cells(i, 2): Exit For
Next i
k = k + 1
Wend
.Columns("B:D").Delete
End With
End Sub
Bonjour,
une version un peu plus élaborée
Sub aargh()
With Sheets("baseprenoms")
n = .Cells(Rows.Count, 1).End(xlUp).Row
.Range("A1:A" & n).Copy .Range("B1")
.Range("C1").Formula = "=upper(B1)"
.Range("C1").Copy .Range("C2:C" & n)
.Range("D1").Formula = "=len(C1)"
.Range("D1").Copy .Range("D2:D" & n)
.Range("B1:D" & n).Sort key1:=.Range("D1"), order1:=xlDescending, Header:=xlNo
Set ws = Sheets("data")
k = 2
While ws.Cells(k, 1) <> ""
tr = "<>.,?@"
For i = 1 To Len(tr)
a = UCase(Replace(ws.Cells(k, 1), Mid(tr, i, 1), " "))
Next i
b = Split(a, " ")
fin = False
For j = LBound(b) To UBound(b)
lb = Len(b(j))
Set re = .Range("D1:D" & n).Find(lb, lookat:=xlWhole)
If Not re Is Nothing Then
For i = re.Row To n
If .Cells(i, 4) <> lb Then Exit For
If InStr(b(j), .Cells(i, 3)) <> 0 Then ws.Cells(k, 2) = .Cells(i, 2): fin = True: Exit For
Next i
End If
If fin Then Exit For
Next j
If Not fin Then
For i = 1 To n
If InStr(a, .Cells(i, 3)) <> 0 Then ws.Cells(k, 2) = .Cells(i, 2): fin = True: Exit For
Next i
End If
k = k + 1
Wend
.Columns("B:D").Delete
End With
End Sub
h2so4 a écrit :Bonjour,
une version un peu plus élaborée
Sub aargh() With Sheets("baseprenoms") n = .Cells(Rows.Count, 1).End(xlUp).Row .Range("A1:A" & n).Copy .Range("B1") .Range("C1").Formula = "=upper(B1)" .Range("C1").Copy .Range("C2:C" & n) .Range("D1").Formula = "=len(C1)" .Range("D1").Copy .Range("D2:D" & n) .Range("B1:D" & n).Sort key1:=.Range("D1"), order1:=xlDescending, Header:=xlNo Set ws = Sheets("data") k = 2 While ws.Cells(k, 1) <> "" tr = "<>.,?@" For i = 1 To Len(tr) a = UCase(Replace(ws.Cells(k, 1), Mid(tr, i, 1), " ")) Next i b = Split(a, " ") fin = False For j = LBound(b) To UBound(b) lb = Len(b(j)) Set re = .Range("D1:D" & n).Find(lb, lookat:=xlWhole) If Not re Is Nothing Then For i = re.Row To n If .Cells(i, 4) <> lb Then Exit For If InStr(b(j), .Cells(i, 3)) <> 0 Then ws.Cells(k, 2) = .Cells(i, 2): fin = True: Exit For Next i End If If fin Then Exit For Next j If Not fin Then For i = 1 To n If InStr(a, .Cells(i, 3)) <> 0 Then ws.Cells(k, 2) = .Cells(i, 2): fin = True: Exit For Next i End If k = k + 1 Wend .Columns("B:D").Delete End With End Sub
Salut, comment distingue tu le nom ou le prénom ? Merci.
Cdlt,
Merci beaucoup, cela semble marcher au poil.
J'avais presque l'impression d'avoir compris sur ta première version (il n'y avait que la ligne la plus importante que je ne comprenais pas), mais sur la version plus aboutie je suis complètement paumé
Bon, en tout cas cela semble marcher.
je vais faire le test avec plus de données pour vérifier.
Merci beaucoup !
VH_AE a écrit :Salut, comment distingue tu le nom ou le prénom ? Merci.
Cdlt,
j'ai programmé suivant l'hypothèse que le premier prénom trouvé est le prénom. (sauf pour le cas où il y a 2 prénoms accolés, exemple francoismartin@gmail.com. Dans ce cas c'est le prénom le plus long qui sera sélectionné)
h2so4 a écrit :Bonjour,
une version un peu plus élaborée
Question complémentaire : comment faire pour que les accents ou caractères spéciaux ("ç", "tirets") ne posent pas de problème ?
Actuellement, si il y a un accent d'un côté (base de prénom ou data) mais pas de l'autre, ils sont considérés comme différents.
bonjour,
une nouvelle proposition pour la gestion des accents et cédille + correction bug.
Sub aargh()
With Sheets("baseprenoms")
' à compléter éventuellement
' --------------------------
s1 = UCase("éèçàîï") ' liste des caractères à remplacer par une des lettres de l'alphabet
s2 = "EECAII" ' liste des caractères de remplacement correspondant à s1
s3 = "-´`'" ' liste des caractères à supprimer
tr = "<>.,?@" 'liste des caractères à considérer comme séparateur
' --------------------------
n = .Cells(Rows.Count, 1).End(xlUp).Row
.Range("A1:A" & n).Copy .Range("B1")
.Range("C1").Formula = "=upper(B1)"
.Range("C1").Copy .Range("C2:C" & n)
.Range("C1:C" & n).Copy
.Range("C1").PasteSpecial xlValues
For i = 1 To Len(s1)
.Range("C1:C" & n).Replace Mid(s1, i, 1), Mid(s2, i, 1)
Next i
For i = 1 To Len(s1)
.Range("C1:C" & n).Replace Mid(s3, i, 1), ""
Next i
.Range("D1").Formula = "=len(C1)"
.Range("D1").Copy .Range("D2:D" & n)
.Range("B1:D" & n).Sort key1:=.Range("D1"), order1:=xlDescending, Header:=xlNo
Set ws = Sheets("data")
k = 2
While ws.Cells(k, 1) <> ""
a = UCase(ws.Cells(k, 1))
For i = 1 To Len(tr)
a = Replace(a, Mid(tr, i, 1), " ")
Next i
For i = 1 To Len(s1)
a = Replace(a, Mid(s1, i, 1), Mid(s2, i, 1))
Next i
For i = 1 To Len(s3)
a = Replace(a, Mid(s3, i, 1), "")
Next i
b = Split(a, " ")
fin = False
For j = LBound(b) To UBound(b)
lb = Len(b(j))
Set re = .Range("D1:D" & n).Find(lb, lookat:=xlWhole)
If Not re Is Nothing Then
For i = re.Row To n
If .Cells(i, 4) <> lb Then Exit For
If InStr(b(j), .Cells(i, 3)) <> 0 Then ws.Cells(k, 2) = .Cells(i, 2): fin = True: Exit For
Next i
End If
If fin Then Exit For
Next j
If Not fin Then
For i = 1 To n
If InStr(a, .Cells(i, 3)) <> 0 Then ws.Cells(k, 2) = .Cells(i, 2): fin = True: Exit For
Next i
End If
k = k + 1
Wend
.Columns("B:D").Delete
End With
End Sub
Merci beaucoup !
J'ai passé le "-" dans les symboles à considérer comme séparateur.
De cette manière, "Jean-François" sera bien reconnu comme un prénom unique (sinon il ne conserve que François).
bonjour,
J'ai passé le "-" dans les symboles à considérer comme séparateur.
De cette manière, "Jean-François" sera bien reconnu comme un prénom unique (sinon il ne conserve que François).
je dois avouer que ce résultat me surprend et que je n'ai pas pu le reproduire.
une nouvelle version
Sub aargh()
With Sheets("baseprenoms")
' à compléter éventuellement
'
s1 = UCase("éèçàîï") ' liste des caractères à remplacer par une des lettres de l'alphabet
s2 = "EECAII" ' liste des caractères de remplacement correspondant à s1
s3 = "-´`'" ' liste des caractères à supprimer
tr = "<>.,?@" 'liste des caractères à considérer comme séparateur
'
n = .Cells(Rows.Count, 1).End(xlUp).Row
.Range("A1:A" & n).Copy .Range("B1")
.Range("C1").Formula = "=upper(B1)"
.Range("C1").Copy .Range("C2:C" & n)
.Range("C1:C" & n).Copy
.Range("C1").PasteSpecial xlValues
For j = 1 To n
a = .Range("C" & j)
For i = 1 To Len(s1)
a = Replace(a, Mid(s1, i, 1), Mid(s2, i, 1))
Next i
For i = 1 To Len(s3)
a = Replace(a, Mid(s3, i, 1), "")
Next i
.Range("C" & j) = a
Next j
.Range("D1").Formula = "=len(C1)"
.Range("D1").Copy .Range("D2:D" & n)
.Range("B1:D" & n).Sort key1:=.Range("D1"), order1:=xlDescending, Header:=xlNo
Set ws = Sheets("data")
k = 2
While ws.Cells(k, 1) <> ""
a = UCase(ws.Cells(k, 1))
For i = 1 To Len(tr)
a = Replace(a, Mid(tr, i, 1), " ")
Next i
For i = 1 To Len(s1)
a = Replace(a, Mid(s1, i, 1), Mid(s2, i, 1))
Next i
For i = 1 To Len(s3)
a = Replace(a, Mid(s3, i, 1), "")
Next i
b = Split(a, " ")
fin = False
For j = LBound(b) To UBound(b)
lb = Len(b(j))
Set re = .Range("D1:D" & n).Find(lb, lookat:=xlWhole)
If Not re Is Nothing Then
For i = re.Row To n
If .Cells(i, 4) <> lb Then Exit For
If InStr(b(j), .Cells(i, 3)) <> 0 Then ws.Cells(k, 2) = .Cells(i, 2): fin = True: Exit For
Next i
End If
If fin Then Exit For
Next j
If Not fin Then
For i = 1 To n
If InStr(a, .Cells(i, 3)) <> 0 Then ws.Cells(k, 2) = .Cells(i, 2): fin = True: Exit For
Next i
End If
k = k + 1
Wend
.Columns("B:D").Delete
End With
End Sub
En fait, j'ai mis "jean francois" dans le listing des prénoms de référence.
Et du coup, le "Jean-François" présent dans la données à extraire est bien reconnu (en tant que "jean françois" certes, cad que je perds le "-" au passage, mais je suis sûr de mon identification).
Peux-tu me dire quelles sont les modifications apportées par ton nouveau code ?
Je suis un peu perdu et ne sais pas ce qu'il faut que je teste
bonjour,
les modifications concernent le remplacement des caractères qui semblait ne pas se faire correctement (notamment le - et le ç).
tu devrais pouvoir mettre Jean-François dans ta base des prénoms. cela devrait fonctionner maintenant.