VBA debogage d'une procédure
Bonjour le forum
Je me bats depuis 3 jours pour débeguer ma procédure qui prise indépendante fonctionne bien mais plante associée avec une autre.
En fait c'est l'instruction "on error resume next" qui est à l'origine du problème sans que je puisse trouver le remède...
le fichier joint permet de lancer la procédure avec un 1 dans la cellule DJ2
Merci de votre aide
Cordialement
Muriel
'TRANSFERT DE DONNEES SUITE RESULTATS
If Range("$DL$2") = 1 Then
Dim rg As Range, r1 As Range, r2 As Range
Dim p1 As String, p2 As String
Application.ScreenUpdating = False 'ne pas raffraîchir l'affichage pendant la macro (plus rapide)
'Pour le 1er tableau, à répéter pour les x tableaux, changer les plages
Set rg = Feuil1.Range("DW23") '1re cellule contenant les infos des 30 tableaux
For j = 0 To 7 '8-1 = nombre de tableaux... à adapter
Range("$DN$2").Formula = j
On Error Resume Next 'nécessaire s'il y a des cellules vides.
p1 = CStr(rg.Offset(j, 1)) 'nom de la plage 1
p2 = CStr(rg.Offset(j, 5)) 'nom de la plage 2
Set r1 = Feuil1.Range(p1) 'convertir le nom en plage
Set r2 = Feuil1.Range(p2) 'convertir le nom en plage
Range("$DP$2").Formula = p1
Range("$DQ$2").Formula = p2
Call MAJ_Tablo2(r1, r2) ' appel de la fonction
Set r1 = Nothing 'vider la plage
Set r2 = Nothing 'vider la plage
Next j
Application.ScreenUpdating = True
End If
End Sub
Sub MAJ_Tablo2(ByRef pTab1 As Range, ByVal pTab2 As Range)
'pTab1 est la plage contenant les agences dans la colonne V
'pTab2 est la plage contenant les agences dans la colonne L
Dim c1 As Range, c2 As Range
Dim N As Byte
For Each c1 In pTab1
For Each c2 In pTab2
If c2 = c1 Then
'on additionne les effectifs, les caht, les intérims
For N = 10 To 12
If c1.Offset(0, N + 29) + c2.Offset(0, N) > 0 Then
c1.Offset(0, N + 29) = c1.Offset(0, N + 29) + c2.Offset(0, N)
Else
c1.Offset(0, N + 29) = ""
End If
Next N
End If
Next c2
Next c1
End Sub
Bonjour Chat Muriel Le forum
Déjà sans ouvrir ton fichier tu te trompes , le on error resume next permet justement de passer les erreurs au cas ou.
Alors c’est pas cela qui te provoque un souci, mais je vais voir ton fichier de suite
a+
papou
bjr Papou
bisous
Oui c'est juste, ce que je voulais dire c'est que pas par pas arrivé à cette instruction la suite de la procédure ne s'effectue pas, retour au debut !!!
Merci de ton aide, je craque
Cordialement
Muriel
Re Muriel le forum
bah oui c'est normal tu ne repars pas au début tu es dans une boucle donc tu remonte au départ de la boucle enfin d'après ce que je vois je ne sais pas ce que tu fais avec ton fichier donc pas facile de vérifier mais bon je continue
a+
tu es aussi sur une instruction événementielle Worksheet.calculate !!
Papou
Salut Chat et le forum
on error resume next : effectivement, c'est bien cette instruction qui te crée des soucis
En cas d'erreur, faire comme si de rien n'était et continuer la macro => c'est ce que j'appelle "botter en touche" : j'ai un problème, mais je ne veux pas le traiter, donc je le masque... et il me revient dans la figure, c'est trop injuste !
Ton code est illisible : trouver l'algorithme à partir de ce code me demanderait trop d'effort. alors, je vais me contenter de le "critiquer"
If Range("$DL$2") = 1 Then Mettre une référence absolue ne sert qu'à compliquer la lecture du code : Tous les range sont définis en abolu !
If Ok = True Then Exit Sub Si je lis bien : si (OK=true) est à true alors sortir. Mais OK est une variable booléenne, non ? If Ok Then Exit Sub si OK=true alors sortir => même résultat
Dim rg As Range, r1 As Range, r2 As Range
Dim p1 As String, p2 As String émailler un programme de déclarations ne sert à rien ! regroupe toutes tes déclarations en début de la macro.
For j = 0 To 7 '8-1 = nombre de tableaux... à adapter
Range("$DN$2").Formula = j
On Error Resume Next 'nécessaire s'il y a des cellules vides. Si c'est nécessaire parce qu'il y a des cellules vides, traite le problème. Avec un if isempty(rg.Offset(j, 1)) then par exemple => là, P1 peut être vide, on affecte quand même r1 et on va à la macro de mise à jour qui se plante... étrange, non ?
On error => tant qu'il n'est pas réaffecté (pour la macro), il reste comme il est (un programmeur correct le réaffecte après avoir traité le numéro d'erreur qui motive un Resume Next). Ça ne sert strictement à rien de l'inclure dans une boucle !
p1 = CStr(rg.Offset(j, 1)) la transformation en texte est automatique : tu l'utilises comme non d'un range => pas la peine d'utiliser Cstr : p1 = rg.Offset(j, 1) donne le même résultat, mais la lisibilité du code est améliorée.
Set r1 = Feuil1.Range(p1) Personnellement, je préfère utiliser le nom de l'onglet, parce qu'il est plus facile de le mettre en variable
Range("$DP$2").Formula = p1 ??? P1 est une formule ? Toujours pareil, dans un soucis de lisibilité on utilisera
Range("DP2") = p1 surtout, si dans ton code tu injectes des formules pour la feuille de calcul
Call MAJ_Tablo2(r1, r2) C'est ici que ton Resume Next te permet d'arriver avec r1 et/ou r2 vide...
Set r1 = Nothing ne sert à rien : redonne la RAM utilisée, mais soit tu re-boucles, et ta variable r1 sera réaffectée, soit tu sorts, est elle sera détruite
Dim N As Byte Personnellement, je ne descends pas en dessous de Integer (2 octets) et, si c'est une variable qui me sert pour les lignes, je la déclare en Long (4 octets). Mais il est vrai que ce n'est pas toujours utile, alors qu'économiser un octet quand on a une RAM qui je juge en GigaOctet...
Je n'aime pas utiliser On Error Resume Next : Je préfère être avertit de l'erreur quand elle se produit, qu'à un moment où j'aurais du mal à la situer. Je ne l'utilise que dans des conditions bien spécifique, et je remet en route la gestion des erreur tout de suite après. Par exemple :
on error resume next
set Wk = workbook("AA")
if err<>0 then
set Wk=workBooks.Open ("....AA.xls"
err.clear
endif
On Error Goto 0J'affecte un fichier à une variable, s'il n'est pas ouvert, j'ai une erreur => j'ouvre le fichier.
Ne sachant pas tester la présence du classeur autrement que par une boucle, le traitement est plus rapide.
C'est comme l'effacement des messages d'alerte : tant que je peux m'en passer, c'est préférable. Mais si je suis obligé de l'utiliser, je le remet en route dès que possible, en encadrant l'instruction qui l'a nécessité.
A+
Bonjour Chat Gorfael le forum
Toujours un plaisir de lire tes explications Gorfael, et pour le on error resume next, tout à fait d'accord avec toi je ne l'utilise jamais, une macro doit tourner de bout en bout en tenant compte des contraintes.
Pour les variables en dessous de long est inutile et plus long à traiter pour excel, car excel doit le convertir pour l'utiliser alors que le long et par défaut sa manière de gérer (lu sur un forum non fantaisiste)
a+
Papou
Bonjour mon cher Banzai
Merci, Merci, Big bisous, tu es un amour
Pour l'instant ca colle !
Je ne m'en sortais pas, j'avais réussi à me passer de "On error résume next "Gorfael a raison de dire que c'est q mm plus simple de traiter le problèm que de botter en touche
Je vais souffrir car j'ai d'autres procédures à venir dans ce dossier.
Ca serait à refaire je ferai une procédure pour éviter l'usage de ces 800 "Si" présents dans les col A et D
Je ne sais mm pas si ca ne va pas être une obligation ce serait quand mm plus correct.
Pour être plus lisible j'ai tenu compte des "critiques" de Gorfael tout en lui disant qu'apres avoir réussi à me passer de "on erro..." que l'instruction "Set r1 = Noting" dans ma procédure était utile, sinon les calculs sont faux...
Et lui dire pour rire "que j'ai connu une affamée qui n'avait vraiment pas de chance, voila qu'elle venait de crever juste au moment où l'on venait de lui apprendre à pêcher"
je vais poursuivre les tests à grande echelle, mais j'ai grace à toi retrouvé le moralj je te tiens informé
Ma formation intensive VBA va bientôt débuter, mais déjà grace à vous tous je suis pas trop inquiète
Merci à tous et bisous Paritec, Gorfael.
Cordialement
Muriel