Saturation mémoire VBA

chris

XLDnaute Barbatruc
Bonjour

J'ai un programme VBA qui tourne très bien (aucune erreur et objectif atteint avec des classeurs créés) mais il manipule de gros fichiers et après la fin du programme, Excel devient instable et plante avec proposition d'envoyer un rapport à MS. Je pense qu'il s'agit d'un problème de gestion mémoire : le plantage se produit lorsqu'on ferme manuellement un classeur.
Y a t'il une commande qui permette de vider la mémoire ?

Sinon toute piste serait la bienvenue.
 

_Thierry

XLDnaute Barbatruc
Repose en paix
Bonsoir Chris, Pat, le Forum

Celà peut provenir de différentes causes. Ce n'est pas forcément dû à VBA, surtout quand je lis 'le plantage se produit lorsqu'on ferme manuellement un classeur'.

Tu n'es pas non plus très détaillée dans ta demande Chris, combien de Classeurs générés à la volée et leur taille respective, ainsi que le nombre d'onglets, de liens, de formules (matricielles ?'), de polices, de Shapes etc...

Tu peux utiliser le Task Manager (Gestionnaire de Tâches de Windows) et le laisser tourner en le laissant visible sur 'Performances', et faire un run de ton Programme, ça pourra te donner des indications...

En ce qui concerne les Codes eux-même, les Variables et Objects déclarés Publiquement sont les seuls qui peuvent te mettre un gros sbinz pour les ressources mémoire, les autres Variables et Objects sont 'éradiqués' en fin de procédure où elles/ils ont été déclarés.

Donc bien vérifier toutes les Variables Publiques, et au cas où les remettre à zéro pour les Numérique, ou à '' pour les String, ou encore Eraze TonTablo pour les Tableau, ou encore Set TonObject = Nothing pour les Objects...(comme annoncé par Pat).

Un 'End' bien placé, peut aussi libérer toutes ces variables d'un seul coup.

Bonne Chance ;) et week end
[ol]@+Thierry[/ol]

EDITION !!!

Un petit truc en plus... au cas où...

Des grosses plages copiées dans le ClipBoard aussi peuvent être gourmantes, pensez à vider avec une simple commande Range('A1').Copy Range('A1')

Message édité par: _Thierry, à: 22/04/2006 23:05
 

michel_m

XLDnaute Accro
Bonjour Chris, pat, Thierry

Autre hypothèse- petit vélo sans garantie:

Mémoire virtuelle saturée: beaucoup de gros fichiers d'où utilisations partielles et/ou restreintes d'où mise en mémoire virtuelle; donc, regarde s'il n' y aurait pas des '.tmp' non effacés dans l'ensemble des disques...ou peut-être augmenter la mémoire virtuelle ?

Tiens nous au courant

Amicalement

Michel_M
 

chris

XLDnaute Barbatruc
Bonjour

Merci de ta réponse.

Plus de précisions :
on s'est aperçu du problème lorsqu'on générait plusieurs classeurs à la suite (il y a un classeur / cas et 9 cas). Mais je le reproduis sur un seul classeur.

Les classeurs ont 5 onglets pour 8 cas et 9 pour le dernier.

Côté objets très peu de choses : 3 boutons de commande sur un onglet.
Dans l'un des classeurs deux onglets ont quatre graphiques.

Côté formules c'est très chargé : jusqu'à 200 colonnes dans certains onglets et jusqu'à 300 lignes avec des formules conditionnelles dans toutes les cellules et des MFC bien chargées également sur presque toutes les cellules (ce sont des plannings type gantt avec des couleurs conditionnelles).
Pas de liaisons externes mais des liens entres certains onglets.

Côté mise en forme une seule police avec ici et là une ligne en gras. Mais une image dans les pieds de page.

Là où je peux sans doute optimiser : j'ai appliqué un quadrillage à l'onglet entier et j'y déroge sur certaines lignes. Je ne sais quel est le meilleur choix.

Côté gestionnaire de tâches il y a des variations très nettes de la mémoire en cours d'exécution : notamment quand on ouvre le modèle pré-formulé cela monte d'un coup puis quand les formule des lignes et colonnes inutiles sont nettoyées et le fichier enregistré cela redescend. Mais une fois tout fermé le niveau reste plus élevé qu'à l'ouverture d'Excel.

Côté copier coller j'ai une ligne que je recopie : je vais effectivement suivre ton conseil.

Côte variables : j'ai effectivement des variables publiques dont un tableau. Il est la base de toutes les procédures. Tout le reste de l'application qui n'est pas lié à la génération de classeur utilise aussi ce tableau.
Pas d'objet.

Arrivant à la même conclusion sur les variables en mémoire j'ai opté pour une mesure radicale : après génération d'un classeur, le classeur qui contient le code se ferme : donc sauf erreur de la part, même les publiques sont oubliées ?
Cela améliore nettement les choses mais Excel reste instable et on finit par reproduite le PB.

Cela se traduit par le phénomène suivant : on clique et rien ne se passe. Si on insiste en recliquant, Excel plante mais si on passe à un autre classeur soit par le menu fenêtre soit via la barre de tâches on peut fermer cet autre classeur. Selon la façon dont on clique on arrive à contourner le plantage : bizarre non ?

Questions :
Peux tu préciser ton 'End bien placé' ?
Me donner des conseils sur la meilleure solution pour les bordures si mon 'tout sauf.. ' n'est pas la meilleure solution.
Autre piste pour éviter les copier coller en série j'utilise des classeurs modèles pré-formulés sur un grand nombre de lignes et colonnes et je supprime les colonnes et lignes en trop après génération : pense-tu que cela puisse aussi être nocif ?

Merci et désolée pour ce long message en ce dimanche ensoleillé que je te souhaite agréable. Je peux attendre lundi sans problème pour la réponse.
 

chris

XLDnaute Barbatruc
Bonjour Michel

Merci de te pencher sur ma mémoire défaillante !

Pas sûre de comprendre l'aspect mémoire virtuelle.
Où cela se règle t-il ?

Une précision : cela plante plus avec 2003 qu'avec 2002 mais cela plante pareil avec un PC disposant de 384MO de RAM et un autre de 1.5GO.

Bon dimanche
 

michel_m

XLDnaute Accro
Re,

mémoire vituelle:

Windows réserve sur le disque dur un espace appelé 'mémoire virtuelle' sur Xp de 2GO par défaut . Ell est mentionnée dans 'outils-système' et correspond au dossier c:\\windows\\temp\\

Pour laisser le maximum de RAM disponible, Windows fait des stats et envoie en mémoire virtuelle les éléments de logiciels et fichiers non utilisés.
Par exemple, lorsque tu demandes une impression, Windows envoie le domaine à imprimer dans 'temp'
et rend la main au système, ce qui te permet de continuer de bosser pendant l'impression.
autre exemple: quand tu bosses sur Excel ou Word ou Xmachin, il y a toujours au moins un fichier temporaire qui traine dans 'temp' et que tu peux pas supprimmer tant que tu utilises le logiciel.

Ces fichiers portent le suffixe '.tmp' et devraient normalement etre supprimées par Windows à la fin du travail mais cela reste aléatoire...
Si l'espace 'mem virtuelle' est insuffisant les '.tmp' vont se placer au petit bonheur la chance et de préférence là où ca gène le plus le fonctionnement cad en racine.

effets: Ton ordi ralentit de + en +, refuse de sauvegarder, envoie des messages de saturation de mémoire ou de demande de rapport à microsoft.
La solution est de nettoyer les '.tmp' par la fonction recherche (désactive l'accès réseau, l'antivirus,firewall, internet, et toute application). A titre anecdotique, mon 'record' trouvé au boulot est 18947 .tmp sous Win98!...'mon ordi, y rame, m'en faudrait un neuf avec écran plat!' (avec 98, une ligne dans autoexec.bat élimine ces fichiers; dis le moi si ca t'intéresse)

Voilà, c'est une piste pour ton pb bien que je la trouve assez improbable mais on se sait jamais...

Amicalement
Michel_M
 

_Thierry

XLDnaute Barbatruc
Repose en paix
Bonjour Chris, Michel, Pat, le Forum

Merci pour ce complément d'Info (et quel complément ! lol)

Oui tout à fait Thierry... Euh non, tout à fait Michel, nettoyage de tous les tmp est indispensable. Tellement indispensable que je n'ai pas pensé le signaler !

Pour la Mémoire Virtuelle (Swap ou encore PageFile), non ce n'est pas de la Ram, c'est un fichier d'échange sur une zone du disque que Windows utilise comme si c'était de la Ram, mais ce n'est pas de la RAM.

En règle générale, on laisse Windows paramètrer tout seul l'espace prévu, par exemple j'ai 1536 Mo par défaut que je pourrai augmenter à 3072 Mo sur la machine où je me trouve actuellement.

Les 1536 Mo représente bien cette notion de 1.5 x fois la RAM installée (j'ai 1024), mais attention, certains spécialistes considère cette affirmation comme étant obsolète sur des systèmes modernes. (voir Article sur Developper.Com


Pour les autres points en Vrac :

Le Nombre d'Onglets un classeur avec 5 onglets (et même 9) est très raisonnable. Pour moi je ne vois pas de souci.

Les Objects Boutons, 3 Boutons, lol mais c'est rien du tout !

Les Graphiques, 2 Onglets contenant chacun 4 Graphs... Selon leur complication, c'est peut-être un peu lourd. J'ai eu des plantage avec des classeurs contenant trop de graphs sur la même feuilles... Voir si tu ne peux pas plutôt les séparer, ou même mieux leur dédier un 'Vrai Onglet' Chart à chacun.


Les Formules, c'est loin d'être ma partie, mais bon si je récapitule 5 Onglets avec 200 colonnes sur 300 lignes dont toutes les cellules contiennent des Formules, et ben ça nous fait 300,000 formules... Je me doute bien que tu ne peux pas faire autrement, mais ça doit mouliner dûr !

Les Mises en Forme Conditionnelles, si ce sont les mêmes cellules qui sont concernées, ça fait le même nombre que de Formules ... En Plus !

Les 'Liens Internes au Classeur'... Si il en y a beaucoup qui sont eux mêmes donc tributaires des Formules de certains Onglets... Et que eux-même mettent à jours d'autres Formules... Et ensuite les Graphs... MamaMia !!

J'ouvre une parenthèse au regard de ces trois derniers Points... Si au départ c'est en VBA que tu récupère un Tableau pour mettre à jour cette 'Industrie' de calcul...

Recommandation 1)
Mettre au tout début
Application.Calculation = xlCalculationManual
(Ensuite on peut lancer des 'Calculates' sporadiques au coup par coup très précis :

Pour une feuille de calcul particulière : Worksheets(1).Calculate
Pour une plage déterminée Worksheets(1).Rows(2).Calculate

Ce devrait faire peut-être un peu moins de dégats...

Penser à remettre à 'xlCalculationAutomatic' quand tu pourras depuis un classeur 'léger', sinon tu vas avoir des utilisateurs qui vont te dire que leur Excel est Cassé lol


Recommandation 2)
Remplacer le maximum de Formule et de MFC par un algo VBA qui écrira en dûr les résultat et fera les Mise en Forme Voulue...

Ce sera peut-être plus long de traitement, mais ça économisera ensuite de se coltiner un 'bouffe ressource'


Les 'images en Pied de Page', si ce n'est pas sorti de ton appareil photo 6 Méga pixel ce ne devrait pas poser de problème !

L'application du 'quadrillage à l'onglet', à éviter, c'est clair, il vaut mieux définir la zone que de quadriller 16 millions de cellules ! Un petit Code VBA devrait le faire sans souci sur 'UsedRange'

Les 'copier coller', donc oui si tu as des grosses plages, sinon pour une seule Ligne, bof c'est pas la mer à boire ni la belle-mère à avaler !

Coté 'Variables Publiques', bien que l'aide VBA n'explique pas vraiment mis à part :

Les variables déclarées avec l'instruction Public sont accessibles à toutes les procédures, dans l'ensemble des modules de toutes les applications, à moins que Option Private Module ne soit activé. Dans ce cas, les variables ne sont publiques qu'au sein du projet qui les accueille

J'ai quand même testé, le fait de Fermer le classeur contenant la Déclaration Publique, la dite variable 'is apparently dead' mais je n'ai pas la preuve de ce qu'elle laisse comme résidus en Mémoire, avec une fermeture un peu 'bourrin', un Erase du Tableau avant fermeture devrait faire (théoriquement) un peu plus de propreté.

Pour le 'End Bien Placé', oh c'est simple dans ton cas vu que tu fermes ce Classeur 'InterFace', tu peux le mettre comme ça :

Private Sub Workbook_BeforeClose(Cancel As Boolean)
End
End Sub

L'aide VBA stipule bien ceci :
L'instruction End met immédiatement fin à l'exécution du code, sans appeler d'événement Unload, QueryUnload, ou Terminate, ou tout autre code Visual Basic. Le code que vous avez écrit dans les événements Unload, QueryUnload, et Terminate des feuilles et des modules de classe n'est pas exécuté. Les objets créés depuis les modules de classe sont détruits, les fichiers ouverts au moyen de l'instruction Open sont fermés et la mémoire occupée par le programme est vidée. Les références d'objet appartenant à d'autres programmes ne sont plus valides

Pour 'éviter les copier coller en série', je pense que ce n'est pas si nocif, puisqu'en VBA à chaque nouveau 'Copié' le précédant est écrasé dans le ClipBoard.

On pourrait voir si tu ne peux pas plutôt transposer des Tableaux Array Variant (Tableau de Plage) directement sur une Copy de WorkSheet 'Matrice' qui serait formatée pour le Design voulu.... Mais je dis bien il faut voir le contexte du programme.

Voilà, j'espère

1) que le Post va pas planter quand je vais l'envoyer !

2) que celà permettra de résoudre (un peu) ton souci

Bon Dimanche (ensoleillé ici aussi, mais j'aime pas trop le soleil lol)

[ol]@+Thierry[/ol]
 

chris

XLDnaute Barbatruc
Bonjour à jmps qui se penche lui aussi sur mon PB

En fait le PC ne semble pas swapper (pas d'activité DD au moindre clic) : j'ai déjà vu des PC limités swapper, on perçoit cette activité.

Là je pense (peut-être à tort) qu'il a alloué beaucoup de mémoire et qu'il ne sait pas comment la libérer où que la donnée qu'il pensait trouver à telle adresse n'est pas correcte car il y a eu un écrasement...

(J'ai il y a longtemps (chez un éditeur de softs)testé des softs en dev et je sais que beaucoup de problèmes viennent de la gestion des données dans la mémoire, et sans savoir techniquement ce qui s'y passe, je sens que c'est là.

Le fait qu'on arrive à éviter le plantage en cliquant sur un autre fichier avant de revenir à celui qui ne réponds pas, montre que ce n'est pas très rationnel (car cet ordre de clics est aléatoire d'une fois à une autre).

Comme c'est un developpement que j'ai fait pour un client, je suis mal car il faut que ça marche.

Donc je cherche des pistes pour alléger la mémoire d'où mes questions sur les bordures où autres points à mieux gérer.

Merci encore de vos lumières.
 

_Thierry

XLDnaute Barbatruc
Repose en paix
Re Bonjour Chris, Michel, Bonjour mon Cher José, le Forum


Arf j'ai mis tant de temps à rédiger ma longue réponse que je vous ai pas vu lol !!!

Bon et bien je vois que Chris est dans les parages, elle a de quoi lire lol

Bon Dimanche
[ol]@+Thierry[/ol]
 

chris

XLDnaute Barbatruc
Rebonjour et merci Thierry

Ton aide, comme celle de Michel, jmps, pat.. ajoute des rayons au soleil qui, lui, va et vient.

Côté recommandation 1 : j'avais déjà limité au max les calculs mais comme il y a des parties tri ou filtres, j'active, désactive er réactive selon..
Mais je vais repeigner le code

La 2 : beau boulot en perspective. Côté timing à pleine charge (une année glissante) l'une des génération prend 20 mn sur une machine récente. Donc je vais essayer les autres avant !!

Je rajoute le end tout de suite et je vais dé-quadriller dèjà partiellement (et + si affinités !) mes modèles.

Côté graphiques, je ne compte pas le nombre d'heures passées à manier le chausse pied pour faire rentrer sur un A4 les quatre graphiques plus des tas d'infos autour parce que le client veut ça et pas autre chose ! Na !
D'ailleurs j'avais oublié dans mon inventaire les polices windings qui agrémentent quelques cellules autour de ces graphiques...
Donc là je n'ai pas de marge de manoeuvre.

Je vous tiendrais au courant : je vais utiliser la méthode expérimentale et pister modif par modif (du moins j'essaierai !).
 

michel_m

XLDnaute Accro
Re,

Petit aparté pour te remercier José. Je viens d'apprendre 'swap' avec pagefile et la confusion que je faisais: petit tour depuis tout à l'heure dans les forums Windows qui ont un peu éclairé ma lanterne à ce sujet

excuses moi, Chris, d'intervenir sans que cela te fasse progresser dans ton pb, mais je tenais à remercier José.

Amicalement (du coup, j'ai loupé le départ de la F1 !)

Michel_M
 

chris

XLDnaute Barbatruc
Rebonjour

J'ai fait divers tests. Conclusion mon programme VBA n'est pas directement concerné.
Ce sont les classeurs résultants car même si démarre Excel à froid, sans ouvrir le classeur contenant le code de génération, mais seulement les classeurs générés, au bout de 3 ou 4 classeurs ouverts j'arrive à reproduire le plantage.

J'ai calculé qu'avec les formules des MFC il y a à peu près 200 000 formules par classeur.
Donc je crains de devoir me résoudre à la piste de Thierry consistant à mettre en dur les résultats et les couleurs via le code pour alléger les formules.

J'ai même remarqué à un moment que bien que je ne fasse rien le mot calculer apparait puis reste affiché dans la barre d'état et, quand en contournant le plantage, j'ai refermé tous les classeurs l'espace mémoire occupé par Excel est bien inférieur à celui occupé au lancement d'Excel comme si le programme lui même s'était fait grignoté.

En tout cas je vous réitère mes remerciements car votre soutien est précieux.
 

_Thierry

XLDnaute Barbatruc
Repose en paix
Re Chris

De rien, c'est normal, pour une fois qu'on peut aider un Contributeur qui en plus est une Contributrice ;)

Et si tu refais la même manip sans VBA, avec Excel paramétré en Calcul Manuel...

Car si ça passe, on pourrait revoir ma Recommandation 1)... Pour t'éviter des Algo à avoir des nuits blanches !

Bon Courage
[ol]@+Thierry[/ol]
 

Statistiques des forums

Discussions
312 192
Messages
2 086 054
Membres
103 109
dernier inscrit
boso_vs_viking