Boucle de macro en échec

Boucle de macro en échec - VB/VBA/VBS - Programmation

Marsh Posté le 10-11-2014 à 17:03:26    

Bonjour à tous !
 
Après pas mal de temps passé à comprendre les grands principes des macros, je me suis lancé pour automatiser des rapports.
 
J'ai donc écrit une macro qui fait une suite de tâches sur une base de données :
 
- copier/coller de données relatives à un client dans le rapport correspondant au client
- rafraîchissement du rapport contenant les nouvelles données
- sauvegarde du rapport dans un répertoire
- fermeture du rapport
 
Cette macro est exécutée pour une liste de clients, j'ai donc fait une boucle afin que l'opération soit répétée pour tous mes clients.  
 
Ma base de données primaire est dans le fichier "Base traitée.xlsm", mes rapports portent le nom de "nom du client.xlsm" (ex : ALPHA.xlsm)
 
Le code est ci-dessous. J'ai limité la boucle aux 2 premiers clients "ALPHA" et "BETA" pour alléger la durée des tests.
 

Code :
  1. Sub separation_base_client()
  2. Dim i, j As Integer
  3. Dim strFichier As String
  4. Dim Chemin As String
  5. Dim nb_clients As Integer
  6.   Chemin = "C:\Users\923006\Google Drive\Rapports"
  7.   nb_clients = Workbooks("Base traitée" ).Worksheets("Liste Clients" ).Cells(Rows.Count, 1).End(xlUp).Row
  8.  
  9.   For j = 2 To 3 Step 1
  10. 'nb_clients
  11.     strFichier = Workbooks("Base traitée" ).Worksheets("Liste clients" ).Range("A" & j).Value
  12.     Workbooks.Open Filename:=Chemin & "\" & strFichier & ".xlsm"
  13.     Workbooks("Base traitée.xlsm" ).Worksheets(1).Activate
  14.    
  15. ' Boucle de recherche par ligne sur la colonne B
  16.      For i = 2 To Cells(Rows.Count, 1).End(xlUp).Row
  17.       With Workbooks("Base traitée.xlsm" ).Worksheets(1).Activate
  18.        If Cells(i, 2).Value = strFichier Then
  19.         Rows(i).Select ' Selection de la ligne
  20.         Selection.Copy 'copie de la selection
  21.         Workbooks(strFichier & ".xlsm" ).Worksheets(1).Activate 'changement de feuille
  22.         Rows(2).Select 'Selection de la deuxième ligne
  23.         Selection.Insert Shift:=xlDown 'Insertion de la selection copier
  24.        End If
  25.       End With
  26.      Next i
  27.    
  28.     Workbooks(strFichier & ".xlsm" ).Worksheets(2).Activate
  29.     Application.Run (strFichier & ".xlsm!Rafraichir" )
  30.     Workbooks(strFichier & ".xlsm" ).Worksheets(2).Activate
  31.     Application.Run (strFichier & ".xlsm!SaveAs" )
  32.     Workbooks(strFichier & ".xlsm" ).Worksheets(2).Activate
  33.     Workbooks(strFichier & ".xlsm" ).Close False
  34.    
  35.   Next j
  36. End Sub


 
Je suis conscient que la méthode choisie n'est peut-être pas la plus simple, ni la plus économe en ressources, cela dit j'aimerais aller au bout de cette idée avant d'essayer de la simplifier.
 
J'ai 2 problèmes avec ce code :  
1 - Lorsque j'exécute la macro avec une boucle sur 'j= 2 to 3', elle fonctionne entièrement pour le premier client, puis s'arrête malgré l'instruction "Next j" en fin de boucle.
 
2 - Lorsque j'exécute la macro à partir du 2ème client "BETA" (j=3), elle fonctionne jusqu'à bloquer sur l'instruction " Application.Run (strFichier & ".xlsm"!Rafraichir) " et me renvoie le message d'erreur suivant : Erreur d'exécution 1004 - Impossible d'exécuter la macro, il est possible qu'elle ne soit pas disponible dans ce classeur ou que toutes les macros soient désactivées.
 
Cette instruction est censée faire appel à une autre macro contenu dans le classeur du client, qui s'exécute normalement lorsqu'elle est lancée depuis le classeur dans lequel elle est stockée. Phénomène intéressant : lorsque je change l'instruction Application.Run (strFichier & ".xlsm"!Rafraichir) en Application.Run ("BETA.xlsm"!Rafraichir), ça ne fonctionne pas non plus. Par contre, lorsque je remplace le nom du client par "ALPHA.xlsm", mon premier rapport client dans lequel j'ai écrit la macro d'origine, ça fonctionne.
 
Voilà, je ne sais pas si cela est très clair, je lance un petit appel à l'aide (je sens que je suis près du but).
 
Merci d'avance pour vos réponses.
shamduf

Reply

Marsh Posté le 10-11-2014 à 17:03:26   

Reply

Marsh Posté le 10-11-2014 à 18:58:46    

 
           Bonjour, bonjour !
 
           La réponse est contenue dans la description ‼
           La macro Rafraichir dans le fichier BETA n'existe pas ou déclenche une erreur !
           Donc suivre directement dans le classeur incriminé la progression du code en mode pas à pas via la touche F8
           pour débusquer la source du problème …
 
           Maintenant ce serait plus logique d'exécuter une telle macro depuis le classeur principal
           en lui passant en paramètre le nom du client …
 

Reply

Marsh Posté le 10-11-2014 à 19:37:32    

Bonjour et merci de ta réponse.
 
La macro existe dans le classeur BETA, c'est bien cela mon problème.
J'aurais effectivement préféré faire exécuter toutes les macros depuis le même classeur, mais cette option ne me convient pas car la macro "Rafraichir" effectue des calculs directement dans le classeur du rapport final...

Reply

Marsh Posté le 10-11-2014 à 20:07:18    

 
           Je ne vois pas bien le rapport : le classeur principal peut très bien effectuer des calculs dans un classeur client !
 
           Suffit de respecter le B-A-BA : la hiérarchie des objets (Classeur / Feuille / Cellule / propriété ou méthode) …
 
           Coder proprement sans Select ou Activate inutiles et souvent source d'erreurs !      Voir cette p'tite leçon
 
           Te reste plus qu'à comparer la macro et le contexte (protection cellules, feuille, …) entre le classeur fonctionnant
           et celui déclenchant une erreur ou directement suivre son code en mode pas à pas …
 

Reply

Marsh Posté le 11-11-2014 à 10:42:53    

Pardon, je crois que je me suis mal exprimé : je souhaite que la macro soit contenue dans le fichier du rapport client afin que les données puissent a posteriori être rafraîchies à l'aide de la macro mais sans passer par la base principale.
 
Au cas où, je préfère que mes fichiers soient un peu indépendants, quoi.
 
Merci

Reply

Marsh Posté le 11-11-2014 à 12:53:13    

 
           Le problème ne venant pas du code du classeur principal … et tu sais déjà où chercher et comment …
 

Reply

Marsh Posté le 11-11-2014 à 21:19:52    

Le code échoue sur la ligne de lancement de la macro dans le code principal :)

Reply

Marsh Posté le 12-11-2014 à 00:27:46    

 
           Non, c'est le code appelé qui échoue ‼
           Et comme le code appelant ne peut suivre dans le code appelé, il signale juste la ligne déclenchant le code appelé.
 
           Rien qu'en lisant ta présentation initiale, la source de l'erreur se trouve bien dans le code du classeur client …
           Donc en suivant en mode pas à pas la progression du code dans le classeur client, etc …
 

Reply

Marsh Posté le 12-11-2014 à 10:57:09    

J'ai un petit souci alors, car quand je lance la macro directement depuis le classeur du client, elle fonctionne normalement, et dans ce cas là le pas à pas n'indique pas d'erreur

Reply

Marsh Posté le 12-11-2014 à 13:51:04    

 

Marc L a écrit :

Te reste plus qu'à comparer la macro et le contexte (protection cellules, feuille, …) entre le classeur fonctionnant
           et celui déclenchant une erreur …


 

Reply

Marsh Posté le 12-11-2014 à 13:51:04   

Reply

Marsh Posté le 12-11-2014 à 15:40:15    

Hello
 
J'ai suivi tes conseils... pour simplifier j'ai dupliqué les instructions de la macro contenue dans le fichier client dans ma macro principale. Ce faisant, toutes les instructions sont au même endroit et la commande d'appel à l'autre classeur n'a plus raison d'être.
J'ai quand même gardé la macro secondaire dans le fichier client, au cas où.
 
En tout cas : ça fonctionne !
 
Merci de ton aide.

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed