Lenteur d'une macro
Bonjour à tous !
Lorsque j'exécute une macro qui modifie pas mal la feuille de départ, le temps d'exécution est assez long.
Mais si je sors l'onglet de mon fichier (qui a plusieurs onglets, d'autres macros, des formules...), la macro s'exécute très rapidement !
Pourtant, la macro ne concerne que cette feuille, il n'y a aucun lien avec d'autres feuilles ou formules.
Le seul lien serait que le bouton se trouve sur une autre feuille.
J'ai essayé d'accélérer la macro avec deux-trois codes que j'ai trouvé (actualisation de l'écran, calculs automatiques...) mais rien n'y fait !
Quelqu'un aurait-il une piste ?
Merci beaucoup !
Bonjour,
Mets la macro (avec balises Code STP !).
Bonjour,
Voilà la macro !
Je suis loin d'être un pro de VBA donc y a sûrement des trucs pas très nets... !
Sub traitement()
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
'défusionner
Sheets("OCCUPATION").Cells.UnMerge
'supprimer l'en-tete
Sheets("OCCUPATION").Activate
Rows("1:8").Select
Selection.EntireRow.Delete
'supprimer les colonnes vides
Dim c
For c = 256 To 1 Step -1
If Cells(65536, c).End(xlUp).Row = 1 Then Cells(1, c).EntireColumn.Delete
Next c
'deplacer le titre
Range("B1").Select
Selection.Cut
Range("B4").Select
ActiveSheet.Paste
'supprimer l'en-tete
Sheets("OCCUPATION").Activate
Rows("1:3").Select
Selection.EntireRow.Delete
'supprimer derniere ligne
With ActiveSheet.UsedRange
ActiveSheet.Rows(.Row + .Rows.Count - 1).Delete
End With
'supprimer les cellules vides en colonne A
Dim Ligne As Long
For Ligne = Range("A65535").End(3).Row To 2 Step -1
If IsEmpty(Cells(Ligne, 1)) Then Cells(Ligne, 1).Delete
Next Ligne
'supprimer les cellules vides en colonne B
Application.ScreenUpdating = False
Dim i As Long
For i = 2 To Range("B65536").End(xlUp).Row
If Cells(i, 2).Value Like "" Then Range(Cells(i, 2), Cells(i, 50)).Delete Shift:=xlUp
Next i
'supprimer les cellules differentes de "Total" en colonne B
Application.ScreenUpdating = False
For i = 2 To Range("B65536").End(xlUp).Row
If Not Cells(i, 2).Value Like "Total" Then Range(Cells(i, 2), Cells(i, 50)).Delete Shift:=xlUp
Next i
Application.ScreenUpdating = False
For i = 2 To Range("B65536").End(xlUp).Row
If Not Cells(i, 2).Value Like "Total" Then Range(Cells(i, 2), Cells(i, 50)).Delete Shift:=xlUp
Next i
'déplacer le titre
Range("A1").Select
ActiveCell.FormulaR1C1 = "=RIGHT(RC[1],27)"
Range("A2").Select
Range("A1").Select
Selection.Copy
Selection.PasteSpecial Paste:=xlValues, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=False
Application.CutCopyMode = False
Range("B1").Select
Selection.ClearContents
'supprimer derniere colonne et colonne B
Columns("B:B").Delete
With ActiveSheet.UsedRange
ActiveSheet.Columns(.Column + .Columns.Count - 1).Delete
End With
'traitement dates
Rows("1:1").Select
Selection.Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
Range("B1").Select
debutcolonne = 2
fincolonne = Sheets("OCCUPATION").UsedRange.Columns.Count + 1
While debutcolonne < fincolonne
Cells(1, debutcolonne).FormulaR1C1 = "=DATE(RIGHT(R2C1,4),MID(R2C1,7,2),R[1]C)"
debutcolonne = debutcolonne + 1
Wend
'supprimer ligne ancienne date
Rows("1:1").Select
Selection.Copy
Selection.PasteSpecial Paste:=xlValues, Operation:=xlNone, SkipBlanks:= _
False, Transpose:=False
Application.CutCopyMode = False
Rows("2:2").Select
Selection.Delete Shift:=xlUp
'calcul total par jour
finligne = Sheets("OCCUPATION").Range("A" & Sheets("OCCUPATION").Rows.Count).End(xlUp).Row + 1
Rows(finligne & ":" & 30).Select
Selection.Delete
Range("A" & finligne).FormulaR1C1 = "Total"
debutcolonne = 2
finligne = Sheets("OCCUPATION").UsedRange.Rows.Count
fincolonne = Sheets("OCCUPATION").UsedRange.Columns.Count
For col = 2 To fincolonne
Cells(finligne, col) = Application.WorksheetFunction.Sum(Worksheets("OCCUPATION").Range(Cells(2, col), Cells(finligne - 1, col)))
Next
'ajuster la largeur des colonnes
Cells.Select
Cells.EntireColumn.AutoFit
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
End SubÇa tient du gag ! Tu commences par supprimer 2 fois l'en-tête....
Qu'est-ce que tu ne supprimes pas ?
Bon ! On supprime l'en-tête, on déplace le titre (lequel ?), on resupprime, on redéplace, on rere...
C'est un fouillis inextricable !
Il faut un modèle de la feuille : situation de départ et mettre ce qui doit rester à l'arrivée, qu'on puisse définir une manière simple de passer de l'une à l'autre.
Je sais que c'est du bidouillage... merci pour le coup de main !
Je joins les deux fichiers : "départ" pour le fichier initial et "arrivée" pour le format idéal après macro !
A votre dispo pour toute explication, évidemment
Merci d'avance !
C'est déjà plus clair !
On va essayer une méthode inverse !
Je vois ça après manger !
Je passe en cuisine !!
Super merci beaucoup !!
Première ébauche ! Il faudrait ajouter pas mal de contrôles de validité mais je n'ai pas jugé utile pour l'instant, avant de savoir si la structure des feuilles que tu traites ainsi est stable ou subit des variations possibles...
Je ne peux garantir que ça va fonctionner dans tous les cas : vu la composition de la feuille, la mise au point a déjà présenté quelques difficultés sur quelques points délicats, et de légères variations de structure pourraient entraîner des résultats surprenants.
Il faudra donc cerner les variations possibles pour intégrer leur prise en compte dans la procédure (ou leur contournement)...
La méthode, si elle s'avère utilisable dans les cas où elle doit l'être, en ne faisant que prélever les données recherchées sur la feuille, sans y intervenir autrement, se révèlera nettement plus rapide...
Le code (je te mettrai des commentaires de repérage ultérieurement si tu le souhaites) :
Sub Test()
Dim TR(), kRub, kTot, kTit, kJ, xClu, k%, i%, j%, h%, n%
xClu = Split("code* nom* marq* devi*")
With Worksheets("Feuille1").UsedRange
Do While k <= .Columns.Count
k = k + 1
For i = 1 To .Rows.Count
If .Cells(i, k) <> "" Then
If IsNumeric(.Cells(i, k)) Then
If kJ = "" Then kJ = i & ";" & k: h = h + 1
Exit For
ElseIf LCase(.Cells(i, k)) = "total" Then
If kTot = "" Then kTot = i & ";" & k: h = h + 1
Exit For
Else
For j = 0 To UBound(xClu)
If LCase(.Cells(i, k)) Like xClu(j) Then Exit For
Next j
If j > UBound(xClu) Then
If IsNumeric(Right(.Cells(i, k), 4)) Then
If kTit = "" Then kTit = i & ";" & k: h = h + 1
Else
If kRub = "" Then kRub = i & ";" & k: h = h + 1
Exit For
End If
End If
End If
End If
Next i
If h = 4 Then Exit Do
Loop
If h < 4 Then
MsgBox "Toutes les informations n'ont pu être recueillies.", vbCritical, _
"Echec de la procédure !": Exit Sub
End If
xClu = Split(kRub, ";"): j = CInt(xClu(0)): k = CInt(xClu(1)): kRub = ""
For i = j To .Rows.Count
If .Cells(i, k) <> "" Then kRub = kRub & ";" & .Cells(i, k): n = i
Next i
xClu = Split(kTot, ";"): j = CInt(xClu(0)): k = CInt(xClu(1)): kTot = ""
For i = j To .Rows.Count
If LCase(.Cells(i, k)) = "total" Then kTot = kTot & ";" & i
Next i
kTot = kTot & ";" & n: n = 0
xClu = Split(kTit, ";"): kTit = .Cells(CInt(xClu(0)), CInt(xClu(1))): xClu = Split(kTit)
kTit = CDate(xClu(UBound(xClu))): kTit = DateSerial(Year(kTit), Month(kTit), 1) - 1
xClu = Split(kJ, ";"): j = CInt(xClu(0)): k = CInt(xClu(1)): h = 0
For i = k To .Columns.Count
If .Cells(j, i) <> "" And IsNumeric(.Cells(j, i)) Then h = h + 1
Next i
kRub = Split(kRub, ";"): ReDim TR(UBound(kRub), h): kTot = Split(kTot, ";")
For i = 1 To UBound(kRub)
TR(i, 0) = kRub(i)
Next i
For i = k To .Columns.Count
If .Cells(j, i) <> "" And IsNumeric(.Cells(j, i)) Then
n = n + 1: TR(0, n) = kTit + CInt(.Cells(j, i))
For h = 1 To UBound(kRub)
TR(h, n) = .Cells(CInt(kTot(h)), i)
Next h
End If
Next i
End With
j = UBound(TR, 1)
For i = 1 To UBound(TR, 2)
h = InStr(1, TR(j, i), Chr(10))
If h > 0 Then TR(j, i) = Left(TR(j, i), h - 1)
Next i
Application.ScreenUpdating = False
With Worksheets.Add(after:=Worksheets("Feuille1"))
With .Range("A1").Resize(UBound(TR, 1) + 1, UBound(TR, 2) + 1)
.Value = TR
.Columns(1).ColumnWidth = 16
With .Offset(1).Resize(UBound(TR, 1) - 1).Borders
.LineStyle = xlContinuous: Weight = xlThin
End With
With .Rows(UBound(TR, 1) + 1)
.HorizontalAlignment = xlCenter: .Font.Bold = True
End With
.Offset(, 1).Resize(UBound(TR, 1), UBound(TR, 2)).HorizontalAlignment = xlCenter
End With
End With
End SubPour la tester, la lancer à partir de la boîte de dialogue macro. Je n'ai pas mis de bouton, ne sachant comment elle sera intégrée dans le contexte de travail.
En cas d'essais sur d'autres feuilles du même type, me prévenir des problèmes éventuels, et surtout des anomalies dont il faudra cerner la source en comparant avec la structure de la feuille à partir de laquelle la proc. a été établie.
Cordialement.