Voici une puissante fonction VBA pour la manipulation de texte. Elle extrait une chaîne de caractères délimitée par deux autres chaînes.
la fonction que je vous ai préparée retournera le texte qui se trouve entre les deux textes adjacents que vous aurez spécifiés. Ainsi, si vous voulez extraire la chaîne "cde" de la chaîne originale "abcdef" – il suffit d'utiliser la fonction qui suit avec pour limites "b" et "f".
NB: Pour la chaîne originale "abbcdef", on obtiendra le même résultat ("cde") avec des limites "ab" et "f".
Cette fonction peut être très pratique lors d'un scraping de contenu d'un site internet, pour analyser des fichiers de log ou encore pour "nettoyer" des données.
Je vous avoue que, personnellement, je me sers de cette fonction quasi quotidiennement!
Détails de la fonction pour trouver un texte délimité en VBA
- Il est possible d'utiliser une seule limite (voir le tableau plus bas) ou même aucune – les deux limites sont des paramètres optionnels.
- La fonction retourne une erreur dans le cas où une des limites n'est pas trouvé où dans les cas illogiques où la limite de début se trouve après la limite de fin.
- La fonction est évidemment utilisable avec un texte qui contient des espaces (exemple: "Code produit: P001")
Utilisation dans une Feuille Excel en tant que UDF
Vous pouvez utiliser cette fonction à l'intérieur de votre code VBA mais également en tant que UDF (Fonction définie par l'utilisateur) dans vos Feuilles. Vous pourrez ainsi utiliser cette fonction avec le contenu des cellules.
Dans votre Feuille, l'utilisation ressemblera à ceci:
Le texte d'origine est contenu dans une cellule, les "délimiteurs" sont fixes dans la fonction
Le texte d'origine ainsi que les deux délimiteurs se trouvent dans les cellules
Comme vous voyez, rien de bien compliqué!
Le code VBA de la fonction qui extrait un texte délimité
Et voici donc le code VBA dont vous aurez besoin…
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
Public Function ExtraireChaineDelimitee(ChaineSource As String, Optional LimiteAvant As String = "", Optional LimiteApres As String = "") 'par: Excel-Malin.com ( https://excel-malin.com ) On Error GoTo FunctionErreur If InStr(1, ChaineSource, LimiteAvant) = 0 Then ExtraireChaineDelimitee = CVErr(xlErrNA) Exit Function Else ExtraitPositionDebut = InStr(1, ChaineSource, LimiteAvant) + Len(LimiteAvant) End If If LimiteApres = "" Then ExtraitPositionFin = Len(ChaineSource) Else ExtraitPositionFin = InStr(1, ChaineSource, LimiteApres) - 1 End If ExtraireChaineDelimitee = Mid(ChaineSource, ExtraitPositionDebut, ExtraitPositionFin - ExtraitPositionDebut + 1) Exit Function FunctionErreur: ExtraireChaineDelimitee = CVErr(xlErrNA) 'ExtraireChaineDelimitee = "" End Function |
Selon vos besoins, vous pouvez modifier le comportement en cas d'erreur: la fonction retourne l'erreur "#N/A
" (Error 2042) mais par une simple modification, elle peut retourner une chaîne vide (""). Il suffit d'échanger le commentaire dans les lignes suivantes:
1 2 3 4 5 |
'... FunctionErreur: 'ExtraireChaineDelimitee = CVErr(xlErrNA) ExtraireChaineDelimitee = "" End Function |
Exemple d’utilisation de la fonction ExtraireChaineDelimitee()
Un exemple d'utilisation en pratique de la fonction ExtraireChaineDelimitee()
pour que vous puissiez vous faire une idée.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
Sub ExempleExtractionDeChaine() 'par: Excel-Malin.com ( https://excel-malin.com ) On Error GoTo ExempleErreur Dim ChaineOriginale1 As String Dim ChaineOriginale2 As String Dim LimiteGauche As String Dim LimiteDroite As String 'extraire l'ID de l'utilisateur des opérations suivantes ChaineOriginale1 = "Article XYZ crée par UserID-256698-FR-1" ChaineOriginale2 = "Article ABC vendu par UserID-658758996-FR-3" LimiteGauche = "UserID-" LimiteDroite = "-FR" User1 = ExtraireChaineDelimitee(ChaineOriginale1, LimiteGauche, LimiteDroite) User2 = ExtraireChaineDelimitee(ChaineOriginale2, LimiteGauche, LimiteDroite) MsgBox "Utilisateur 1 = " & User1 & "; Utilisateur 2 = " & User2 Exit Sub ExempleErreur: MsgBox "Une erreur est survenue..." End Sub |
Exemples de résultats (chaînes de caractères) obtenus grâce à cette fonction VBA
Si nous prenons comme base la chaîne "abcdef", voici ce que l'on obtiendra avec les différentes possibilités:
- ExtraireChaineDelimitee("abcdef", "ab", "ef") ==> "cd"
- ExtraireChaineDelimitee("abcdef", "", "ef") ==> "abcd"
- ExtraireChaineDelimitee("abcdef", , "ef") ==> "abcd"
- ExtraireChaineDelimitee("abcdef", "abc", "") ==> "def"
- ExtraireChaineDelimitee("abcdef", "ab") ==> "cdef"
- ExtraireChaineDelimitee("abcdef") ==> "abcdef"
- ExtraireChaineDelimitee("abcdef", "bc", "xyz") ==> erreur #N/A
- ExtraireChaineDelimitee("abcdef", "ef", "ab") ==> erreur #N/A
- ExtraireChaineDelimitee("abcdef", "cd", "cd") ==> erreur #N/A
Pour conclure…
Cette fonction, en plus d'être utile, démontre les possibilités des UDF (Fonctions définies par l'utilisateur). Si vous trouvez un cas intéressant de l'utilisation pratique de cette fonction, n'hésitez pas à en faire part aux autres dans les commentaires…
Pour aller plus loin en VBA
Comme vous avez pu constater, le code VBA sur cette page utilise largement la fonction InStr(). En savoir plus sur la fonction VBA InStr.
D'autres liens utiles:
- Liste de toutes les fonctions disponibles en VBA
- Référentiel VBA – e-book par Excel-Malin.com contenant toutes les fonctions, instructions, événements et opérateurs disponibles en VBA
- Extraire le code HTML d'une page web – à combiner avec le code VBA qui se trouve plus haut pour construire un puissant outil d'extraction d'information disponibles sur internet…
- Autres codes sources VBA pratiques et prêts à l'emploi
- Comment utiliser la fonction Excel RECHERCHEV directement en VBA (tutoriel)
- Envoyer un email avec VBA
- Calculer la SOMME en VBA
12 commentaires sur “VBA: Extraire une chaîne de caractères délimitée”
Merci. ça marche tres bien!
Bonjour,
A partir d'une liste d'urls pointant sur des fiches produits en colonne A, je souhaiterais retrouver l'état du stock en colonne B. Près de 6000 références.
Le scrapping prend près de 3 heures, donc beaucoup trop long.
Voici le code où se trouve l'information, soit "EN STOCK", soit "RUPTURE DE STOCK" ou "DISPONIBLE LE….."
<span class="ok">EN STOCK </span>
A vos bons coeurs 😉
Bonjour Calimero,
et c'est quoi votre question au juste?
Si vous avez une URL différente pour chaque produit, cela veut dire que le scrapper doit visiter 6000 pages web – 3h ne me paraissent pas excessives pour cela. Bien sûr, cela dépend de la méthode utilisée. Le code ici: Obtenir code source HTML d’une page web est très rapide mais tout dépend du serveur auquel vous vous connectez et de la vitesse de connextion.
Vous n'avez pas un moyen de trouver cette info sur une liste des produits (par exemple l'url de la catégorie avec la liste des produits de cette catégorie?) d'où vous pourriez extraire cette info? Si vous avez 60 URLs avec 100 produits chacun, cela devrait aller nettement plus vite (avec une boucle à l'intérieur du code d'une URL)…
Et attention, avec 6000 appels en 3 heures, vous risquez de vite vous faire repérer par le propriétaire du serveur…
Et pour le code dans votre exemple, j'ai l'impression qu'il n'est pas unique. Je suppose que la 'class="ok"' colorie le OK en vert. Cela veut dire que par exemple RUPTURE DE STOCK ne sera pas balisé par le même code.
Il vous faut trouver la partie du code HTML qui sera la même pour tous les cas. vous ferez le nettoyage après…
J'ai déjà fait cela mainte fois.
J'espère que cela vous aide. Bàv, Martin
Bonjour Martin,
En fait, j'ai trouvé les urls des familles, et des marques.
Avec l'url des marques, je peux afficher tous les produits en la terminant par "…marque*". Mais je scrape par 32 produits maximum ( &page=1, &page=2, etc…), ça sera peut être moins repérable. Au total, cela me fait 181 pages.
Ce que je voudrais dans l'idéal, c'est qu'il aille chercher les références et l'état du stock à partir de l'unique url des marques. Si pas possible, alors à partir de plusieurs urls.
Voici le code d'une cellule qui contient les éléments des produits. J'ai enlevé, par discrétion, tous les éléments confidentiels.
Est ce que ça peut vous mettre sur la piste.
Pour info, je suis inculte en VBA et ça ne me passionne pas ( dommage ).;-)
Ah, j'oubliais, c'est le site d'un de mes fournisseurs auquel j'ai demandé un état des stocks mais qui ne sait pas comment faire et qui est allergique à internet. Donc, l'accès est sécurisé.
Re-bonjour Martin,
Le copier/coller ne prend pas quand je veux répondre.
J'ai ceci depuis le fichier xml de mon scrap, ça pourra peut être vous en dire plus :
"HTML[0][ ]\BODY[1][int]\DIV[1][ ]\DIV[2][int-content]\DIV[1][ ]\DIV[1][col2]\DIV[3][listeArticle]\DIV[0][produits-grid]\TABLE[0][ ]\TBODY[0][ ]\TR[0][ ]\TD[0][tdCelluleItem1]\DIV[0][item]\DIV[3][price]\DIV[1][stock]\SPAN[0][ok]\"
Cordialement,
Re-bonjour,
oui, l'ajout du code html dans les commentaires ne marche pas bien car il est "traduit" comme si c'était une partie de la page.
Mais je peux accéder à votre message dans l'administration donc c'est bon.
En effet, 181 pages c'est déjà mieux que 6000 🙂 Sinon, essayez s'il n'y a pas un paramètre dans URL avec le nombre d'items par page, c'est souvent le cas (par exemple quelque chose comme &page=2&itemsperpage=100).
Je vais essayer de regarder votre demande mais je ne promets pas que j'aurai le temps. Normalement, ce type de demande plus complexe/personnalisé passe par la consultance. Sinon, si cela urge, essayez le Forum de Excel-Pratique.com. Là bas, ils sont plus nombreux et pourront peut-être vous aider plus vite. Bien à vous, Martin
Bonjour,
Merci pour votre aide.
Si je mets, marque=*&limit=100&page=1, ça fonctionne, page 2 etc…
Si vous avez le temps de regarder après ce problème, ce serait vraiment sympathique.
Cordialement,
Bonjour Excel-Malin
Je gère un référentiel d'articles dont les intitulés comportent une couleur.
Je dois extraire la couleur de la chaîne de caractère de l'intitulé du produit.
Comme il y a plusieurs couleurs, elles doivent être contenues dans une liste à partir de laquelle la macro doit exécuter la requête d'extraction de la chaîne délimitée (ici le nom de la couleur).
Comment faire pour intégrer ce paramètre dans le code vba ci-dessus ?
Je vous remercie d'avance pour votre aide.
B.R
Bonjour,
si la couleur est entouré du même texte (peu importe la couleur), alors la fonction que vous pouvez trouver ici fonctionnera pour n'importe quelle couleur. Il suffit d'utiliser la chaîne qui se trouve avant et après la couleur.
Peut-être si vous montreriez quelques références comme exemple, je pourrais vous aider plus concrètement…
Cordialement, Martin
Merci pour cette macro.
Mais pour mon besoin (extraction de log), j'ai du l'améliorer
je voulais que ExtraireChaineDelimitee("xefabcdef", "ab", "ef") ==> "cd", mais ça marche pas car il y a un "ef" avant "ab".
Merci pour ce grand service! Ca fait toujours plaisir de trouver des personnes qui partagent leurs outils comme vous. Quand on est pas très câlé ca aide beaucoup
Avec plaisir