Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Vba Delete paragraphs

4 réponses
Avatar
gary
Bonjour

La procédure suivante est extrêmement longue.
Avez-vous une idée de ce qui la rend si longue ? Et une suggestion ?

Il s'agit d'effacer tous les paragraphe d'un document (de 200 pages)
sauf les titres, et sauf certains paragraphes où apparaissent des underscores

Pour info je veux récupérer les structure d'une spécification fonctionnelle
word avec le nom des variables seulement.

Merci à tous lecteurs.
--------------------------------
Voici l'objet du délit :

Sub totSupression()
'Dim i, paraDepart, nbPara, niveauPara, positionUnderscore As Integer
'Dim garder, texTest As String

paraDepart = 444
nbPara = 991

MsgBox ("allons y")
ActiveDocument.Paragraphs(paraDepart).Range.Select

For i = paraDepart To nbPara
garder = "non"
niveauPara = ActiveDocument.Paragraphs(i).OutlineLevel
If niveauPara < 6 And niveauPara > 0 Then garder = "oui"
textTest = ActiveDocument.Paragraphs(i).Range.Text
positionUnderscore = InStr(textTest, "_")
If positionUnderscore > 1 Then garder = "oui"

If garder = "non" Then
ActiveDocument.Paragraphs(i).Range.Delete
i = i - 1
nbPara = nbPara - 1
End If

Next i
End Sub
----------------------------------

4 réponses

Avatar
Anacoluthe
Bonjour !

'gary' nous a écrit ...
For i = paraDepart To nbPara
...
If garder = "non" Then
ActiveDocument.Paragraphs(i).Range.Delete
i = i - 1
nbPara = nbPara - 1
End If
Next i
End Sub


Votre code est totalement 'hérétique' et gaspille des ressources!

A l'intérieur d'une boucle For i = 1 to N vous modifiez i et N !!!
Vous avez une chance /énorme/ que ça ne plante pas !

De plus vous obligez Word à recompter les paragraphes chaque fois.
Si vous parcourez une collection en détruisant des éléments
ce qui fait varier le nombre et les indices des éléments, la
logique usuelle est de les supprimer à partir de la fin :

For i = nbPara To paraDepart Step -1
...
If garder = "non" Then
ActiveDocument.Paragraphs(i).Range.Delete
Next i

et ne modifiez ni l'index ni les bornes d'une boucle
dans une boucle svp ...........

Anacoluthe
« Si le mot énoncé peut être parfois dangereux,
plus dangereux encore sera le mot supprimé. »
- Luc ROCHEFORT

Avatar
gary
Merci,

C'est pas tant que je sois hérétique que païen !

En procédant à l'envers la performance est nettement meilleure.
Mais elle reste légèrement inférieure à la seconde par paragraphe.

Plutôt que de travailler sur la collection des paragraphes, pourrait-je
gagner en performance en travaillant sur une range ?
Dans quelle direction regarder ?

Merci encore,



Bonjour !

'gary' nous a écrit ...
For i = paraDepart To nbPara
...
If garder = "non" Then
ActiveDocument.Paragraphs(i).Range.Delete
i = i - 1
nbPara = nbPara - 1
End If
Next i
End Sub


Votre code est totalement 'hérétique' et gaspille des ressources!

A l'intérieur d'une boucle For i = 1 to N vous modifiez i et N !!!
Vous avez une chance /énorme/ que ça ne plante pas !

De plus vous obligez Word à recompter les paragraphes chaque fois.
Si vous parcourez une collection en détruisant des éléments
ce qui fait varier le nombre et les indices des éléments, la
logique usuelle est de les supprimer à partir de la fin :

For i = nbPara To paraDepart Step -1
....
If garder = "non" Then
ActiveDocument.Paragraphs(i).Range.Delete
Next i

et ne modifiez ni l'index ni les bornes d'une boucle
dans une boucle svp ...........

Anacoluthe
« Si le mot énoncé peut être parfois dangereux,
plus dangereux encore sera le mot supprimé. »
- Luc ROCHEFORT





Avatar
gary
J'ai le sentiment que c'est la fonctin instr qui n'aide pas.
Utiliser la recherche (en vba) et placer un marqueur en début de paragraphe
Puis revenir regarder paragraphe par paragraphe si j'ai ce marqueur.
Penses-tu que ça puisse améliorer la performance ?


Merci,

C'est pas tant que je sois hérétique que païen !

En procédant à l'envers la performance est nettement meilleure.
Mais elle reste légèrement inférieure à la seconde par paragraphe.

Plutôt que de travailler sur la collection des paragraphes, pourrait-je
gagner en performance en travaillant sur une range ?
Dans quelle direction regarder ?

Merci encore,



Bonjour !

'gary' nous a écrit ...
For i = paraDepart To nbPara
...
If garder = "non" Then
ActiveDocument.Paragraphs(i).Range.Delete
i = i - 1
nbPara = nbPara - 1
End If
Next i
End Sub


Votre code est totalement 'hérétique' et gaspille des ressources!

A l'intérieur d'une boucle For i = 1 to N vous modifiez i et N !!!
Vous avez une chance /énorme/ que ça ne plante pas !

De plus vous obligez Word à recompter les paragraphes chaque fois.
Si vous parcourez une collection en détruisant des éléments
ce qui fait varier le nombre et les indices des éléments, la
logique usuelle est de les supprimer à partir de la fin :

For i = nbPara To paraDepart Step -1
....
If garder = "non" Then
ActiveDocument.Paragraphs(i).Range.Delete
Next i

et ne modifiez ni l'index ni les bornes d'une boucle
dans une boucle svp ...........

Anacoluthe
« Si le mot énoncé peut être parfois dangereux,
plus dangereux encore sera le mot supprimé. »
- Luc ROCHEFORT







Avatar
Anacoluthe
Bonjour !

'gary' nous a écrit ...
Plutôt que de travailler sur la collection des paragraphes, pourrait-je
gagner en performance en travaillant sur une range ?
Dans quelle direction regarder ?


Vous pouvez encore accélérer considérablement la procédure :
- Définissez tout le Range à traiter au lieu d'indexer les § de tout
le document chaque fois
- évitez de ré-indexer plusieurs fois un élément d'une collection
- regroupez toutes les conditions en une seule (and, or)
ou imbriquez les conditions (c'est selon le cas)
- évitez de définir des variables provisoires inutiles
(NiveauPara, TextTest etc.) pour vos tests
- Désactivez le recalcul de la mise en page et de l'affichage
en début de procédure sans oublier de le rétablir à la fin
Application.ScreenUpdating = False (puis remettre True)

La fonction InStr est en effet beaucoup plus lente que le
Rechercher-Remplacer (RR) de Word. Reste qu'il faut bien choisir
ce que va faire ce RR pour les paragraphes avec '_'
N'ajoutez pas un test de plus !
Votre algorithme devrait être : supprimer dans les paragraphes
qui ne sont pas des titres ceux où on ne trouve pas de '_'
(conditions imbriqués)

Anacoluthe
« Si le mot énoncé peut être parfois dangereux,
plus dangereux encore sera le mot supprimé. »
- Luc ROCHEFORT