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 !

7arrivee.xlsx (24.82 Ko)
6depart.zip (12.99 Ko)

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 Sub

Pour 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.

14julienbr-depart.zip (21.80 Ko)
Rechercher des sujets similaires à "lenteur macro"