Accélération d'une macros

Fermé
Gérard - Modifié par pijaku le 17/01/2014 à 11:39
gbinforme Messages postés 14946 Date d'inscription lundi 18 octobre 2004 Statut Contributeur Dernière intervention 24 juin 2020 - 20 janv. 2014 à 22:31
Bonjour, j'aimerais savoir si quelqu'un peu m'indiquer pourquoi ma macros prend une heure à se compléter (308 000 lignes). Y a-t-il un moyen de la modifier pour cela?

Sub pre_traitement_donnees()
Application.ScreenUpdating = False

    Columns("D:D").Select
    Selection.Insert Shift:=xlToRight, CopyOrigin:=xlFormatFromLeftOrAbove
    Range("D1").Select
    ActiveCell.FormulaR1C1 = "=IF(RC[-1]=0,2400,RC[-1])"
    Range("D1").Select
    Selection.AutoFill Destination:=Range("D:D")

    Range("D:D").Select
    Selection.Copy
    Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
        :=False, Transpose:=False
    Columns("C:C").Select
    Application.CutCopyMode = False
    Selection.Delete Shift:=xlToLeft
    
    Sheets("Base").Select

 
    Sheets.Add After:=Sheets(Sheets.Count)
    Sheets("Feuil1").Select
    Sheets("Feuil1").Name = "102"
    Sheets.Add After:=Sheets(Sheets.Count)
    Sheets("Feuil2").Select
    Sheets("Feuil2").Name = "115"
    Sheets.Add After:=Sheets(Sheets.Count)
    Sheets("Feuil3").Name = "140"
    Sheets.Add After:=Sheets(Sheets.Count)
    Sheets("Feuil4").Name = "160"
   

Sheets("Base").Select

  Dim LR As Long, i As Long
LR = Range("A" & Rows.Count).End(xlUp).Row
For i = 2 To LR
    If Range("A" & i).Value = "102" Then Rows(i).Copy Destination:=Sheets("102").Range("A" & Rows.Count).End(xlUp).Offset(1)
Next i
For i = 2 To LR
    If Range("A" & i).Value = "115" Then Rows(i).Copy Destination:=Sheets("115").Range("A" & Rows.Count).End(xlUp).Offset(1)
Next i
For i = 2 To LR
    If Range("A" & i).Value = "140" Then Rows(i).Copy Destination:=Sheets("140").Range("A" & Rows.Count).End(xlUp).Offset(1)
Next i

For i = 2 To LR
    If Range("A" & i).Value = "160" Then Rows(i).Copy Destination:=Sheets("160").Range("A" & Rows.Count).End(xlUp).Offset(1)
Next i
End Sub
A voir également:

3 réponses

michel_m Messages postés 16603 Date d'inscription lundi 12 septembre 2005 Statut Contributeur Dernière intervention 16 décembre 2023 3 310
17 janv. 2014 à 08:34
Bonjour,

Effectivement, à part le screenupdating, il y a tout pour ralentir la procédure; select-selection, copy-paste....

Pour être concret car il y a rien de + risqué de modifier un code sans le tester,

mettre UN EXTRAIT (3000 lignes maxi) du classeur sans données confidentielles en pièce jointe sur
https://www.cjoint.com/
puis copier l'adresse du lien et la coller dans le message de réponse

Dans cette attente
0
michel_m Messages postés 16603 Date d'inscription lundi 12 septembre 2005 Statut Contributeur Dernière intervention 16 décembre 2023 3 310
Modifié par michel_m le 17/01/2014 à 12:27
En attendant "le" classeur

combien de colonnes maxi dans la feuilles "base" ?

macro partielle jusqu'à la construction de nouvelles feuilles

Option Explicit
Sub pretraitement_ccm()
Dim Derlig As Long, Col_c(), Cptr As Long

Application.ScreenUpdating = False

'------- -------Traitement colonne_C
With ActiveSheet
Derlig = .Range("C" & Rows.Count).End(xlUp).Row
'mémorisation colonne C en RAM
Col_c = Application.Transpose(.Range("C1:C" & Derlig).Value)
For Cptr = 1 To UBound(Col_c)
Col_c(Cptr) = IIf(Col_c(Cptr) = 0, 2400, Col_c(Cptr))
Next
'restitution calculée
.Range("C1").Resize(UBound(Col_c), 1) = Application.Transpose(Col_c)
End With

'-------------Ajout 4 feuilles
ajouter_feuille 102
ajouter_feuille 115
ajouter_feuille 140
ajouter_feuille 160

End Sub

'######################
Sub ajouter_feuille(onglet)
Sheets.Add After:=Sheets(Sheets.Count)
ActiveSheet.Name = onglet
End Sub


Si pas de signe de vie jusqu'à samedi midi, abandon du suivi
0
Bonjour, merci de la réponse. En réalité, la partie qui pose problème est la fin, soit :
Sheets("Base").Select

Dim LR As Long, i As Long
LR = Range("A" & Rows.Count).End(xlUp).Row
For i = 2 To LR
If Range("A" & i).Value = "102" Then Rows(i).Copy Destination:=Sheets("102").Range("A" & Rows.Count).End(xlUp).Offset(1)
Next i
For i = 2 To LR
If Range("A" & i).Value = "115" Then Rows(i).Copy Destination:=Sheets("115").Range("A" & Rows.Count).End(xlUp).Offset(1)
Next i
For i = 2 To LR
If Range("A" & i).Value = "140" Then Rows(i).Copy Destination:=Sheets("140").Range("A" & Rows.Count).End(xlUp).Offset(1)
Next i

For i = 2 To LR
If Range("A" & i).Value = "160" Then Rows(i).Copy Destination:=Sheets("160").Range("A" & Rows.Count).End(xlUp).Offset(1)
Next i
End Sub

le reste s'exécute en une fraction de seconde. L'objectif est de séparer les lignes selon le code qui leur est attribué dans la colonne A, soit 102, 115, 140 ou 160 et de les coller sur la feuille précédemment créée et qui possède le même code.

Désolé pour la réponse tardive, nous ne sommes vraiment pas sur le même fuseau horaire (Québec).
0
michel_m Messages postés 16603 Date d'inscription lundi 12 septembre 2005 Statut Contributeur Dernière intervention 16 décembre 2023 3 310
Modifié par michel_m le 18/01/2014 à 08:05
Bonjour,
Désolé pour la réponse tardive, nous ne sommes vraiment pas sur le même fuseau horaire (Québec).
D'accord c'est noté

pour la 2° partie, je ne l'avais pas encore attaquée, notamment en attente des réponses à mes demandes; et de m^me je me demande pourquoi tu as fait un copier-coller de ton 1° envoi: peut-être que je ne sais pas lire

le reste s'exécute en une fraction de seconde. Merci, très sympa de ta part: garde ta macro , je me suis cassé la t^te pour me faire envoyer paitre :-((

. L'objectif est de séparer les lignes selon le code qui leur est attribué dans la colonne A, soit 102, 115, 140 ou 160 et de les coller sur la feuille précédemment créée et qui possède le même code.
Merci, j'avais compris sinon je t'aurais demandé des explications


d'autre part je t'avais fait des demandes auxquelles tu n'as pas répondu:

1° lien 17/1 8:34
mettre UN EXTRAIT (3000 lignes maxi) du classeur sans données confidentielles en pièce jointe sur
https://www.cjoint.com/
puis copier l'adresse du lien et la coller dans le message de réponse

2° lien 17/1 12:22
combien de colonnes maxi dans la feuilles "base" ?


Et pendant que j'y suis:
la colonne A de la feuille "base" ne comporte t' elle que les 4 numéros 102, 115, 140, 160 ?

Libre à toi de me répondre, j'attends donc que tu daignes le faire
0
michel_m Messages postés 16603 Date d'inscription lundi 12 septembre 2005 Statut Contributeur Dernière intervention 16 décembre 2023 3 310
19 janv. 2014 à 07:59
Pas de réponse: abandon du suivi sans regrets
0
gbinforme Messages postés 14946 Date d'inscription lundi 18 octobre 2004 Statut Contributeur Dernière intervention 24 juin 2020 4 709
20 janv. 2014 à 11:11
Bonjour Gérard, Michel,

Comme le soleil s'est un peu mis en grève autant profiter de l'écran. ;-)
J'ai donc regardé ce que tu voulais faire avec ta macro et je te propose ce code.
Sub speed_pre_traitement_donnees()
Dim col As Integer, LR As Long, f As Integer, deb As Date
Dim nom(), tbd(), tbf(), n As Integer, idd As Long, idf As Long
    nom = Array(102, 115, 140, 160)     ' table sélection
    deb = Time
    Application.ScreenUpdating = False
    With Sheets("Base")
        col = .UsedRange.Columns.Count  ' nombre colones
        LR = .UsedRange.Rows.Count      ' nombre lignes
        tbd = .Cells(1, 1).Resize(LR, col).Value    ' base en table
        For n = 0 To 3                  ' ventilation sur feuilles
            Sheets.Add After:=Sheets(Sheets.Count)
            ActiveSheet.Name = nom(n)   ' nouvelle feuille
            idf = 1
            ReDim tbf(1 To UBound(tbd), 1 To col)
            For f = 1 To col            ' copie titre
                tbf(idf, f) = tbd(1, f)
            Next f
            For idd = 1 To UBound(tbd)  ' copie données
                If tbd(idd, 3) = 0 Then tbd(idd, 3) = 2400
                If tbd(idd, 1) = nom(n) Then
                    idf = idf + 1
                    For f = 1 To col    ' ligne sélectionnée
                        tbf(idf, f) = tbd(idd, f)
                    Next f
                End If
            Next idd                    ' table sur feuille
            Cells(1, 1).Resize(UBound(tbf, 1), UBound(tbf, 2)).Value = tbf
        Next n                          ' table base sur feuille
        .Cells(1, 1).Resize(UBound(tbd, 1), UBound(tbd, 2)).Value = tbd
    End With
    MsgBox "Début_: " & deb & vbLf & "Fin____: " & Time
    Sheets("Base").Activate
    Application.ScreenUpdating = True
End Sub

Pour traiter rapidement ce type de procédure, il vaut mieux éviter de fonctionner sur les feuilles car les adressages sont gourmands en calculs. La macro te fourni le temps d'exécution qui devrait descendre sous la minute.

Bon test
0
michel_m Messages postés 16603 Date d'inscription lundi 12 septembre 2005 Statut Contributeur Dernière intervention 16 décembre 2023 3 310
20 janv. 2014 à 11:59
très sympa...
0
Merci à vous pour vos réponses, ça va beaucoup mieux grâce à vous.
0
gbinforme Messages postés 14946 Date d'inscription lundi 18 octobre 2004 Statut Contributeur Dernière intervention 24 juin 2020 4 709
20 janv. 2014 à 22:31
Bonjour,

Cyrano de Bergerac : Ah ! non ! c'est un peu court, jeune homme !
On pouvait dire... Oh ! Dieu !... bien des choses en somme
.

Pour tous ceux qui vont lire ce poste tu aurais pu "dire... bien des choses" afin que l'on puisse comprendre en quoi nos réponses t'ont aidé ou perturbé, si ton souci de durée c'était amélioré et comment, etc ...
Merci de le faire pour donner une solution à ta question.
0