| ||||||||
Astucien | Bonsoir à toutes et tous, Dans un fichier Excel, j'ai une macro que j'ai modifiée suite à un allègement de l'onglet concerné, je suis certain des lignes ciblées mais malgrés cela j'ai une erreur que je ne trouve pas. La Macro: Public Sub Remplace() Dim li As Long, co As Long 'https://forum.pcastuces.com/forcer_a_0-f23s32282.htm Application.ScreenUpdating = False With ActiveSheet For li = lideb To lifin If .Cells(li, 20).Value = 0 Then 'T31:T441 soit la colonne 20 ici l'erreur For co = 21 To 36 'U31:AJ31 soit Col 21 à 36 à modifier Cells(li, 20).Value = 1 'Change 1en 0 colonne T If .Cells(li, co) = 1 Then .Cells(li, co) = 0 Next co End If Next li End With Application.ScreenUpdating = True End Sub A l'avance merci pour votre aide, cordialement. | |||||||
Publicité | ||||||||
| ||||||||
Astucien | Bonsoir, Si tu précisais quelle erreur... ? Outre le numéro d'erreur, il est indispensable de savoir quelle est la valeur de li au moment de l'erreur. Egalement les valeurs de lideb et lifin au même moment (d'autant qu'elles ne sont ni déclarées ni définies dans ta macro : variables modules ?) NB-Après avoir cliqué sur "débogage" lors du déclenchement de l'erreur d'exécution, il suffit de faire passer le curseur sur les variables pour qu'une info-bulle t'informe de leur valeur à l'arrêt de l'exécution. La ligne de code : Cells(li, 20).Value = 1 est à passer avant la ligne : For co = 21 To 36 (Inutile de l'exécuter 16 fois, une suffira !) Tout ce que je peux dire pour l'instant. | |||||||
Astucien | ferrand a écrit : Bonjour Ferrand, J'ai repris l'ancienne macro tel quelle était et remise en forme. la c'est bon elle marche. Par contre je ne voit pas comment elle s'exécute 16 fois pour une. Merci pour ton aide. Option Explicit Const lideb = 21 'T21 Const lifin = 481 'AJ441 Public Sub Essai() Dim li As Long, co As Long 'Application.ScreenUpdating = False With ActiveSheet For li = lideb To lifin If .Cells(li, 13).Value = 0 Then '13ème colonne For co = 0 To 10 'Les 10 premières colonnes Cells(li, 13).Value = 0 'Change 1 en 0 colonne U If .Cells(li, co) = 0 Then .Cells(li, co) = 1 'Remplace 1 par 0 Next co End If Next li End With 'Application.ScreenUpdating = True End Sub Public Sub Remplace() Dim li As Long, co As Long 'https://forum.pcastuces.com/forcer_a_0-f23s32282.htm Application.ScreenUpdating = False With ActiveSheet For li = lideb To lifin If .Cells(li, 20).Value = 0 Then 'T31:T481 soit la colonne 20 For co = 21 To 36 'T31:AJ31 soit Col 21 à 36 à modifier Cells(li, 20).Value = 1 'Change 1en 0 colonne AD If .Cells(li, co) = 1 Then .Cells(li, co) = 0 Next co End If Next li End With Application.ScreenUpdating = True End Sub
| |||||||
Astucien | Inutile de demander de l'aide si tu ne réponds pas aux questions ! [Nota- Ton code est déjà malaisé à lire du fait que tu introduis une interligne entre chaque ligne : le copier-coller à partir du module ne devrait pas donner ce résultat, le collage dans le post supprime l'indentation (ce qui est déjà dommmage) mais n'introduit pas d'interligne !]
Tu places la ligne : Cells(li, 20).Value = 1 dans une boucle qui s'exécute 16 fois. Cette ligne va donc 16 fois affecter la valeur 1 à la même cellule (li ne variant pas au cours de l'exécution de cette boucle qui fait varier co...), c'est 15 fois de trop. Si ta procédure se présente comme ci-dessous, aucune raison de déclencher une erreur d'exécution, sauf si tu testes la valeur 0 sur une cellule qui contient du texte ! Const lideb As Integer = 31 Sub Remplace() Les petites rectifs que j'ai opérées ne portent pas sur des éléments qui auraient pu déclencher une erreur [inutile de déclarer la procédure publique, elle l'est par défaut dans un module standard ; préférable de déclarer constantes et variables avec un type de données ; le type Long ne se justifie pour des lignes ou colonnes que si tu envisages de dépasser 32767]. Donc, si une erreur apparaît, ce ne peut être provoqué que par des causes extérieures à la procédure : soit les constantes lideb et lifin n'ont pas été définies à la valeur voulue, soit des cellules sur lesquelles tu testes une valeur numérique contiennent autre chose que des nombres.
Modifié par ferrand le 26/05/2015 12:27 | |||||||
Astucien | ferrand a écrit : Re bonjour Ferrand, Désolé si je n'ai pas répondu correctement à tes questions, n'étant pas au top sur les Macro, je ne comprend pas tout. Pour les interlignes, j'ai juste fait un copier/coller sans faire "valeur". Je test ton aide quand j'ai un moment. Encore merci pour ton aide, cordialement. | |||||||
Astucien | La question était : numéro de l'erreur ? valeur de li au moment de l'erreur ? valeurs de lideb et lifin au même moment ? | |||||||
Astucien | ferrand a écrit : La réponse en images; | |||||||
Astucien | OK pour l'erreur, 1004 c'est une erreur Excel. Mais tu n'indiques pas les valeurs des variables... Cependant, si ton image de module est complète, il y manque les constantes ! Il est donc probable que si tu lances la macro dans ces conditions, lideb=0, lifin=0, donc au 1er tour (unique : de 0 à 0) li=0, et chercher la valeur de la cellule T0 qui n'existe pas, génère nécessairement une erreur. Tes constantes sont probablement déclarées dans un autre module (vu ton précédent post), mais contrairement aux procédures, les variables et constantes de niveau module ne sont pas publiques par défaut. Non déclarées publiques, leur portée est limitée au module dans lequel elles se trouvent. D'autre part il semble que tu aurais intérêt à mettre de l'ordre car avec au moins 61 modules, s'y retrouver ne doit pas être facile ! Toutes les macros que tu utilises peuvent très certainement tenir dans un seul module... | |||||||
Astucien | ferrand a écrit : Bonsoir Ferrand, J'ai testé ta macro, elle fonctionne correctement, merci. Il est possible qu'il y ai besoin de faire de l'ordre dans les 61 modules, certains sont activés par un bouton et pour les 52 semaines de l'année avec une copie spécifique il en reste donc 9 dont deux elles aussi activées par un bouton et une copie spécifique, les 7 autres sont utilisées pour des choix dans les différents onglets.Il est même possible qu'il y en ai qui ne servent plus. Je suis d'accord sur le fait que tous cela est un peu lord et j'aimerai bien l'alléger un tentouillé. Ma connaissance des macro est trop limitée pour y arriver. La reprise du fichier complet que j'ai repris à la suite d'une autre personne et adapté à certaines demandes me parait très difficile, il serat nécessaire un jour de repartir sur des bases plus saines. Je te remercie pour tout ça, cordialement. | |||||||
Astucien | Re, D'ailleur j'ai une autre macro que je trouve un peu longue dans son exécution, mise en route par un bouton elle aussi, si tu pouvais me donner des infos afin de l’alléger un peut je suis preneur. A l'avance merci, cordialement. Sub CopCol() Application.ScreenUpdating = False Range("B31:Q481").Copy Range("U31").Select 'U ou AJ' [U31] 'U ou AJ' Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _ :=False, Transpose:=False Application.CutCopyMode = False For Each X In Selection If X.Value = Chr(160) Or X.Value = Chr(32) Or X.Value = 0 Or X.Value = Chr(22) Then X.ClearContents Next Application.ScreenUpdating = False End Sub | |||||||
Astucien |
Tu n'as pas bien compris en quoi consiste la programmation et comment tout cela fonctionne... Un module standard n'est qu'une feuille destinée à accueillir du texte, constituant le code à exécuter, quelle que soit la façon de lancer son exécution, manuellement, par bouton, ou par du code (une procédure peut en lancer d'autres). Il ne fait donc aucun doute que le contenu de tes 61 modules peut sans difficultés et sans dommages être rassemblé dans un seul, car le découpage que tu sembles faire ne correspond à aucune nécessité de programmation. | |||||||
Astucien | ferrand a écrit : Bonsoir Ferrand, Désolé d'avoir tarder un peu pour la réponse, mais je suis assez occupé en ce moment. Je veux bien comprendre que le texte de mes macro peut être contenu dans un seul module, mais après pour les affecter aux boutons correspondants, la je ne sais pas faire. Besoin d'un bon soutiens pour y arriver. A l'avance merci.
| |||||||
Astucien |
Tu une procédure au bouton, pas un module, donc tout devrait suivre s'il n'y a pas ambiguïté. Ceci étant, réaffecter se fait comme pour la première affectation (il arrive qu'on soit obligé d'en refaire, après passage du fichier par un hébergeur...) Mais à la relecture, je crains que, outre tes 61 modules, ton classeur ne comporte 52 feuilles ou plus et autant de boutons ! Dans ce cas, cela me paraît un peu "surchargé", et l'allègement à faire est plus important, pour réduire le nombre de boutons, et si tu as des feuilles hebdomadaires comme je le suppose, les réduire de 52 à 1 (puisque tu n'afficheras qu'une feuille à la fois, c'est son contenu qu'il faut faire varier sans alourdir le classeur avec une multitude de feuilles qui ne servent à rien quand tu ne t'en sers pas [en stockant les données à conserver sur un petit nombre de feuilles qui peuvent rester masquées]). | |||||||
Astucien |
Bonsoir Ferrand, Pour répondre à tes questions, il y a dans le classeur 14 feuilles, les 52 macro comme tu l'a compris sont pour les semaines de l'année. J'ai donc fait un regroupement de 16 des macro, semaine 1 à 16 sur la feuille 3, celle qui comporte les données sur chaque semaine et ensuite j'ai supprimé les macro inutiles. Après avoir réaffecté les macro sur les boutons concernés, cela fonctionne nickel. Je n'ai plus qu'a m'y coller pour les 36 autres. Merci pour les conseils, je continue mes modifs et reviendrai vers toi pour la suite.
| |||||||
Astucien | Bonsoir à toutes et tous, Après avoir fait le ménage dans la liste des macro que pouvait comporter mon fichier et du coup une simplification, il en reste une qui me pose des interrogations sur ça lenteur. Serte la plage du copier/coller est très large mais quand même à mon avis trop longue à s'exécuter. Je vous la glisse en dessous pour un aperçu en espérant que vous puissiez me guider un peu. A l'avance merci pour les réponses, cordialement. Sub CopCol() Application.ScreenUpdating = False Range("B31:Q481").Copy Range("U31").Select 'U ou AJ' [U31] 'U ou AJ' Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _ :=False, Transpose:=False Application.CutCopyMode = False For Each X In Selection If X.Value = Chr(160) Or X.Value = Chr(32) Or X.Value = 0 Or X.Value = Chr(22) Then X.ClearContents Next Application.ScreenUpdating = False End Sub | |||||||
Astucien | Bonsoir, Essaie ça : Dim i%, k%, m%, v | |||||||
Astucien | ferrand a écrit : Bonsoir Ferrand, Après avoir essayé les valeurs, j'ai l'erreur ci-dessous en image; | |||||||
Astucien | J'ai fourni le code, mais faut le mettre dans une procédure ! exemple : Sub LeDrole() End Sub Entre ces deux lignes tu mets le code. | |||||||
Astucien | ferrand a écrit : Bonsoir Ferrand, Désolé pour ma bourde, comme je l'ai déjà précisé, je ne suis pas au top. Il n'est pas inutile de répéter les procédures pour les faire rentrer. Sinon après correction l'essai n'est pas mieux que la macro précédente car elle ne fini pas, je suis obliger de la stopper et j'obtiens le résultat suivant en image;
Les valeurs me semble bonnes pourtant. A plus, cordialement. | |||||||
Astucien | Numéro de l'erreur ? Valeurs de i et k au moment de l'erreur ? La feuille concernée est bien la feuille active ? Elle n'est pas protégée ? Pas de particularités telles que cellules fusionnées ? | |||||||
Astucien | ferrand a écrit : Bonsoir Ferrand, Désolé d'avoir tardé à te répondre, trop de boulot. La macro que tu m'as envoyé à une durée d'exécution de 2mn, celle que j'utilisai précédemment est de 30s alors que la tienne est plus simple. Merci pour tes réponses, cordialement. | |||||||
Astucien | Si tu n'identifies pas l'erreur, comment veux-tu trouver la cause ? Lorsqu'une erreur d'exécution survient, l'exécution de la macro s'arrête et tu as un message qui indique le numéro de l'erreur. Il faut le noter. Ensuite cliquer sur Débogage, la macro s'affiche et la ligne sur laquelle est survenue l'erreur est surlignée. Il faut la noter aussi. A ce moment tu balades le curseur de la souris sur les variables, une info-bulle affiche leur valeur qui est la valeur qu'elles avaient au moment de l'arrêt. Au cas particulier, les valeurs de i et k pourraient indiquer la cellule sur laquelle l'erreur s'est produite. Sans ces éléments (qu'il faut moins d'une minute pour rassembler), la boule de cristal ne fonctionne pas. Rien dans le code ne peut laisser supposer la possibilité d'une erreur d'exécution. Et testée sur un tableau de caractères, elle s'exécute en 10 s. Il y a donc autre chose dans ton classeur, la feuille ou le contenu des cellules... qui provoque un problème ! | |||||||
Astucien | ferrand a écrit : Bonsoir Ferrand, Je ne peux pas avoir de message d'erreur puisque je la stop avec la touche "echap" du clavier.
Le débogage donne ce qui suis. Je pense qu'il serait mieux que je te joigne l'onglet de mon fichier car il y a des cellules fusionnées, des conditions de couleur selon 1 ou 0, et une mise à zéro par une action sur un autre bouton. Le copier est fait sur des cellules contenant des liaisons avec un autre onglet. Les trois macro y sont présentes, tu pourras faire les comparaisons. Cela peut perturber ta macro. http://www.cjoint.com/c/EGbtZexPp3x A l'avance, merci pour les réponses. | |||||||
Astucien | Pas d'erreur d'exécution constatée ! Un peu longue : 33 s. Mais on réduit nettement la durée en inhibant la mise à jour de l'affichage. Durée d'exécution constatée (sur une dizaine d'essai) variant de 3 à 7 s. Erreur ?? J'ai d'autres remarques mais elles attendront que j'aie récupéré complètement après anesthésie (je sors de clinique). | |||||||
Astucien | ferrand a écrit : Bonjour Ferrand, Je te remercie pour cette réponse, tu prend tout le temps qu'il est nécessaire pour me répondre, je connaît hélas moi aussi le résultat des anesthésies, prend soin de toi et va y doucement. Sachant que cet épisode ralentis le fonctionnement des neurones, laisse leurs la possibilité de récupérer. Bon rétablissement, cordialement. | |||||||
Astucien | Bonsoir Ferrand, J'espère que le passage de l'anesthésie c'est estompé et que ta santé est au mieux, que tu as le temps de profiter un peu du soleil et que ce moment sera vite oublié. A plus, cordialement.
| |||||||
Astucien | Salut ! Tout va à peu près, merci. Pour en revenir à ton extrait de fichier, la macro s'exécute normalement. Il convient juste d'empêcher la mise à jour de l'affichage : Application.ScreenUpdating = False Next i en introduisant les 2 lignes en gras. Ce qui dans ce cas paraît judicieux et divise par 10 le temps d'exécution. Mais par ailleurs, cette procédure qui reproduit un tableau à un autre emplacement de la même feuille pose quelques questions du fait que lors de sa reproduction tu l'épures de valeurs correspondant chacune à un seul caractère, dont on ne voit pas pour certaines comment elles pourraient s'y trouver, même si ce tableau est saisi ailleurs que sur cette feuille. D'abord le caractère 22 : il s'agit d'un caractère de contrôle, ayant notamment une fonction lors de transmission par télétype (j'ai fait ça à l'armée ! c'est bien loin) mais je ne vois vraiment pas comment tu pourrais le récupérer dans ton tableau, lequel apparaît comme un tableau de chiffres issu à l'origine d'une saisie. Le caractère 32 : c'est l'espace ordinaire. Si tu ne t'amuses pas à taper des espaces au petit bonheur, il n'y aucune raison d'en trouver. Le caractère 160 : espace insécable. Il faut vouloir l'introduire pour en saisir un, donc pourquoi y en aurait-il ? Le 0 (zéro), ça c'est un chiffre. Si tu ne tapes pas de 0, il n'y en aura pas. Si tu appelles une cellule vide par formule, le résultat sera effectivement 0, mais tu peux inhiber son affichage, par un format de cellule personnalisé sur la plage concerné. Ceci étant, si on se contente d'éliminer les 0, l'exécution de la macro devient pratiquement instantanée. Il me paraît utile de regarder de près cette question. Autre chose : tu places tes macros dans le module de la feuille concernée. Ce n'est pas une bonne idée. Ces macros (ordinaires) ont normalement leur place dans un module stanndard. Les modules spécifiques aux feuilles de calcul (de même que le module dédié au classeur) sont principalement dévolus aux procédures évènementielles et il est préférable de ne pas les surcharger par des procédures courantes. Cela serait plus rationnel dans le cas où tes boutons étaient des contrôles activeX, et où ces macros constitueraient la procédure exécutée à l'évènement Click du bouton. Encore que dans ce cas il pourrait également être préférable de n'utiliser l'évènement Click que pour lancer avec des arguments adéquats une procédure située dans un module standard, surtout si l'on peut donner une utilisation plus générale à ces procédures (mais là je n'ai qu'une vue partielle de ton classeur et il m'est difficile de me prononcer, cependant vu nos discussions antérieures sur le nombre de modules, je ne serais pas étonné que des procédures similaires puissent être fusionnées en une seule, les arguments envoyés à la procédure permettant de différencier et préciser les actions exécutées dans chaque cas).
| |||||||
Astucien | Bonjour Ferrand, Je te remercie pour toutes ces informations, la difficulté résidait dans les cellules copiées contenant des zéro, après avoir fait la correction des liaisons sur ces cellules, qui maintenant sont vides, l'exécution de la macro est instantanée. Pour ta convalescence, j'espère que cela n'est pas trop sérieux et que tu vas récupérer au plus vite, bon courage. Le sujet de cette macro est donc résolu, je prend contact avec toi pour mon sujet sur l'onglet à copier et déplacer dès que je suis dispo. A bientôt, cordialement. | |||||||
|
Les bons plans du moment PC Astuces | Tous les Bons Plans | ||||||||||||||||||
|