formateur informatique

Rechercher et remplacer dans les fichiers d'un dossier

Accueil  >  Bureautique  >  Excel  >  Excel VBA  >  Rechercher et remplacer dans les fichiers d'un dossier
Livres à télécharger


Pour partager cette vidéo sur les réseaux sociaux ou sur un site, voici son url :


Inscription Newsletter    Abonner à Youtube    Vidéos astuces Instagram
Sujets que vous pourriez aussi aimer :


Rechercher et remplacer dans les fichiers d'un dossier

Dans cette formation VBA Excel, nous proposons de monter une application fort précieuse permettant de remplacer n'importe quelle occurrence par une autre, dans tous les fichiers contenus dans un dossier. Ce dossier doit être spécifié par l'utilisateur à l'aide d'une boîte de dialogue Windows standard. L'objectif est d'automatiser les actions de mises à jour par traitements récursifs en exploitant les objets VBA permettant de manipuler les fichiers et dossiers.

Application Visual Basic Excel pour remplacer dans tous les fichiers situés dans un dossier

Dans l'application finalisée illustrée par la capture ci-dessus, deux boutons sont à disposition de l'utilisateur pour enclencher les actions. Des zones sont prévues pour stocker les informations comme le chemin d'accès, le terme recherché et le terme de remplacement.

Sources et présentation du concept
Pour réaliser une simulation intéressante, nous proposons d'agir sur des fichiers de cache Html qui servent de sources à une page Web, dotée d'un moteur de recherche. N'importe lequel d'entre eux peut être appelé pour restituer les informations qu'il contient, en fonction des mots clés tapés par l'internaute. Mais le code qui compose ces fichiers doit subir des mises à jour pour s'adapter à la page Internet de réception. Il serait absurde d'envisager des modifications manuelles, d'autant qu'ils sont tous concernés par les mêmes traitements. Nous exploiterons cette page Web, pour visualiser concrètement les changements opérés par notre application. Pour ce faire, nous avons besoin de récupérer les sources. La décompression propose deux fichiers à la racine. Vous notez tout d'abord la présence du classeur rechercher-remplacer-dossier.xlsm, pour l'application VBA à construire. Et vous notez de même la présence du fichier de la page Web saisie-semi-automatique.html. Ce dernier est accompagné de ses ressources externes dans les sous dossiers, nécessaires pour fonctionner, comme nous l'ont appris les formations au développement Web en Javascript.
  • Double cliquer sur le fichier saisie-semi-automatique.html pour l'ouvrir dans un navigateur,
Contenu de page Web dynamique construit sur fichiers externes à nettoyer par le code VBA Excel

Le code Javascript de cette page Html n'est pas fonctionnel. Ce n'est pas ce qui nous intéresse ici. Mais dès l'ouverture, elle charge l'un des fichiers de cache dans son contenu. N'importe quel autre fichier résidant dans le sous dossier cache est susceptible d'être chargé dans la page, en lieu et place. Et plusieurs imperfections sautent aux yeux. Tout d'abord nous constatons la présence d'images brisées. Les liens Html apparaissent en bleu souligné, ce qui fait penser aux très anciens sites Internet. Les rubriques ne sont pas suffisamment espacées. Et enfin, même s'il faut cliquer dessus pour s'en apercevoir, les liens Html sont eux aussi brisés. Ils conduisent vers des pages qui n'existent pas, à cause d'un préfixe manquant et donc à ajouter grâce à l'application VBA Excel.
  • Dans le dossier de décompression, double cliquer sur le sous dossier cache pour accéder à son contenu,
Vous y notez la présence de plus de 400 fichiers Html. Ce nombre a volontairement été réduit pour simplifier l'importation. Bien que proposant tous un contenu différent, ils possèdent la même structure avec les mêmes imperfections que nous avons notées sur la page Web.
  • Cliquer avec le bouton droit de la souris sur le fichier absolues-excel.html par exemple,
  • Dans le menu contextuel qui apparaît, choisir de l'ouvrir avec un éditeur tel que le Notepad,
Contenu Html des fichiers externes à purger et corriger automatiquement des imperfections par le code VBA Excel

Comme vous le remarquez, ces fichiers sont constitués d'un code Html linéaire, construit par un code serveur pour permettre des restitutions de bases de connaissances, selon les termes fréquemment tapés par les internautes. Ce fichier en l'occurrence pèse 9ko, il contient donc environ 9000 caractères.

Naviguer dans les dossiers du système d'exploitation
Il est temps de s'intéresser au classeur Excel dont l'objectif à l'issue sera de permettre le nettoyage de tous ces fichiers ou autres, dans un traitement récursif. N'importe quel terme ou expression doit pouvoir être remplacée par une autre. Mais avant cela, nous devons permettre à l'utilisateur de désigner le dossier dans lequel le traitement automatisé doit intervenir.
  • A la racine du dossier de décompression, double cliquer sur le fichier rechercher-remplacer-dossier.xlsm, pour l'ouvrir dans Excel,
  • Puis, cliquer sur le bouton Activer la modification du bandeau de sécurité,
Structure application Excel pour chercher et remplacer expressions dans tous les fichiers externes du dossier spécifié

Seule la feuille Traitement compose ce classeur. La cellule B6 est prévue pour stocker le chemin d'accès au dossier, défini par l'utilisateur au clic sur le bouton Dossier. Les cellules B9 et B11 sont respectivement prévues pour mémoriser le terme à remplacer et le terme de remplacement. Le bouton Démarrer doit alors lancer le traitement sur tous les fichiers contenus dans le dossier spécifié en B6. Sa mission est de réaliser le remplacement des termes dans chacun d'entre eux, en fonction des indications contenues en B9 et B11.

Nous devons donc proposer à l'utilisateur de spécifier un dossier, à l'aide du premier bouton. Le ruban Développeur est nécessaire pour ces manipulations. S'il n'est pas présent dans votre environnement, la formation pour débuter la programmation en VBA Excel, rappelle comment l'afficher.
  • Cliquer sur l'onglet Développeur en haut de la fenêtre Excel pour activer son ruban,
  • Dans la section Contrôles du ruban, cliquer sur le bouton Mode création,
  • Puis, sur la feuille Excel, double cliquer sur le bouton 1/ Dossier,
Nous basculons ainsi dans l'éditeur de code Visual Basic Excel, entre les bornes de la procédure chemin_Click. Le code VBA que nous y ajouterons se déclenchera donc au clic sur ce bouton.

Pour piloter les boîtes de dialogue standards de Windows, la référence Microsoft Office 16.0 Object Library a été ajoutée au projet Visual Basic. Le numéro dépend de la version du pack Office. Une différence de version ne procure aucune incidence.

Référence librairie VBA Excel pour désigner fichiers et dossiers avec boîte de dialogue Office standard

Si cette librairie n'est pas ajoutée, les classes ne peuvent pas être instanciées. En conséquence, les objets permettant de piloter ces boîtes de dialogue, ne peuvent pas être créés.
  • Entre les bornes de la procédure, ajouter les déclarations suivantes :
Dim bDialogue As Office.FileDialog
Dim chDossier As String


Très simplement, nous déclarons une première variable comme un objet de boîte de dialogue standard. Nous le nommons bDialogue. Puis nous déclarons une variable de type chaîne de caractères afin de pouvoir réceptionner le chemin d'accès désigné par l'utilisateur, au travers de cette boîte de dialogue.

Après les déclarations, suivent les affectations.
  • A la suite du code, ajouter les deux instructions suivantes :
Set bDialogue = Application.FileDialog(msoFileDialogFolderPicker)
bDialogue.Title = "Sélectionner un dossier à parcourir"


Grâce à la propriété FileDialog de l'objet VBA Application, nous instancions la classe permettant de piloter un type de boîte de dialogue. Ce type est défini en paramètre de la propriété. Au cours de la saisie, c'est la liste IntelliSense qui nous guide. En l'occurrence, le paramètre msoFileDialogFolderPicker définit une boîte de dialogue permettant de parcourir et désigner des dossiers. A ce stade, notre objet bDialogue a donc hérité des propriétés et méthodes nécessaires pour les manipuler. Et pour preuve, sur la ligne suivante, nous exploitons la propriété Title afin de personnaliser la barre de titre de la boîte de dialogue. Et c'est donc une méthode qui va permettre de déclencher son affichage.
  • A la suite du code VBA, ajouter les instructions suivantes :
If bDialogue.Show = -1 Then
chDossier = bDialogue.SelectedItems(1)
Range("B6").Value = chDossier
End If


La méthode Show de l'objet bDialogue renvoie une valeur numérique. Si elle vaut 1, elle indique que l'utilisateur a bien sélectionné un dossier sans se défausser. C'est la raison pour laquelle nous intégrons le traitement dans une instruction conditionnelle If. La propriété SelectedItems renvoie le chemin d'accès ainsi désigné. Le paramètre 1 est nécessaire pour préciser qu'il s'agit du premier dossier de la sélection bien que nous n'ayons pas paramétré la multi sélection. Nous stockons ce chemin dans la variable chDossier puis l'inscrivons en cellule B6 de la feuille Excel.
  • Enregistrer les modifications (CTRL + S) et basculer sur la feuille Excel (ALT + F11),
  • Dans le ruban Développeur, cliquer sur le bouton Mode création pour le désactiver,
  • Cliquer alors sur le bouton 1/ Dossier de la feuille,
  • Dans la boîte de dialogue qui suit, sélectionner le sous dossier cache du dossier de décompression,
  • Puis, valider par Ok,
Déclencher boîte de dialogue Office standard par le code VBA Excel pour sélectionner dossiers et fichiers

Une fois la validation prononcée, vous constatez que le chemin d'accès complet au dossier, est parfaitement restitué dans la cellule B6, comme nous l'avons mentionné dans le code VBA par affectation. Il s'agit de l'information essentielle pour que le code Visual Basic puisse parcourir l'ensemble des fichiers qu'il contient, afin d'y opérer les remplacements automatisés.

Le code complet de la procédure chemin_Click, est le suivant :

Private Sub chemin_Click()
Dim bDialogue As Office.FileDialog
Dim chDossier As String

Set bDialogue = Application.FileDialog(msoFileDialogFolderPicker)
bDialogue.Title = "Sélectionner un dossier à parcourir"

If bDialogue.Show = -1 Then
chDossier = bDialogue.SelectedItems(1)
Range("B6").Value = chDossier
End If
End Sub


Nettoyer la plage d'extraction
Avant de procéder à l'examen du dossier par traitement récursif, nous devons penser qu'il est nécessaire de supprimer les informations d'un potentiel précédent traitement. Ces informations seront inscrites à partir de la ligne 8, entre les colonnes G et I. Nous avons régulièrement réalisé ce genre de traitement à l'aide d'une boucle While qui permet de poursuivre l'exécution tant qu'un critère est vérifié, en l'occurrence ici, tant qu'une cellule non vide est détectée.
  • Dans le ruban Développeur, cliquer de nouveau sur le bouton Mode création,
  • Puis, sur la feuille Excel, double cliquer sur le bouton 2/ Démarrer,
Nous générons ainsi la procédure événementielle demarrer_Click, celle qui s'exécutera au clic sur ce bouton. Le code ne peut être déclenché que si trois conditions sont satisfaites. Le dossier doit être spécifié. Les termes de recherche et de remplacement doivent être définis. En d'autres termes, les cellules B6, B9 et B11 ne doivent pas être vides.
  • Dans les bornes de la procédure demarrer_Click, ajouter les instructions suivantes :
If (Range("B6").Value = "") Then
MsgBox ("Vous devez désigner un dossier à parcourir avec le premier bouton")
Exit Sub
End If

If (Range("B9").Value = "") Then
MsgBox ("Vous devez spécifier un terme à remplacer")
Exit Sub
End If

If (Range("B11").Value = "") Then
MsgBox ("Vous devez spécifier un terme de remplacement")
Exit Sub
End If


Il s'agit de trois traitements conditionnels équivalents, seule la cellule testée change. Prenons la première en exemple. Si le contenu de la cellule B6 est détecté comme vide : Range("B6").Value = "", alors nous affichons un message à l'utilisateur grâce à la fonction VBA MsgBox, pour corriger le problème. Et dans la foulée, nous exploitons l'instruction Exit Sub pour mettre fin à l'exécution du code.

Si les trois tests ne sont pas concluants, cela signifie que l'utilisateur a renseigné tous les paramètres. Nous devons donc poursuivre l'exécution du programme. Par esprit de structure, nous souhaitons que cette procédure passe la main à deux procédures indépendantes. La première doit se charger de nettoyer la feuille, nous la nommerons nettoyer. La seconde doit de charger de réaliser le traitement récursif pour traiter tous les fichiers du dossier, nous la nommerons traiter_dossier.
  • Bien qu'elles n'existent pas encore, réaliser leurs appels, à la suite du code :
Nettoyer
traiter_dossier


Ces deux procédures doivent désormais être créées. Toujours par esprit de structure, nous proposons de les ajouter dans un module.
  • Dans l'explorateur de projet, sur la gauche de l'éditeur de code VBA, déployer l'affichage du dossier Modules,
  • Puis, cliquer sur l'élément Module1 déjà présent, pour afficher sa feuille de code au centre de l'écran,
  • Créer les deux procédures nettoyer et traiter_dossier, comme suit :
Sub nettoyer()

End Sub

Sub traiter_dossier()

End Sub
  • Dans les bornes de la procédure nettoyer, ajouter les déclarations et affectation suivantes :
Dim ligne As Integer: Dim colonne As Integer

ligne = 8


Nous avons besoin de parcourir les lignes et certaines colonnes, donc nous déclarons les variables en adéquation. Puis, nous initialisons la ligne sur l'indice 8, soit la position à partir de laquelle le code VBA doit analyser les cellules, pour les vider s'il reste des traces d'extraction. Ensuite, comme nous en avons l'habitude désormais, il s'agit d'enclencher une boucle While qui poursuivra son traitement récursif, tant que son critère est vrai, soit tant que la cellule en cours n'est pas vide.
  • A la suite du code, créer la boucle While comme suit :
While (Cells(ligne, 7).Value <> "")

Wend


C'est effectivement la cellule de la ligne 8 en colonne G (indice 7) qui est utilisée comme point de départ de l'analyse. Si la cellule en cours d'étude n'est pas vide, c'est l'ensemble des cases sur les trois colonnes qui doivent être purgées, soit de la colonne G à I. Donc il s'agit d'imbriquer une seconde boucle à l'intérieur de la première, pour simplifier le code et le traitement. Lorsque les bornes sont définies, une boucle For Next est dédiée.
  • A l'intérieur de la boucle While, ajouter les instructions suivantes :
For colonne = 7 To 9
Cells(ligne, colonne).Value = ""
Next colonne
ligne = ligne + 1


Pour chaque ligne (ligne = ligne + 1), tant que la cellule de référence n'est pas vide, nous les effaçons toutes (Cells(ligne,colonne).Value = ""), pour l'ensemble des trois colonnes (For colonne = 7 To 9).

Pour tester le code, il s'agit de définir un dossier ainsi que des termes en B9 et B11. Souvenez-nous, si tel n'est pas le cas, les tests VBA que nous avons codés nous bloqueront. De même, il s'agit d'inscrire quelques valeurs temporaires à partir de la ligne 8, sur plusieurs lignes. Enfin, il s'agit de désactiver le mode Création et de cliquer sur le bouton Démarrer.

Le code complet de la procédure nettoyer est le suivant :

Sub nettoyer()
Dim ligne As Integer: Dim colonne As Integer

ligne = 8

While (Cells(ligne, 7).Value <> "")
For colonne = 7 To 9
Cells(ligne, colonne).Value = ""
Next colonne
ligne = ligne + 1
Wend

End Sub


Parcourir tous les fichiers d'un dossier
Comme nous l'avait appris la formation VBA Access pour accéder aux fichiers externes par le code, nous devons instancier la classe qui permettra d'hériter des propriétés et méthodes permettant de manipuler les fichiers et dossiers. Et comme souvent, c'est la fonction VBA CreateObject avec un argument spécifique qui va nous le permettre. Mais avant cela, nous devons déclarer et initialiser les variables nécessaires au traitement.
  • Entre les bornes de la procédure traiter_dossier, ajouter les déclarations et affectations suivantes :
Dim nom_dossier As String: Dim fichier As Object
Dim le_dossier, chaque_fichier: Dim flux_lecture
Dim ligne As Integer: Dim le_fichier As String
Dim contenu As String: Dim chercher As String: Dim remplacer As String

nom_dossier = Range("B6").Value
chercher = Range("B9").Value
remplacer = Range("B11").Value
ligne = 8


Nous déclarons entre autres les variables nom_dossier et le_fichier en tant que String afin de pouvoir manipuler les chemins d'accès au dossier et à chacun des fichier parcourus. La variable fichier est déclarée comme un objet pour pouvoir instancier la classe permettant de manipuler les fichiers du disque. Les variables le_dossier et chaque_fichier sont volontairement non typées. Elles le seront à la volée par affectation, afin de manipuler le dossier et chacun des fichiers qui y réside. La variable flux_lecture est prévue pour instancier la classe permettant d'accéder aux fichiers externes, en lecture et en écriture, tout en définissant l'encodage, pour résoudre les problèmes d'accents. Les dernières variables de type String parlent d'elles-mêmes. La variable contenu doit stocker l'information complète du fichier Html en cours de lecture. Les variables chercher et remplacer y seront exploitées pour réaliser les modifications demandées par l'utilisateur.

Comme nous avons déjà affecté les premières variables classiques, juste après les déclarations, nous devons désormais instancier les classes qui permettront aux variables objets, d'hériter des propriétés et méthodes nécessaires.
  • A la suite du code, ajouter les affectations suivantes :
Set fichier = CreateObject("scripting.filesystemobject")
Set le_dossier = fichier.getfolder(nom_dossier)
Set flux_lecture = CreateObject("ADODB.Stream")
flux_lecture.Charset = "utf-8"


Grâce au paramètre scripting.filesystemobject passé à la fonction VBA CreateObject, nous instancions la classe permettant à la variable fichier d'hériter des méthodes pour manipuler les fichiers du système. Et précisément, sa méthode getfolder avec en paramètre le chemin du dossier spécifié, permet d'affecter la variable le_dossier. Elle dispose donc désormais des propriétés nécessaires pour piloter ce dossier spécifique. Enfin, nous instancions la classe permettant à l'objet flux_lecture d'accéder au contenu des fichiers externes. Pour cela, nous passons le paramètre ADODB.Stream à la fonction VBA CreateObject. Dans la foulée donc, grâce à sa propriété Charset, nous définissons une bonne fois pour toute l'encodage (utf-8) qui sera utilisé pour tous les fichiers atteints.

Nous disposons désormais de tous les moyens nécessaires pour accéder aux données externes. Comme nous ne connaissons pas à l'avance le nombre de fichiers contenus dans le dossier, nous devons exploiter une boucle de traitement For Each.
  • A la suite du code, créer la boucle parcourant les fichiers, comme suit :
For Each chaque_fichier In le_dossier.Files

Next chaque_fichier


Comme nous l'avons expliqué dans de précédentes formations, les objets à gauche et à droite de l'instruction In doivent être du même type. C'est la raison pour laquelle nous n'avions pas typé la variable chaque_fichier. Elle hérite à la volée des propriétés nécessaires pour manipuler chaque fichier qui sera parcouru. C'est la propriété Files de l'objet le_dossier qui renvoie une collection. Cette collection correspond à l'ensemble des fichiers contenus dans le dossier pointé.
  • A l'intérieur de la boucle, ajouter les deux affectations suivantes :
le_fichier = nom_dossier & "\" & chaque_fichier.Name
contenu = ""


Grâce à la propriété héritée Name de l'objet chaque_fichier, nous prélevons le nom du fichier en cours de lecture dans la boucle. Nous concaténons cette information au chemin du dossier. Nous obtenons donc le chemin d'accès complet au fichier parcouru. Dès lors, nous pourrons explicitement le désigner pour accéder à son contenu et le prélever. Justement, nous réinitialisons la variable contenu à chaque passage, pour la purger de son ancien traitement.

Rechercher et remplacer dans les fichiers externes
Puisque nous disposons de toutes les informations nécessaires, il est temps d'accéder au contenu de chaque fichier lu, grâce à l'objet flux_lecture. Une fois l'intégralité du fichier réceptionné, nous pourrons le traiter pour y remplacer le terme désigné. Pour que cette modification soit ancrée, nous devrons ensuite enregistrer le fichier sur le disque. Tout traitement se réalise en effet dans la mémoire du système.
  • A la suite du code, ajouter les instructions permettant de récupérer le contenu du fichier :
flux_lecture.Open
flux_lecture.LoadFromFile (le_fichier)
contenu = flux_lecture.ReadText()
flux_lecture.Close


La méthode Open de l'objet flux_lecture permet de réserver un accès en mémoire pour y charger le fichier. Et justement, c'est ensuite sa méthode LoadFromFile qui comme son nom l'indique, charge le fichier dont le chemin d'accès complet lui est passé en paramètre. Alors sa méthode ReadText() permet tout simplement de récupérer l'intégralité des données que nous affectons à la variable contenu. Avant de travailler cette dernière, nous n'oublions de libérer la mémoire grâce à la méthode Close de l'objet flux_lecture.

Désormais, la fonction Replace doit opérer les modifications. Suite à cela, nous les sauvegarderons. Comme nous sommes dans une boucle For Each, ces traitements valent pour tous les fichiers parcourus. La syntaxe de la fonction Replace est la suivante :

Replace(Chaîne_de_texte ; Terme_a_remplacer ; Terme_de_remplacement)
  • A la suite du code, ajouter les traitements suivants :
contenu = Replace(contenu, chercher, remplacer)

flux_lecture.Open
flux_lecture.WriteText contenu
flux_lecture.SaveToFile le_fichier, 2
flux_lecture.Close


Nous exploitons tout d'abord la fonction Replace sur la variable contenu afin de remplacer toutes les occurrences du terme désigné depuis la feuille, par l'expression de remplacement. Puis, nous exploitons de nouveau l'objet flux_lecture, mais pour enregistrer cette fois. Nous réservons d'abord l'accès en mémoire par sa méthode Open. L'écriture s'y fait par sa méthode WriteText en lui passant la chaîne à écrire (contenu). Puis sa méthode SaveToFile réalise l'enregistrement sous le nom de fichier qui lui est passé en premier paramètre. Une fois la sauvegarde terminée, nous libérons la mémoire par sa méthode Close.

A ce stade, tous les fichiers sont susceptibles d'être modifiés. Mais avant cela, il nous reste à restituer les informations du rapport entre les colonnes G et I, à partir de la ligne 8. Pour ce faire :
  • A la suite du code, toujours dans la boucle For Each, ajouter les instructions suivantes :
Cells(ligne, 7).Value = chaque_fichier.Name
Cells(ligne, 9).Value = "Ok"
ligne = ligne + 1


Surtout, nous n'oublions pas d'incrémenter la variable ligne avant de boucler pour que l'inscription du prochain fichier, se réalise bien sur la ligne du dessous.

Exécuter les modifications robotisées sur les fichiers
Pour un codage propre, les objets exploités doivent être vidés afin de libérer les ressources.
  • A la suite du code mais après la boucle, ajouter les trois instructions suivantes :
Set flux_lecture = Nothing
Set le_dossier = Nothing
Set fichier = Nothing


C'est comme toujours l'instruction Nothing, par réaffectation, qui permet de détruire ces objets. Pour visualiser les effets des manipulations à suivre, il est intéressant de conserver ouvert le fichier de la page Web. De même, il est intéressant d'ouvrir un fichier de cache, comme absolues-excel.html, dans un éditeur tel que le NotePad.
  • Enregistrer les modifications (CTRL + S) et basculer sur la feuille Excel (ALT + F11),
Le premier traitement à réaliser consiste à remplacer dans tous les fichiers, l'information inscrite en L1 par l'information inscrite en L2. En langage Html cette modification ajoute un petit espace entre les calques pour aérer légèrement la présentation. Comme les cellules de réception en B9 et B11 sont des cellules fusionnées, pour recopier les données, il est conseillé de réaliser un copier-coller de barre de formule à barre de formule.
  • Répliquer l'information de la cellule L1 dans la cellule B9,
  • Répliquer l'information de la cellule L2 dans la cellule B11,
  • Puis, cliquer sur le bouton Démarrer,
Le temps d'exécution varie selon la cadence du processeur. Mais étant donné le nombre d'opérations effectuées et le nombre de fichiers traités, la vitesse de traitement est satisfaisante.
  • Basculer dans l'éditeur Notepad pour afficher le code de la page Html,
Remplacement robotisé de termes recherchés dans des fichiers externes parcourus par un code Visual Basic Excel

Comme vous le remarquez, l'éditeur indique que des modifications ont eu lieu et propose de mettre à jour l'affichage du fichier. Vous devez donc valider cette proposition. Et comme l'illustre la capture ci-dessus, l'attribut style a parfaitement été ajouté dans les balises div reconnues par leur classe titre_cat. Il est important de comprendre que toutes les balises div de tous les fichiers ont ainsi été affectées. Ces pages Html proposent au-delà de 10 résultats chacune et il y a plus de 400 pages. En conséquence, notre code VBA Excel a réalisé plus de 4000 modifications dans ces fichiers externes. Le principe reste le même si le nombre de fichiers grandit. Nous constatons donc tout l'intérêt de ces actions robotisées qui réalisent en un temps record, ce qu'il aurait été inconcevable de faire manuellement.
  • Basculer sur le navigateur de la page Web et la rafraîchir avec la touche F5,
Vous remarquez en effet que les lignes des rubriques s'espacent quelque peu, pour une présentation plus agréable. Nous allons désormais procéder à des remplacements dont l'incidence visuelle est plus marquée.
  • Revenir sur la feuille du classeur Excel,
  • Répliquer l'information de la cellule L4 dans la cellule B9,
  • Répliquer l'information de la cellule L5 dans la cellule B11,
  • Puis, cliquer sur le bouton Démarrer,
Tout d'abord nous remplaçons la cible du lien _self par _blank pour que la page de destination soit ouverte dans un nouvel onglet, plutôt qu'en lieu et place. Puis, nous ajoutons l'attribut Style pour que ces liens ne soient plus soulignés (text-decoration:none) et que leur couleur bleue soit remplacée par du gris (color:#666).

Si vous basculez dans l'éditeur Notepad, une nouvelle mise à jour est demandée à cause de modifications externes, celles engagées par notre code VBA Excel. Si vous affichez le contenu de l'une des balises a href, vous notez effectivement que la modification et l'ajout ont parfaitement été opérés. Encore une fois, toutes les balises de cette nature pour l'ensemble des pages Web ont été affectées. Nous proposons de constater les incidences visuelles, plus probantes cette fois.
  • Basculer sur la fenêtre du navigateur et rafraîchir la page avec la touche F5 du clavier,
Modifier occurrences semblables dans tous les fichiers contenus dans un dossier par traitement robotisé VBA Excel

Cette fois, comme l'illustre la capture ci-dessus, les modifications visuelles sont beaucoup plus significatives. Le soulignement pour l'ensemble des liens a effectivement disparu. De même le bleu a bien été remplacé par un gris plus sobre.

Un problème persiste néanmoins. Ces liens sont brisés car leur url n'est pas complète. Si vous cliquez sur l'un d'entre eux, vous êtes redirigé sur une page d'erreur. Cette url est définie par l'attribut href d'une balise a.

<a href='mastermind-creer-un-jeu-avec-excel-200.html'...

Il manque le préfixe du site internet (https://www.bonbache.fr/). La dernière opération de recherche et remplacement, consiste donc à ajouter ce préfixe dans tous les attributs href, pour toutes les pages Html du dossier.
  • Revenir sur la feuille du classeur Excel,
  • Répliquer l'information de la cellule L8 dans la cellule B9,
  • Répliquer l'information de la cellule L9 dans la cellule B11,
  • Puis, cliquer sur le bouton Démarrer,
Pas d'incidence visuelle cette fois, mais une correction majeure dans le résultat et la fonctionnalité de la page Web. Si vous rafraîchissez cette dernière, au clic sur l'un des liens, vous êtes désormais parfaitement redirigé sur l'une des rubriques de formation du site Bonbache.fr.

Le code complet de la procédure traiter_dossier est le suivant :

Sub traiter_dossier()
Dim nom_dossier As String: Dim fichier As Object
Dim le_dossier, chaque_fichier: Dim flux_lecture
Dim ligne As Integer: Dim le_fichier As String
Dim contenu As String: Dim chercher As String: Dim remplacer As String

nom_dossier = Range("B6").Value
chercher = Range("B9").Value
remplacer = Range("B11").Value
ligne = 8

Set fichier = CreateObject("scripting.filesystemobject")
Set le_dossier = fichier.getfolder(nom_dossier)
Set flux_lecture = CreateObject("ADODB.Stream")
flux_lecture.Charset = "utf-8"

For Each chaque_fichier In le_dossier.Files
le_fichier = nom_dossier & "\" & chaque_fichier.Name
contenu = ""
flux_lecture.Open
flux_lecture.LoadFromFile (le_fichier)
contenu = flux_lecture.ReadText()
flux_lecture.Close

contenu = Replace(contenu, chercher, remplacer)
flux_lecture.Open
flux_lecture.WriteText contenu
flux_lecture.SaveToFile le_fichier, 2
flux_lecture.Close

Cells(ligne, 7).Value = chaque_fichier.Name
Cells(ligne, 9).Value = "Ok"
ligne = ligne + 1
Next chaque_fichier

Set flux_lecture = Nothing
Set le_dossier = Nothing
Set fichier = Nothing

End Sub


Remplacer une information variable
Il nous reste en effet à corriger le problème d'affichage des images dont le lien est brisé. Nous ne possédons pas ces images. Il ne s'agit donc pas de réaliser un correctif mais de supprimer toutes les balises qui les concernent et ce, dans toutes les pages Html bien évidemment. Mais, il n'y a pas de règle stricte pour les déceler. Leur contenu change d'un lien à un autre et d'une page à une autre. En revanche, nous connaissons leur signature. Nous savons qu'elles débutent comme ceci : <img, et qu'elles se terminent comme cela : /> :

<img class='img_cat' src='MasterMind-creer-un-jeu-avec-Excel 2017-06-02-48-02.jpg' alt='' />

Nous avons déjà appris comment procéder face à cette problématique grâce à la formation précédente sur le traitement des chaînes de caractères par les expressions régulières. Il s'agit de construire un motif indiquant comment débute la chaîne à trouver et comment elle se termine, tout en précisant que les caractères situés entre ces informations sont inconnus et possèdent un nombre indéfini. Pour cela, nous avons encore besoin d'instancier une classe, grâce à la fonction VBA CreateObject, afin de manipuler ces expressions régulières.

Nous pourrions très bien personnaliser ce traitement en prévoyant deux zones supplémentaires sur la feuille Excel. L'utilisateur y indiquerait la séquence de début ainsi que la séquence de fin. Mais ici, nous allons nous contenter de créer une fonction indépendante pour ce traitement particulier.
  • Basculer dans l'éditeur de code VBA Excel,
  • Après la fonction traiter_dossier, créer la fonction decoupe_spec, comme suit :
Function decoupe_spec(chaine As String) As String
Dim expReg As Object: Dim motif As Object

Set expReg = CreateObject("vbscript.regexp")
expReg.Pattern = "(<img)[0-9a-zA-Z_   \/.:;'=-]*(/>)"
Set motif = expReg.Execute(chaine)

While motif.Count > 0
chaine = expReg.Replace(chaine, "")
Set motif = expReg.Execute(chaine)
Wend

decoupe_spec = chaine
End Function


La vocation d'une fonction est de retourner le résultat du traitement qu'elle réalise, à la procédure qui l'appelle. Ce renvoi se réalise implicitement par l'affectation de ce résultat au nom même de la fonction (decoupe_spec = chaine). Nous lui affectons un paramètre (chaine As String) qui est le contenu du fichier, à chaque passage dans la boucle, à nettoyer de ces balises img. Nous déclarons les deux objets nécessaires pour piloter les expressions régulières : expReg et motif.

Nous instancions la classe vbscript.regexp, grâce à la fonction CreateObject. De fait, l'objet expReg hérite de toutes les propriétés et méthodes permettant de manipuler ces expressions régulières. Ainsi, nous exploitons sa propriété Pattern pour définir le motif à rechercher : (<img)[0-9a-zA-Z_   \/.:;'=-]*(/>). Par les parenthèses, nous indiquons strictement comment débute et se termine chaque occurrence à trouver. Entre les crochets, nous indiquons tous les caractères qu'il est possible de rencontrer comme des lettres, des chiffres ou encore des caractères spéciaux. L'étoile après les crochets spécifie que leur nombre est inconnu et indifférent.

Grâce à sa méthode Execute, nous instancions l'objet motif qui de fait, hérite des propriétés nécessaires pour tester ce pattern sur la chaîne de caractères passée en paramètre. Ainsi, grâce à sa propriété Count, nous enclenchons une boucle qui tourne tant que le motif est trouvé. Et à chaque fois qu'il est trouvé, nous le supprimons grâce à la méthode Replace de l'objet expReg. Avant de boucler, nous redéfinissons la recherche sur la prochaine occurrence (motif = expReg.Execute(chaine)), pour réactualiser le critère.
  • Dans la boucle de la procédure traiter_dossier, après la ligne : contenu = Replace(contenu, chercher, remplacer), ajouter l'appel suivant :
contenu = decoupe_spec (contenu)

Ainsi, pour chaque fichier, dès lors que son contenu est récupéré et traité, nous le passons à la fonction decoupe_spec qui se charge de le purger des balises img, et qui retourne le résultat en lieu et place.
  • Enregistrer les modifications et basculer sur la feuille Excel,
  • Saisir exactement les mêmes termes en B9 et B11, par exemple href=', pour n'enclencher aucun remplacement,
  • Puis, cliquer sur le bouton Démarrer,
  • Basculer sur le navigateur Web et rafraîchir la page,
Supprimer des termes proches et ressemblants grâce aux expressions régulières pilotées par le code VBA Excel

Comme vous le constatez, tous les liens brisés ont disparu puisque toutes les balises img ont été supprimées. Les expressions régulières démontrent toute leur puissance lorsqu'il s'agit de remplacer des termes proches ou ressemblants, par le biais d'actions robotisées, ici pilotées en VBA Excel.

 
Sur Facebook
Sur Youtube
Les livres
Contact
Mentions légales



Abonnement à la chaîne Youtube
Partager la formation
Partager sur Facebook
Partager sur Twitter
Partager sur LinkedIn