problème NettoyageClasseur.xls

philppe27

XLDnaute Occasionnel
Bonjour,
J'ai récupéré sur le forum le fichier NettoyageClasseur.xls qui fonctionne très bien et permet manuellement de réduire considérablement la taille de certain de mes fichiers.
J'ai donc passé une étape supplémentaire en me disant que sur ces fichiers à risque d'embonpoint je pourrais mettre le code de NettoyageClasseur.xls dans Private Sub Workbook_BeforeClose(Cancel As Boolean). Ainsi, tant qu'à faire autant automatiser la procédure pour enregistrer des fichiers avec la plus petite taille possible et réduire ainsi les temps de traitement.
Bonne initiative (tant qu'à faire je me félicite moi-même...) qui fonctionne très bien quand je ferme le fichier (voir code ci-dessous)
Par contre, je rencontre un problème lorsque je ferme ce fichier à partir d'une macro qui se trouve sur un autre fichier. La macro Workbook_BeforeClose semble bien se déclencher mais c'est le code que j'ai recopié qui ne semble pas adapté à ce cas de figure et le traitement de nettoyage ne se fait pas correctement.
Merci de vos conseils



Dim Sht As Worksheet, DCell As Range, Calc As Long, Rien As String, compt1 As Integer
Dim Avant As Double, plage As Range
Dim MemVisible

ThisWorkbook.Activate

On Error Resume Next
Calc = Application.Calculation ' ---- mémorisation de l'état de recalcul
'------------------------------------------------------------
With Application
.Calculation = xlCalculationManual
.StatusBar = "Nettoyage en cours..."
.EnableCancelKey = xlErrorHandler
.ScreenUpdating = True
End With
'-------------------- le traitement
For Each Sht In Worksheets
' Si la feuille est masquée
MemVisible = Sht.Visible
If Sht.Visible <> xlSheetVisible Then Sht.Visible = xlSheetVisible
'si la feuille est protégée
Sht.Unprotect Password:="secret" 'déprotéger la feuille
'
Avant = Sht.UsedRange.Cells.Count
Application.StatusBar = Sht.Name & "-" & Sht.UsedRange.Address
'-------------------Traitement de la zone trouvée
If Sht.UsedRange.Address <> "$A$1" Or Not IsEmpty(Sht.[A1]) Then
Set DCell = Sht.Cells.Find("*", , , , xlByRows, xlPrevious)(2)
'----------------Suppression des lignes inutilisées
If Not DCell Is Nothing Then
Sht.Range(DCell, Sht.Cells([A:A].Count, 1)).EntireRow.Delete
Set DCell = Nothing
Set DCell = Sht.Cells.Find("*", , , , xlByColumns, xlPrevious)(, 2)
'----------------Suppression des colonnes inutilisées
If Not DCell Is Nothing Then Sht.Range(DCell, Sht.[IV1]).EntireColumn.Delete
End If
Rien = Sht.UsedRange.Address
End If

Sht.Protect Password:="secret", DrawingObjects:=True, Contents:=True, Scenarios:=True 'protéger la feuille
Sht.Visible = MemVisible
Next Sht

ActiveSheet.Unprotect Password:="secret" 'déprotéger la feuille
'--------------------
Application.StatusBar = False
Application.Calculation = Calc
On Error GoTo 0

ThisWorkbook.save
End Sub
 

Pièces jointes

  • NettoyageClasseur.xls
    37.5 KB · Affichages: 106
  • NettoyageClasseur.xls
    37.5 KB · Affichages: 117
  • NettoyageClasseur.xls
    37.5 KB · Affichages: 113
C

Compte Supprimé 979

Guest
Re : problème NettoyageClasseur.xls

Salut Philppe27,

Je ne comprends ce qui t'arrive :confused:

Test effectué, ça fonctionne ...
Ouvre Classeur2Test et clique sur le bouton

A+
 

Pièces jointes

  • Philppe27.zip
    15.3 KB · Affichages: 40
  • Philppe27.zip
    15.3 KB · Affichages: 42
  • Philppe27.zip
    15.3 KB · Affichages: 42

philppe27

XLDnaute Occasionnel
Re : problème NettoyageClasseur.xls

Merci Bruno de ta réponse mais je suis circonspect sur le test car si j'ai bien compris tu considère que le test est concluant parce que ton message indique "classeur néttoyé".
En cela je suis d'accord avec toi Workbook_BeforeClose est activé et fonctionne. Mais ce que je constate par ailleurs c'est que la taille de mon fichier ne diminue pas alors que lorsque je le ferme manuellement il diminue....
C'est donc dans le code qu'il y a un problème (peut-être parce que le fichier qui lance n'est pas celui qui nettoie ???...) J'avoue que je coince
 

JCGL

XLDnaute Barbatruc
Re : problème NettoyageClasseur.xls

Bonjour à tous,

Peux-tu mettre ce code dans un module et appeler la sub Nettoie dans le _BeforeClose : les Msgbox et les StatusBar te renverront les informations nécessaires

Code:
[COLOR=BLUE]Option Explicit[/COLOR]

[COLOR=BLUE]Sub[/COLOR] Nettoie()
[COLOR=BLUE]Dim[/COLOR] Sht [COLOR=BLUE]As[/COLOR] Worksheet, DCell [COLOR=BLUE]As[/COLOR] Range, Calc [COLOR=BLUE]As Long[/COLOR], Rien [COLOR=BLUE]As String[/COLOR]
[COLOR=BLUE]Dim[/COLOR] Avant [COLOR=BLUE]As Double[/COLOR], Plage [COLOR=BLUE]As[/COLOR] Range
[COLOR=BLUE]On Error Resume Next[/COLOR]
Calc = Application.Calculation
[COLOR=GREEN]'------------------------------------------------------------[/COLOR]
MsgBox "Pour le classeur actif : " & ActiveWorkbook.FullName _
& Chr(10) & "Dans chaque feuille de calcul" _
& Chr(10) & "Recherche la zone contenant des données," _
& Chr(10) & "Réinitialise la dernière cellule utilisée" _
& Chr(10) & "Optimise la taille du fichier Excel", vbInformation, "d'après LL et GeeDee"
[COLOR=GREEN]'-------------------------------------------------------------[/COLOR]
MsgBox "Taille initiale de ce classeur en octets" _
& Chr(10) & FileLen(ActiveWorkbook.FullName), vbInformation, ActiveWorkbook.FullName
[COLOR=GREEN]'------------------------------------------------------------[/COLOR]
[COLOR=BLUE]With[/COLOR] Application
.Calculation = xlCalculationManual
.StatusBar = "Nettoyage en cours..."
.EnableCancelKey = xlErrorHandler
.ScreenUpdating = [COLOR=BLUE]True[/COLOR]
[COLOR=BLUE]End With[/COLOR]
[COLOR=GREEN]'-------------------- le traitement[/COLOR]
[COLOR=BLUE]For Each[/COLOR] Sht [COLOR=BLUE]In[/COLOR] Worksheets
Avant = Sht.UsedRange.Cells.Count
Application.StatusBar = Sht.Name & "-" & Sht.UsedRange.Address
[COLOR=GREEN]'-------------------Traitement de la zone trouvée[/COLOR]
[COLOR=BLUE]If[/COLOR] Sht.UsedRange.Address <> "$A$1" [COLOR=BLUE]Or Not[/COLOR] IsEmpty(Sht.[A1]) [COLOR=BLUE]Then[/COLOR]
[COLOR=BLUE]Set[/COLOR] DCell = Sht.Cells.Find("*", , , , xlByRows, xlPrevious)(2)
[COLOR=GREEN]'----------------Suppression des lignes inutilisées[/COLOR]
[COLOR=BLUE]If Not[/COLOR] DCell [COLOR=BLUE]Is Nothing Then[/COLOR]
Sht.Range(DCell, Sht.Cells([A:A].Count, 1)).EntireRow.Delete
[COLOR=BLUE]Set[/COLOR] DCell = [COLOR=BLUE]Nothing[/COLOR]
[COLOR=BLUE]Set[/COLOR] DCell = Sht.Cells.Find("*", , , , xlByColumns, xlPrevious)(, 2)
[COLOR=GREEN]'----------------Suppression des colonnes inutilisées[/COLOR]
[COLOR=BLUE]If Not[/COLOR] DCell [COLOR=BLUE]Is Nothing Then[/COLOR] Sht.Range(DCell, Sht.[IV1]).EntireColumn.Delete
[COLOR=BLUE]End If[/COLOR]
Rien = Sht.UsedRange.Address
[COLOR=BLUE]End If[/COLOR]
ActiveWorkbook.Save
[COLOR=GREEN]'---------------------Message pour la feuille traitée[/COLOR]
MsgBox "Nom de la feuille de calcul : " & Sht.Name _
& Chr(10) & Format(Sht.UsedRange.Cells.Count / Avant, "0.00%") _
& " de la taille initiale", vbInformation, ActiveWorkbook.FullName
[COLOR=BLUE]Next[/COLOR] Sht
[COLOR=GREEN]'--------------------Message fin de traitement[/COLOR]
MsgBox "Taille optimisée de ce classeur en octets " & Chr(10) _
  & FileLen(ActiveWorkbook.FullName), vbInformation, ActiveWorkbook.FullNameActive
[COLOR=GREEN]'--------------------[/COLOR]
Application.StatusBar = [COLOR=BLUE]False[/COLOR]
Application.Calculation = Calc
[COLOR=BLUE]End Sub[/COLOR]
Code colorisé par Un peu de couleurs dans nos posts

A+ à tous
 
Dernière édition:

philppe27

XLDnaute Occasionnel
Re : problème NettoyageClasseur.xls

Bonjour JCGL,

J'ai mis comme demandé ton code dans les fichiers de Bruno et le fichier nettoyé est bien celui qui contient le code de nettoyage ce qui est donc conforme à ce que j'attends. Je vais refaire le test avec mes fichiers et reviendrait sur le forum si j'ai encore le problème.

Merci beaucoup cordialement
 

philppe27

XLDnaute Occasionnel
Re : problème NettoyageClasseur.xls

Bon voilà j'y vois plus clair,

le code en cause est un code rajouté par rapport au code initial :
' Si la feuille est masquée
MemVisible = Sht.Visible
If Sht.Visible <> xlSheetVisible Then Sht.Visible = xlSheetVisible
'si la feuille est protégée
Sht.Unprotect Password:="secret" 'déprotéger la feuille

qui se justifie parce que j'ai des feuilles masquées et protégées.
Lorsque j'utilise une macro sur un autre classeur pour fermer le fichier qui nettoie le code ci-dessus ne fonctionne pas et je ne vois pas apparaitre les feuilles masquées lors du nettoyage.

Merci d'avance pour vos réponses

Cordialement


Sub Nettoie()
Dim Sht As Worksheet, DCell As Range, Calc As Long, Rien As String
Dim Av As Double, Plage As Range
On Error Resume Next
Calc = Application.Calculation
'------------------------------------------------------------
MsgBox "Pour le classeur actif : " & ActiveWorkbook.FullName _
& Chr(10) & "Dans chaque feuille de calcul" _
& Chr(10) & "Recherche la zone contenant des données," _
& Chr(10) & "Réinitialise la dernière cellule utilisée" _
& Chr(10) & "Optimise la taille du fichier Excel", vbInformation, "d'après LL et GeeDee"
'-------------------------------------------------------------
MsgBox "Taille initiale de ce classeur en octets" _
& Chr(10) & FileLen(ActiveWorkbook.FullName), vbInformation, ActiveWorkbook.FullName
'------------------------------------------------------------
With Application
.Calculation = xlCalculationManual
.StatusBar = "Nettoyage en cours..."
.EnableCancelKey = xlErrorHandler
.ScreenUpdating = True
End With
'-------------------- le traitement
For Each Sht In Worksheets
' Si la feuille est masquée
MemVisible = Sht.Visible
If Sht.Visible <> xlSheetVisible Then Sht.Visible = xlSheetVisible
'si la feuille est protégée
Sht.Unprotect Password:="secret" 'déprotéger la feuille
Av = Sht.UsedRange.Cells.Count
Application.StatusBar = Sht.Name & "-" & Sht.UsedRange.Address
'-------------------Traitement de la zone trouvée
If Sht.UsedRange.Address <> "$A$1" Or Not IsEmpty(Sht.[A1]) Then
Set DCell = Sht.Cells.Find("*", , , , xlByRows, xlPrevious)(2)
'----------------Suppression des lignes inutilisées
If Not DCell Is Nothing Then
Sht.Range(DCell, Sht.Cells([A:A].Count, 1)).EntireRow.Delete
Set DCell = Nothing
Set DCell = Sht.Cells.Find("*", , , , xlByColumns, xlPrevious)(, 2)
'----------------Suppression des colonnes inutilisées
If Not DCell Is Nothing Then Sht.Range(DCell, Sht.[IV1]).EntireColumn.Delete
End If
Rien = Sht.UsedRange.Address
End If
'ActiveWorkbook.Save
'---------------------Message pour la feuille traitée
MsgBox "Nom de la feuille de calcul : " & Sht.Name _
& Chr(10) & Format(Sht.UsedRange.Cells.Count / Av, "0.00%") _
& " de la taille initiale", vbInformation, ActiveWorkbook.FullName
Sht.Protect Password:="secret", DrawingObjects:=True, Contents:=True, Scenarios:=True 'protéger la feuille
Sht.Visible = MemVisible
Next Sht
'--------------------Message fin de traitement
Sht.Unprotect Password:="secret" 'déprotéger la feuille
MsgBox "Taille optimisée de ce classeur en octets " & Chr(10) _
& FileLen(ActiveWorkbook.FullName), vbInformation, ActiveWorkbook.FullNameActive
'--------------------
Application.StatusBar = False
Application.Calculation = Calc
Sht.Protect Password:="secret", DrawingObjects:=True, Contents:=True, Scenarios:=True 'protéger la feuille

End Sub
 

philppe27

XLDnaute Occasionnel
Re : problème NettoyageClasseur.xls

Ci-joint 2 fichiers pour tester l'anomalie:
- fermeture lancé du fichier à nettoyer les feuilles masquées sont nettoyées
- fermeture lancé d'un autre fichier les feuilles masquées n'apparaissent pas dans le traitement de la macro et elles ne sont pas nettoyées

Merci de votre aide
 

Pièces jointes

  • Classeur2Test.zip
    23.2 KB · Affichages: 26
  • Classeur2Test.zip
    23.2 KB · Affichages: 26
  • Classeur2Test.zip
    23.2 KB · Affichages: 27

JCGL

XLDnaute Barbatruc
Re : problème NettoyageClasseur.xls

Bonjour à tous,

Si je relis depuis le début de la discussion, je mettrais dans Classeur1Nettoyage.xls en ThisWorkBook :

Code:
Option Explicit

Private Sub Workbook_BeforeClose(Cancel As Boolean)
    Call Nettoie
End Sub

A+ à tous
 

philppe27

XLDnaute Occasionnel
Re : problème NettoyageClasseur.xls

Désolé JCGL mais les onglets b et c n'apparaissent lors du déroulement de la macro nettoie en lançant la fermeture à partir de classeur2Test.
Par contre tout est correct en fermant à partir de classeur1Nettoyage
Je ne vois pas d'où cela peut venir ?
 

JCGL

XLDnaute Barbatruc
Re : problème NettoyageClasseur.xls

Bonjour à tous,

Je ne peux pas te dire pourquoi cela ne fonctionne pas à partir de ton autre fichier.

J'ai, presque, le même code est cela fonctionne chez moi (lorsque j'ai un fichier à "nettoyer", je lance mon fichier "nettoyeur" qui ouvre l'explorateur pour le choix du fichier).

A+ à tous
 

philppe27

XLDnaute Occasionnel
Re : problème NettoyageClasseur.xls

Bonjour à tous,

Je ne peux pas te dire pourquoi cela ne fonctionne pas à partir de ton autre fichier.

J'ai, presque, le même code est cela fonctionne chez moi (lorsque j'ai un fichier à "nettoyer", je lance mon fichier "nettoyeur" qui ouvre l'explorateur pour le choix du fichier).

A+ à tous

Je ne sais pas si je comprends bien ta dernière phrase. Je pense que tu préconises d'avoir un fichier qui nettoie en batterie les fichiers figurant dans un répertoire par exemple.
En ce qui me concerne pour réduire les temps d'ouverture et de fermeture de fichier Workbook before close est l'idéal. C'est d'autant plus rageant que avec Workbook open ça fonctionne très bien. Je pourrais contourner peut-être le problème en ouvrant les feuilles à partir du fichier qui pilote la fermeture des autres fichiers. Dans ce cas, il faudrait que je conserve la situation des feuilles avant leur ouverture dans les fichiers qui sont nettoyés. Compliqué pour pas grand chose ....
 
G

Guest

Guest
Re : problème NettoyageClasseur.xls

Bonsoir Philippe,

Hello JC:):)

Philippe.

C'est normal dans le cas des deux fichiers fournis plus haut (Post #8)
Quant tu ouvres un classeur par Open, il devient le classeur actif
Si tu actives un autre classeur et que tu invoques la méthode Close du classeur que tu as précédement ouvert, celui-ci devient le classeur actif. Et la macro Nettoie travail sur le classeur actif.

Dans ton fichier 'Classeur2Test.xls' tu dois écrire ta macro comme ci-dessous.

Code:
Sub Test()
'Après son ouverture, il devient le classeur actif 
 Application.Workbooks.Open ThisWorkbook.Path & "\Classeur1nettoyage.xls"
 'Activer le classeur qui contient cette macro
  ThisWorkbook.Activate
'Lancer la macro Nettoie par la méthode run pour que ce classeur reste actif
   Application.Run "Classeur1nettoyage.xls!Nettoie"
 
'Fermer l'autre éventuellement 
'mais sa macro Before_Close sera exécutée donc la macro 'Nettoie' aussi sur lui-même)
Workbooks("Classeur1nettoyage.xls").Close
End Sub

A+
 

Discussions similaires

Membres actuellement en ligne

Aucun membre en ligne actuellement.

Statistiques des forums

Discussions
312 105
Messages
2 085 350
Membres
102 870
dernier inscrit
Armisa