Existe-t-il un moyen efficace d'identifier la dernière correspondance caractère/chaîne d'une chaîne à l'aide des fonctions de base? C'est à dire. pas le dernier caractère/chaîne de la chaîne, mais la position de la dernière occurrence d'un caractère/chaîne in une chaîne. Search
et find
fonctionnent tous les deux de gauche à droite, donc je ne vois pas comment appliquer sans un long algorithme récursif. Et cette solution semble maintenant obsolète.
Je pense que je comprends ce que vous voulez dire. Supposons par exemple que vous souhaitiez le\droit dans la chaîne suivante (qui est stockée dans la cellule A1):
Lecteur:\Dossier\Sous-dossier\Nom du fichier.ext
Pour obtenir la position du dernier \, vous utiliseriez cette formule:
=FIND("@",SUBSTITUTE(A1,"\","@",(LEN(A1)-LEN(SUBSTITUTE(A1,"\","")))/LEN("\")))
Cela nous dit que le plus à droite est au caractère 24. Il le fait en recherchant "@" et en remplaçant le dernier "\" par un "@". Il détermine le dernier en utilisant
(len(string)-len(substitute(string, substring, "")))\len(substring)
Dans ce scénario, la sous-chaîne est simplement "\" et a une longueur de 1; vous pouvez donc laisser la division à la fin et simplement utiliser:
=FIND("@",SUBSTITUTE(A1,"\","@",LEN(A1)-LEN(SUBSTITUTE(A1,"\",""))))
Maintenant, nous pouvons utiliser cela pour obtenir le chemin du dossier:
=LEFT(A1,FIND("@",SUBSTITUTE(A1,"\","@",LEN(A1)-LEN(SUBSTITUTE(A1,"\","")))))
Voici le chemin du dossier sans le\final
=LEFT(A1,FIND("@",SUBSTITUTE(A1,"\","@",LEN(A1)-LEN(SUBSTITUTE(A1,"\",""))))-1)
Et pour obtenir uniquement le nom de fichier:
=MID(A1,FIND("@",SUBSTITUTE(A1,"\","@",LEN(A1)-LEN(SUBSTITUTE(A1,"\",""))))+1,LEN(A1))
Cependant, voici une version alternative pour tout placer à droite de la dernière instance d'un caractère spécifique. Donc, en utilisant notre même exemple, ceci renverrait également le nom du fichier:
=TRIM(RIGHT(SUBSTITUTE(A1,"\",REPT(" ",LEN(A1))),LEN(A1)))
Pourquoi ne pas créer une fonction personnalisée et l'utiliser dans votre formule? VBA a une fonction intégrée, InStrRev
, qui fait exactement ce que vous recherchez.
Mettez ceci dans un nouveau module:
Function RSearch(str As String, find As String)
RSearch = InStrRev(str, find)
End Function
Et votre fonction ressemblera à ceci (en supposant que la chaîne d'origine soit en B1):
=LEFT(B1,RSearch(B1,"\"))
tigeravatar et Jean-François Corbett ont suggéré d'utiliser cette formule pour générer la chaîne droite de la dernière occurrence du caractère "\"
=TRIM(RIGHT(SUBSTITUTE(A1,"\",REPT(" ",LEN(A1))),LEN(A1)))
Si le caractère utilisé comme séparateur est un espace "", la formule doit être remplacée par:
=SUBSTITUTE(RIGHT(SUBSTITUTE(A1," ",REPT("{",LEN(A1))),LEN(A1))),"{","")
Inutile de mentionner, le caractère "{" peut être remplacé par n'importe quel caractère qui ne serait pas "normalement" dans le texte à traiter.
Vous pouvez utiliser cette fonction que j'ai créée pour trouver la dernière instance d'une chaîne dans une chaîne.
Bien sûr, la formule Excel acceptée fonctionne, mais il est beaucoup trop difficile à lire et à utiliser. À un moment donné, vous devez vous séparer en petits morceaux pour en assurer la maintenance. Ma fonction ci-dessous est lisible, mais cela n'a aucune importance car vous l'appelez dans une formule utilisant des paramètres nommés. Cela rend l'utilisation simple.
Public Function FindLastCharOccurence(fromText As String, searchChar As String) As Integer
Dim lastOccur As Integer
lastOccur = -1
Dim i As Integer
i = 0
For i = Len(fromText) To 1 Step -1
If Mid(fromText, i, 1) = searchChar Then
lastOccur = i
Exit For
End If
Next i
FindLastCharOccurence = lastOccur
End Function
Je l'utilise comme ça:
=RIGHT(A2, LEN(A2) - FindLastCharOccurence(A2, "\"))
Je viens juste de proposer cette solution, aucun VBA n’est nécessaire;
Trouvez la dernière occurrence de "_" dans mon exemple;
=IFERROR(FIND(CHAR(1);SUBSTITUTE(A1;"_";CHAR(1);LEN(A1)-LEN(SUBSTITUTE(A1;"_";"")));0)
Expliqué à l'envers;
SUBSTITUTE(A1;"_";"") => replace "_" by spaces
LEN( *above* ) => count the chars
LEN(A1)- *above* => indicates amount of chars replaced (= occurrences of "_")
SUBSTITUTE(A1;"_";CHAR(1); *above* ) => replace the Nth occurence of "_" by CHAR(1) (Nth = amount of chars replaced = the last one)
FIND(CHAR(1); *above* ) => Find the CHAR(1), being the last (replaced) occurance of "_" in our case
IFERROR( *above* ;"0") => in case no chars were found, return "0"
J'espère que c'était utile.
Considérant une partie d'un commentaire fait par @SSilkmon objectif final a été de tout mettre à droite de cette dernière occurrence une autre approche avec une formule très simple consiste à copier une colonne (disons A
) des chaînes et sur la copie (par exemple, ColonneB) appliquent Rechercher et remplacer. Par exemple, prenons l'exemple suivant: Drive:\Folder\SubFolder\Filename.ext
Ceci retourne ce qui reste (ici Filename.ext
) après la dernière instance du caractère choisi (ici \
) qui est parfois l'objectif de toute façon et facilite la recherche de la position du dernier caractère avec une formule courte telle que:
=FIND(B1,A1)-1
Je suis un peu en retard à la fête, mais peut-être que cela pourrait aider. Le lien dans la question avait une formule similaire, mais le mien utilise l'instruction IF () pour supprimer les erreurs.
Si vous n'avez pas peur de Ctrl + Maj + Entrée, vous pouvez très bien utiliser une formule matricielle.
Chaîne (dans la cellule A1): "One.two.three.four"
Formule:
{=MAX(IF(MID(A1,ROW($1:$99),1)=".",ROW($1:$99)))} use Ctrl+Shift+Enter
Résultat: 14
Premier,
ROW($1:$99)
renvoie un tableau d'entiers allant de 1 à 99: {1,2,3,4,...,98,99}
.
Suivant,
MID(A1,ROW($1:$99),1)
renvoie un tableau de chaînes d'une longueur trouvée dans la chaîne cible, puis renvoie des chaînes vides une fois que la longueur de la chaîne cible est atteinte: {"o","n","e",".",..."u","r","","",""...}
Suivant,
IF(MID(I16,ROW($1:$99),1)=".",ROW($1:$99))
compare chaque élément du tableau à la chaîne "." et retourne soit l'index du caractère dans la chaîne, soit FALSE: {FALSE,FALSE,FALSE,4,FALSE,FALSE,FALSE,8,FALSE,FALSE,FALSE,FALSE,FALSE,14,FALSE,FALSE.....}
Dernier,
=MAX(IF(MID(I16,ROW($1:$99),1)=".",ROW($1:$99)))
renvoie la valeur maximale du tableau: 14
Les avantages de cette formule sont qu’elle est courte, relativement facile à comprendre et ne nécessite aucun caractère unique.
Les inconvénients sont l'utilisation requise de Ctrl + Maj + Entrée et la limitation de la longueur de la chaîne. Cela peut être contourné avec une variante illustrée ci-dessous, mais cette variante utilise la fonction OFFSET () qui est une fonction volatile (lecture: lente).
Pas sûr de la vitesse de cette formule par rapport aux autres.
Variations
=MAX((MID(A1,ROW(OFFSET($A$1,,,LEN(A1))),1)=".")*ROW(OFFSET($A$1,,,LEN(A1)))) works the same way, but you don't have to worry about the length of the string
=SMALL(IF(MID(A1,ROW($1:$99),1)=".",ROW($1:$99)),2) determines the 2nd occurrence of the match
=LARGE(IF(MID(A1,ROW($1:$99),1)=".",ROW($1:$99)),2) determines the 2nd-to-last occurrence of the match
=MAX(IF(MID(I16,ROW($1:$99),2)=".t",ROW($1:$99))) matches a 2-character string **Make sure you change the last argument of the MID() function to the number of characters in the string you wish to match!
Très tard pour le parti, mais une solution simple utilise VBA pour créer une fonction personnalisée.
Ajouter la fonction à VBA dans le classeur, la feuille de calcul ou un module VBA
Function LastSegment(S, C)
LastSegment = Right(S, Len(S) - InStrRev(S, C))
End Function
Puis la formule de la cellule
=lastsegment(B1,"/")
dans une cellule et la chaîne à rechercher dans la cellule B1 peuplera la cellule avec le texte suivi du dernier "/" de la cellule B1 . Aucune limite de longueur, aucune formule obscure . Seul inconvénient, je pense, est le besoin d'un classeur prenant en charge les macros.
Toute fonction VBA utilisateur peut être appelée de cette manière pour renvoyer une valeur à une formule de cellule, y compris en tant que paramètre d'une fonction Excel intégrée.
Si vous comptez utiliser beaucoup la fonction, vous devez vérifier si le caractère n'est pas dans la chaîne, alors la chaîne est vide, etc.
Cellule A1 = find/the/position/of/the last slash
une méthode simple consiste à inverser le texte, puis à trouver la première barre oblique normalement. Vous pouvez maintenant obtenir la longueur du texte intégral moins ce nombre.
Ainsi:
=LEN(A1)-FIND("/",REVERSETEXT(A1),1)+1
Ceci retourne 21, la position du dernier /
Dans les versions plus récentes d'Excel (2013 et ultérieur), le remplissage en Flash peut constituer une solution simple et rapide, voir: Utilisation de Flash Fill dans Excel .
Un moyen simple de faire cela dans VBA est:
YourText = "c:\Excel\text.txt"
xString = Mid(YourText, 2 + Len(YourText) - InStr(StrReverse(YourText), "\" ))