IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Macros et VBA Excel Discussion :

Correction "procédure trop longue"


Sujet :

Macros et VBA Excel

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Octobre 2010
    Messages
    47
    Détails du profil
    Informations forums :
    Inscription : Octobre 2010
    Messages : 47
    Par défaut Correction "procédure trop longue"
    Bonjour à tous,

    J'ai une erreur "procédure trop longue".
    Je soupçonne que c'est parce que mon code est beaucoup trop long.

    Voici le début du code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
     
    If MaFsource.Cells(77, Col).Value = "" Then
                ShDEST.Range("B2").Value = IIf(Len(MaFsource.Cells(79, Col).Value) = 0, "", (MaFsource.Cells(79, Col).Value))
                ShDEST.Range("B2").Value = ShDEST.Range("B2").Value & IIf(Len(MaFsource.Cells(80, Col).Value) = 0, "", vbLf & MaFsource.Cells(80, Col).Value)
                ShDEST.Range("B2").Value = ShDEST.Range("B2").Value & IIf(Len(MaFsource.Cells(81, Col).Value) = 0, "", vbLf & MaFsource.Cells(81, Col).Value)
                If MaFsource.Cells(79, Col).Value = "" And MaFsource.Cells(80, Col).Value = "" And MaFsource.Cells(81, Col).Value = "" Then ShDEST.Range("B2").Value = "Aucune activité inscrite"
            End If
            If MaFsource.Cells(77, Col).Value <> "" Then
            ShDEST.Range("B2").Value = MaFsource.Cells(77, Col).Value
            End If
     
             If MaFsource.Cells(82, Col).Value = "" Then
                ShDEST.Range("D2").Value = IIf(Len(MaFsource.Cells(84, Col).Value) = 0, "", (MaFsource.Cells(84, Col).Value))
                ShDEST.Range("D2").Value = ShDEST.Range("D2").Value & IIf(Len(MaFsource.Cells(85, Col).Value) = 0, "", vbLf & MaFsource.Cells(85, Col).Value)
                ShDEST.Range("D2").Value = ShDEST.Range("D2").Value & IIf(Len(MaFsource.Cells(86, Col).Value) = 0, "", vbLf & MaFsource.Cells(86, Col).Value)
                If MaFsource.Cells(79, Col).Value = "" And MaFsource.Cells(80, Col).Value = "" And MaFsource.Cells(81, Col).Value = "" Then ShDEST.Range("D2").Value = "Aucune activité inscrite"
           End If
           If MaFsource.Cells(82, Col).Value <> "" Then
            ShDEST.Range("D3").Value = MaFsource.Cells(92, Col).Value
            End If
     
           If MaFsource.Cells(87, Col).Value = "" Then
                ShDEST.Range("B3").Value = IIf(Len(MaFsource.Cells(89, Col).Value) = 0, "", (MaFsource.Cells(89, Col).Value))
                ShDEST.Range("B3").Value = ShDEST.Range("B3").Value & IIf(Len(MaFsource.Cells(90, Col).Value) = 0, "", vbLf & MaFsource.Cells(90, Col).Value)
                ShDEST.Range("B3").Value = ShDEST.Range("B3").Value & IIf(Len(MaFsource.Cells(91, Col).Value) = 0, "", vbLf & MaFsource.Cells(91, Col).Value)
                If MaFsource.Cells(89, Col).Value = "" And MaFsource.Cells(90, Col).Value = "" And MaFsource.Cells(91, Col).Value = "" Then ShDEST.Range("B3").Value = "Aucune activité inscrite"
            End If
            If MaFsource.Cells(87, Col).Value <> "" Then
            ShDEST.Range("B3").Value = MaFsource.Cells(87, Col).Value
            End If
     
             If MaFsource.Cells(92, Col).Value = "" Then
                ShDEST.Range("D3").Value = IIf(Len(MaFsource.Cells(94, Col).Value) = 0, "", (MaFsource.Cells(94, Col).Value))
                ShDEST.Range("D3").Value = ShDEST.Range("D3").Value & IIf(Len(MaFsource.Cells(95, Col).Value) = 0, "", vbLf & MaFsource.Cells(95, Col).Value)
                ShDEST.Range("D3").Value = ShDEST.Range("D3").Value & IIf(Len(MaFsource.Cells(96, Col).Value) = 0, "", vbLf & MaFsource.Cells(96, Col).Value)
                If MaFsource.Cells(94, Col).Value = "" And MaFsource.Cells(95, Col).Value = "" And MaFsource.Cells(96, Col).Value = "" Then ShDEST.Range("D3").Value = "Aucune activité inscrite"
           End If
           If MaFsource.Cells(92, Col).Value <> "" Then
            ShDEST.Range("D3").Value = MaFsource.Cells(92, Col).Value
            End If
    Voici la fin du code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
     
    If MaFsource.Cells(357, Col).Value = "" Then
                ShDEST.Range("B30").Value = IIf(Len(MaFsource.Cells(359, Col).Value) = 0, "", (MaFsource.Cells(359, Col).Value))
                ShDEST.Range("B30").Value = ShDEST.Range("B30").Value & IIf(Len(MaFsource.Cells(360, Col).Value) = 0, "", vbLf & MaFsource.Cells(360, Col).Value)
                ShDEST.Range("B30").Value = ShDEST.Range("B30").Value & IIf(Len(MaFsource.Cells(361, Col).Value) = 0, "", vbLf & MaFsource.Cells(361, Col).Value)
                If MaFsource.Cells(359, Col).Value = "" And MaFsource.Cells(360, Col).Value = "" And MaFsource.Cells(361, Col).Value = "" Then ShDEST.Range("B30").Value = "Aucune activité inscrite"
            End If
            If MaFsource.Cells(357, Col).Value <> "" Then
            ShDEST.Range("B30").Value = MaFsource.Cells(357, Col).Value
            End If
     
            If MaFsource.Cells(362, Col).Value = "" Then
                ShDEST.Range("D30").Value = IIf(Len(MaFsource.Cells(364, Col).Value) = 0, "", (MaFsource.Cells(364, Col).Value))
                ShDEST.Range("D30").Value = ShDEST.Range("D30").Value & IIf(Len(MaFsource.Cells(365, Col).Value) = 0, "", vbLf & MaFsource.Cells(365, Col).Value)
                ShDEST.Range("D30").Value = ShDEST.Range("D30").Value & IIf(Len(MaFsource.Cells(366, Col).Value) = 0, "", vbLf & MaFsource.Cells(366, Col).Value)
                If MaFsource.Cells(364, Col).Value = "" And MaFsource.Cells(365, Col).Value = "" And MaFsource.Cells(366, Col).Value = "" Then ShDEST.Range("D30").Value = "Aucune activité inscrite"
           End If
           If MaFsource.Cells(357, Col).Value <> "" Then
            ShDEST.Range("D30").Value = MaFsource.Cells(357, Col).Value
            End If
    Quelques explications :
    j'ai des blocs de données qui se présentent toujours de la même façon :
    On commence à la ligne 77
    Le premier bloc va de la ligne 77 à la ligne 81
    Le second bloc va de la ligne 82 à la ligne 86
    Le troisième bloc va de la ligne 87 à la ligne 91
    Le quatrième bloc va de la ligne 92 à la ligne 96
    et ainsi de suite...
    Les blocs de données commencent toujours en alternance par un numéro de ligne paire ou impaire et ils sont constitués de 5 lignes dans lesquelles je prélèves les données pour les placer sur une autre feuille.

    Je suppose que l'on peut faire beaucoup mieux que ce que j'ai écrit... mais je ne suis vraiment pas un spécialiste des macros alors votre aide sera plus que bienvenue.

  2. #2
    Expert éminent Avatar de Menhir
    Homme Profil pro
    Ingénieur
    Inscrit en
    Juin 2007
    Messages
    16 037
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2007
    Messages : 16 037
    Par défaut
    Citation Envoyé par fb62840 Voir le message
    J'ai une erreur "procédure trop longue".
    Je soupçonne que c'est parce que mon code est beaucoup trop long.
    Si par "trop long" tu veux dire "trop de lignes", c'est tout à fait improbable.
    Si tu avais plusieurs milliers de lignes de code, on aurait pu se poser la question, mais quelques dizaines, ça ne risque pas de faire peur à VBA.

  3. #3
    Membre averti
    Inscrit en
    Octobre 2010
    Messages
    47
    Détails du profil
    Informations forums :
    Inscription : Octobre 2010
    Messages : 47
    Par défaut
    Citation Envoyé par Menhir Voir le message
    Si par "trop long" tu veux dire "trop de lignes", c'est tout à fait improbable.
    Si tu avais plusieurs milliers de lignes de code, on aurait pu se poser la question, mais quelques dizaines, ça ne risque pas de faire peur à VBA.
    Je ne comprends pas, en testant le code, tout se passe bien jusqu'à un certain point Tout se passe bien mais sur la portion que j'ai porté en "commentaires" si j'enlève les ' des commentaires le code bloque et affiche le message d'erreur

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
     
    If MaFsource.Cells(352, Col).Value = "" Then
                ShDEST.Range("D29").Value = IIf(Len(MaFsource.Cells(354, Col).Value) = 0, "", (MaFsource.Cells(354, Col).Value))
                ShDEST.Range("D29").Value = ShDEST.Range("D29").Value & IIf(Len(MaFsource.Cells(355, Col).Value) = 0, "", vbLf & MaFsource.Cells(355, Col).Value)
                ShDEST.Range("D29").Value = ShDEST.Range("D29").Value & IIf(Len(MaFsource.Cells(356, Col).Value) = 0, "", vbLf & MaFsource.Cells(356, Col).Value)
                If MaFsource.Cells(354, Col).Value = "" And MaFsource.Cells(355, Col).Value = "" And MaFsource.Cells(356, Col).Value = "" Then ShDEST.Range("D29").Value = "Aucune activité inscrite"
           End If
           If MaFsource.Cells(352, Col).Value <> "" Then
            ShDEST.Range("D29").Value = MaFsource.Cells(352, Col).Value
            End If
     
           'If MaFsource.Cells(357, Col).Value = "" Then
                'ShDEST.Range("B30").Value = IIf(Len(MaFsource.Cells(359, Col).Value) = 0, "", (MaFsource.Cells(359, Col).Value))
                'ShDEST.Range("B30").Value = ShDEST.Range("B30").Value & IIf(Len(MaFsource.Cells(360, Col).Value) = 0, "", vbLf & MaFsource.Cells(360, Col).Value)
                'ShDEST.Range("B30").Value = ShDEST.Range("B30").Value & IIf(Len(MaFsource.Cells(361, Col).Value) = 0, "", vbLf & MaFsource.Cells(361, Col).Value)
                'If MaFsource.Cells(359, Col).Value = "" And MaFsource.Cells(360, Col).Value = "" And MaFsource.Cells(361, Col).Value = "" Then ShDEST.Range("B30").Value = "Aucune activité inscrite"
            'End If
            'If MaFsource.Cells(357, Col).Value <> "" Then
            'ShDEST.Range("B30").Value = MaFsource.Cells(357, Col).Value
            'End If
    J'ai beau lire et relire cette portion de code en commentaire je ne trouve pas d'erreur... peut être y verrez-vous clair ?

  4. #4
    Expert éminent Avatar de Menhir
    Homme Profil pro
    Ingénieur
    Inscrit en
    Juin 2007
    Messages
    16 037
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2007
    Messages : 16 037
    Par défaut
    Citation Envoyé par fb62840 Voir le message
    sur la portion que j'ai porté en "commentaires" si j'enlève les ' des commentaires le code bloque et affiche le message d'erreur
    Essaye de localiser le problème plus précisément.
    Commence par enlever les apostrophes devant les If / End If.
    Ensuite, enlève-les ligne par ligne.
    A chaque fois tu fais une exécution.
    Comme ça tu sauras sur quelle ligne ça bloque.

    Ensuite, tu fais pareil dans la ligne concernée : tu n'utilises que des morceaux, de plus en plus gros, jusqu'à ce que tu mettes le doigt précisément sur le problème.

  5. #5
    Membre averti
    Inscrit en
    Octobre 2010
    Messages
    47
    Détails du profil
    Informations forums :
    Inscription : Octobre 2010
    Messages : 47
    Par défaut
    Citation Envoyé par Menhir Voir le message
    Essaye de localiser le problème plus précisément.
    Commence par enlever les apostrophes devant les If / End If.
    Ensuite, enlève-les ligne par ligne.
    A chaque fois tu fais une exécution.
    Comme ça tu sauras sur quelle ligne ça bloque.

    Ensuite, tu fais pareil dans la ligne concernée : tu n'utilises que des morceaux, de plus en plus gros, jusqu'à ce que tu mettes le doigt précisément sur le problème.
    C'est exactement ce que j'ai fait... et ça bloque apparemment sans raison...

    En mettant la portion de code dans une macro "suite" elle s'exécute parfaitement...

    J'ai donc utilisé cette "réparation" sans doute imparfaite mais qui fonctionne...

  6. #6
    Expert confirmé

    Homme Profil pro
    Curieux
    Inscrit en
    Juillet 2012
    Messages
    5 169
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Curieux
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2012
    Messages : 5 169
    Billets dans le blog
    5
    Par défaut
    Bonjour,

    Menhir, en fait il ne montre que "quelques lignes" de sa procédure. Moi au contraire je parie qu'il a dépassé la taille maximale
    https://msdn.microsoft.com/fr-fr/vba...dure-too-large

    La cause semble entendue : tu as des blocs de données à traiter rigoureusement de la même façon
    Au lieu de faire une boucle pour itérer le traitement de chaque bloc, tu as codé le traitement de chaque bloc unitaire.

    Il te faut donc comparer les décalages d'un bloc à l'autre, pour savoir comment fabriquer ta boucle

    Un exemple pour comprendre

    une procédure qui traite de façon unitaire 100 000 tâches
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Sub PasOptimal()
        Range("A1") = 1
        Range("A2") = 2
        Range("A3") = 3
        '........ 99 995 ligne plus loin .....
        Range("A100000") = 100000
    End Sub
    une procédure qui boucle 100 000 fois pour réaliser la même tâche
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Sub Optimal()
    Dim i As Long
        For i = 1 To 100000
            Range("A" & i).Value = i
        Next i
    End Sub

Discussions similaires

  1. [XL-2007] Procédure trop longue
    Par presser dans le forum Macros et VBA Excel
    Réponses: 5
    Dernier message: 08/06/2009, 18h52
  2. Une procédure trop longue
    Par lola06 dans le forum VBA Access
    Réponses: 2
    Dernier message: 15/05/2007, 14h02
  3. [Vba access 97] Procédure trop longue
    Par saufffy dans le forum Access
    Réponses: 6
    Dernier message: 26/02/2007, 10h40
  4. [ASE] Procèdure trop longue
    Par Benjamin78 dans le forum Sybase
    Réponses: 2
    Dernier message: 11/04/2006, 10h01
  5. [ASE][T-SQL]Procédure trop longue
    Par Benjamin78 dans le forum Sybase
    Réponses: 5
    Dernier message: 21/03/2006, 12h25

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo