Espace pile insuffisant

Boostez vos compétences Excel avec notre communauté !

Rejoignez Excel Downloads, le rendez-vous des passionnés où l'entraide fait la force. Apprenez, échangez, progressez – et tout ça gratuitement ! 👉 Inscrivez-vous maintenant !

mathieumalet

XLDnaute Nouveau
Bonjour à tous,

J'ai créé un programme pour automatiser le traitement de données. Au bout d'un certain temps d'exécution une erreur apparait et m'informe que "l'espace pile est insuffisant".

Je sais d'où vient le problème puisque ma macro fait appel à elle même.Cela fonctionne très bien lorsque le nombre de ligne à traiter n'excède pas le millier.

Je voudrais savoir si il n'est pas possible de "vider le cache mémoire d'excel par une instruction VBA avant de ré-exécuter ma macro".

Merci d'avance,

@+
 
Re : Espace pile insuffisant

Salut Mathieu,

En général, cela vient d'un problème de vriables objet qui ne sont pas vidées à la fin d'un processus.

Il faut penser à faire :
Code:
Set VariableObjet = Nothing

A voir 😉
 
Re : Espace pile insuffisant

BrunoM45 à dit:
Salut Mathieu,

En général, cela vient d'un problème de vriables objet qui ne sont pas vidées à la fin d'un processus.

Il faut penser à faire :
Code:
Set VariableObjet = Nothing

A voir 😉


Salut,

Bonne idée mais non, cela ne fonctionne pas. Et j'insiste sur le fait que ma macro fonctionne parfaitement si le fichier analysé ne dépasse pas les 1000 lignes.

Merci de ton aide,
 
Re : Espace pile insuffisant

BrunoM45 à dit:
Aurais-tu la possibilité de nous mettre le code,
ou une partie du code sur le forum !?

A+

Re salut,

Tiens je te le donne mais je te préviens il y a bcp de lignes.

Code:
Sub mat2()

'On désactive les paramètres Excel par défaut afin d'améliorer la vitesse d'exécution de la macro'

'Déclaration des variables'

Dim PosteName As Variant
Dim PosteQty As Variant
Dim TacheQty As Variant
Dim DetailsQty As Variant
Dim Ligne As Integer
Dim Ligne2 As Integer
Dim LigneRef As Integer
Dim LignePoste As Integer
Dim LigneSuivante As Integer
Dim MyReference As String
Dim MyTache As Variant
Dim MyDetails As Variant
Dim Mysubdetails As Variant
Dim MyQuantity As Variant
Dim MyCode As Variant
Dim MyUnit As Variant
Dim MyMontant As Variant
Dim LigneTache As Integer
Dim LigneDetails As Integer


'Recherche du prochain argument valide'

Sheets("Feuil3").Select
Range("E1:E65000").Select
Selection.find(What:="P", After:=ActiveCell, LookIn:=xlValues, LookAt:= _
        xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False) _
        .Activate
ActiveCell.Select
Do

'selection de la ligne suivante'

Ligne = ActiveCell.Row
LigneSuivante = Ligne + 1
Rows(LigneSuivante).Select
ActiveCell.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
ActiveCell.Select
MyReference = ActiveCell.Value

 ' Boucle externe.
 
Ligne = ActiveCell.Row
Rows(Ligne).Select
ActiveCell.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
ActiveCell.Select
    Do While MyReference = "C"    'je recherche l'argument valide'
    Exit Do
    Loop
Loop Until MyReference <> "C"  ' Quitte la boucle externe
                                ' immédiatement.

'Boucle d'exécution conditionnelle'

Do
 
If ActiveCell.Value = "S" Then
ActiveCell.Select
ActiveCell.Formula = "C"
Selection.Next.Select
ActiveCell.Select
Mysubdetails = ActiveCell.Value
Ligne = ActiveCell.Row

'On note la quantité'

    Selection.Next.Select
    Selection.Next.Select
    Selection.Next.Select
    Selection.Next.Select
    Selection.Next.Select
    Selection.Next.Select
    ActiveCell.Select
    MyQuantity = ActiveCell.Value
    
'On note le Code'

    Selection.Next.Select
    ActiveCell.Select
    MyCode = ActiveCell.Value
    
 'On note le montant'
 
    Selection.Next.Select
    ActiveCell.Select
    MyMontant = ActiveCell.Value
    
 'On note l'unité'
 
    Selection.Next.Select
    ActiveCell.Select
    MyUnit = ActiveCell.Value
    

Sheets("Devis").Select
Range("subdetails_insert").Select
Ligne = ActiveCell.Row
LigneSuivante = Ligne - 1
Rows(LigneSuivante).Select
ActiveCell.Select
Selection.Next.Select
ActiveCell.Select
If ActiveCell.Value = "subdetails #" Then
ActiveCell.Select
ActiveCell.Formula = Mysubdetails


Else: Application.Run "ii_Ajout_sous_details"
Range("subdetails_insert").Select
Ligne = ActiveCell.Row
LigneSuivante = Ligne - 1
Rows(LigneSuivante).Select
ActiveCell.Select
Selection.Next.Select
ActiveCell.Select
ActiveCell.Formula = Mysubdetails

End If

'les frais'

If MyQuantity > "0" And MyUnit = "EUR" And MyCode = "FDP" Then
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
ActiveCell.Select
ActiveCell.Formula = "1"
Selection.Next.Select
ActiveCell.Select
ActiveCell.Formula = MyMontant * 1000 * MyQuantity
End If

'Main d'oeuvre'

If MyQuantity > "0" And MyUnit = "J" Then
Selection.Next.Select
ActiveCell.Select
ActiveCell.Formula = MyMontant
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
ActiveCell.Select
ActiveCell.Formula = MyQuantity
End If

'Les frais'

If MyQuantity > "0" And MyUnit = "EUR" And MyCode = "DEB" Then
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
ActiveCell.Select
ActiveCell.Formula = "1"
Selection.Next.Select
ActiveCell.Select
ActiveCell.Formula = MyMontant * 1000 * MyQuantity
End If

'les frais divers'

If MyQuantity > "0" And MyUnit = "EUR" And MyCode = "DIV" Then
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
ActiveCell.Select
ActiveCell.Formula = "1"
Selection.Next.Select
ActiveCell.Select
ActiveCell.Formula = MyMontant * 1000 * MyQuantity
End If

If MyQuantity > "0" And MyUnit = "EUR" And MyCode = "CPP" Then
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
ActiveCell.Select
ActiveCell.Formula = MyQuantity
Selection.Next.Select
ActiveCell.Select
ActiveCell.Formula = MyMontant * 1000
End If

'les appros normaux'

If MyQuantity > "0" And MyUnit = "EUR" And MyCode = "APN" Then
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
ActiveCell.Select
ActiveCell.Formula = MyQuantity
Selection.Previous.Select
Selection.Previous.Select
Selection.Previous.Select
Selection.Previous.Select
Selection.Previous.Select
Selection.Previous.Select
Selection.Previous.Select
Selection.Previous.Select
Selection.Previous.Select
Selection.Previous.Select
ActiveCell.Select
ActiveCell.Formula = MyMontant
End If


'les appros spécifiques'

If MyQuantity > "0" And MyUnit = "EUR" And MyCode = "APS" Then
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
ActiveCell.Select
ActiveCell.Formula = MyQuantity
Selection.Previous.Select
Selection.Previous.Select
Selection.Previous.Select
Selection.Previous.Select
Selection.Previous.Select
Selection.Previous.Select
Selection.Previous.Select
Selection.Previous.Select
Selection.Previous.Select
ActiveCell.Select
ActiveCell.Formula = MyMontant
End If

'selection de la ligne suivante sur le Devis'

Sheets("feuil3").Select
Ligne = ActiveCell.Row
LigneSuivante = Ligne + 1
Rows(LigneSuivante).Select
ActiveCell.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
ActiveCell.Select
MyReference = ActiveCell.Value


ElseIf MyReference = "P" Then
ActiveCell.Select
ActiveCell.Formula = "C"
Selection.Next.Select
ActiveCell.Select
PosteName = ActiveCell.Value
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
ActiveCell.Select
PosteQty = ActiveCell.Value

'restitution sur la propal'

Sheets("Devis").Select
Application.Run "ii_Ajout_Poste"
Range("subdetails_insert").Select
ActiveCell.Select
LigneRef = ActiveCell.Row
LignePoste = LigneRef - 7
Rows(LignePoste).Select
ActiveCell.Select
Selection.Next.Select
ActiveCell.Select
ActiveCell.Formula = PosteName
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
ActiveCell.Select
ActiveCell.Formula = PosteQty


'selection de la ligne suivante sur le Devis'

Sheets("feuil3").Select
Ligne = ActiveCell.Row
LigneSuivante = Ligne + 1
Rows(LigneSuivante).Select
ActiveCell.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
Selection.Next.Select
ActiveCell.Select
MyReference = ActiveCell.Value

'si c'est fini'

Else:
Sheets("Devis").Select

'on réactive les paramètres Excel par défaut pour effectuer les calculs'

Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True

Range("A1:A1").Select

Exit Sub
End If

    Do While MyReference <> "C"   'je recherche l'argument valide'
    Exit Do
    Loop
    Loop Until MyReference = "C" ' Quitte la boucle externe
                                ' immédiatement.
                                


'Boucle de passage à la suite'

Application.Run "mat2"

End Sub

Le pbe vient de la boucle de passage à la suite qui recharge la même macro. J'ai essayé de créer la même macro mat 3 qui recharge mat 2 et mat 2 qui recharge mat 3 mais même résultat.

Ciao,
 
Re : Espace pile insuffisant

Je pense que ton code est à optimiser, déjà.

Plusieurs questions :
1) Pourquoi avoir plusieurs : Selection.Next.Select à la suite ?

2) pourquoi avoir :
Do ....
Do While MyReference = "C" 'je recherche l'argument valide'
Exit Do
Loop
Loop Until MyReference <> "C" ' Quitte la boucle externe

3) Tu relances à chaque fois ta Sub Mat2, à quel moment dois tu la quitter ?

A+
 
Re : Espace pile insuffisant

BrunoM45 à dit:
Je pense que ton code est à optimiser, déjà.

Plusieurs questions :
1) Pourquoi avoir plusieurs : Selection.Next.Select à la suite ?

2) pourquoi avoir :
Do ....
Do While MyReference = "C" 'je recherche l'argument valide'
Exit Do
Loop
Loop Until MyReference <> "C" ' Quitte la boucle externe

3) Tu relances à chaque fois ta Sub Mat2, à quel moment dois tu la quitter ?

A+

J'optimise ce code en ce moment en créant des offsets de données; je demande un décalage d'un certain nombre de cellule pour collecter les données. Cela raccourcit le code et supprime les Selection.next.

Je quitte ma sub mat 2 lorsque MyReference est vide c'est à dire à la fin du tableau analysé.

Au fait, c'est sympa pour le soutien.

Ciao
 
Re : Espace pile insuffisant

bonjour Bruno, Mathieu

Espace pile insuffisant

au fure et à mesure que l'on execute des boucles (For next, While Wend,Do loop), le processus empile et desempile les differentes boucles.

si nous sortons de maniere inadequate d'une boucle, cette deniere ne se desempile pas, à un moment donné, la pile est pleine et l'espace insuffisant pour ajouter une autre boucle

donc le probleme present à regler ce sont les boucles qui ne sont pas closes.

je me posais, dans un fil precedent, la question à savoir si les diffrents exit (exit do, exit for) desempilaient. nous avons la reponse..........

il va falloir changer la maniere de faire les boucles en paticulier les while wend, do loop

Edit : je viens de faire des tests pour reproduire cette erreur, apres pres de 5*2*65000 boucles imbriquées, toujours pas d'erreur de pile

en regardant mieux ton code, à la fin de ta procedure, Application.run "mat2" ?????????
une procedure qui se relance un nombre indeterminé de fois voila peut etre ton probleme de pile
si tu veux refaire ta procedure, fais un goto debut avec un adresse (debut🙂 apres les declarations de variables
 
Dernière édition:
Re : Espace pile insuffisant

Bonjour à tous,

Tonton VBA n'aime pas beaucoup les itérations et atteint l'espace pile suivant la "grosseur" de la macro. Pour gagner de l'espace, ta macro doit être la plus compacte possible comme te l'ont signalé Bruno et Wilfried.Donc, proscrire aussi tout les select-sélection très lourds et très longs.
Comme l'a signalé Bruno, il y a des boucles bizarres.

Quant à la sortie des macros tu vas dépiler autant de fois que tu as empiler. S'il n'y a pas d'autres macros que mat2 tu peux tenter un END qui te videra la procédure d'un seul coup.

Ci dessous une petite démo d'école avec une itération, la sortie se fait lorsque find ne trouve plus de valeur cherchée car provoquant une erreur
En changeant end par exit sub la durée est nettement + longue...


Sub supprimerFFF()
Dim lig As Long

Application.ScreenUpdating = False
On Error GoTo sortie
lig = Columns(1).Find("FFF", Range("A65536"), , xlPart, xlByRows).Row
Rows(lig).Delete

' nombre d'itérations maxi: env.<2000
supprimerFFF

sortie:
End

End Sub
 
Re : Espace pile insuffisant

Salut Wilfried,

Effectivement, les boucles imbriquées n'améliorent pas la chose !

Mathieu, comme Bruno, je ne comprends pas trop les suites de selection.next.select et l'enregistreur de macro, qu'on utilise tous, montre ici ses limites.

Amitiés
 
Re : Espace pile insuffisant

salut les gars,

Vous avez tout à fait raison de signaler que mon code est un peu lourd. Je me suis lancé dans le VB il y a quelques jours et ... ca se voit lol.

Pour le selection.next je les remplace par le code offset. En fait, j'utilise ce code pour sélectionner un nombre dans un tableau source que je retourne dans un autre tableau.

Bien entendu, il s'agit de trouver et de retourner les nombres dans les bonnes cellules.

Pouvez vous être un peu plus précis sur vos remarques pour desempiler les boucles. Je vois bien que le prbe vient de ma macro mat2 que je relance. Il faut donc qu'avant de la relancer je désempile les boucles successives.

Comment faire.

Merci sympa pour les tuyaux.

Mathieu
 
- Navigue sans publicité
- Accède à Cléa, notre assistante IA experte Excel... et pas que...
- Profite de fonctionnalités exclusives
Ton soutien permet à Excel Downloads de rester 100% gratuit et de continuer à rassembler les passionnés d'Excel.
Je deviens Supporter XLD

Discussions similaires

Retour