Entrer et sortir d'une macro d'un fichier à un autre

Lancelot

XLDnaute Nouveau
Hello tout le monde,

Je préfère prévenir, quitte à me tirer une balle dans le pied, le sujet est prise de tête, LOL.

J'ai 3 fichiers, A, B et C qui me permettent de suivre des évènements sur des équipements tout au long de l'année.
Dans chacun de ces fichiers j'ai écris des zolies macros pour simplifier la tache à chacun de mes utilisateurs.

J'ai créé des liens dans ces macros pour pouvoir copier, lorsque l'utilisateur coche une checkbox, le dit évènement dans un des autres fichiers. En d'autres termes:

Si fichier A est en cours de saisie et que l'utilisateur coche fichier B alors à la fin de la saisie dans fichier A, le fichier B s'ouvre avec les éléments déjà renseignés dans le fichier A qui peuvent alors éventuellement être modifiés et/ou complétés par le même utilisateur

Si fichier B est en cours de saisie et que l'utilisateur coche fichier A alors à la fin de la saisie dans fichier B, le fichier A s'ouvre avec les éléments déjà renseignés dans le fichier B qui peuvent alors peuvent éventuellement être modifiés et/ou complétés par le même utilisateur

Si fichier C est en cours de saisie et que l'utilisateur coche fichier B alors à la fin de la saisie dans fichier A, le fichier B s'ouvre avec les éléments déjà renseignés dans le fichier A qui peuvent alors peuvent éventuellement être modifiés et/ou complétés par le même utilisateur

etc... avec les autres cas possible.

Jusque là tout va bien pour mes macros, elles fonctionnent bien : pas de problème.

Par contre, dès l'instant où l'utilisateur coche les deux fichiers, la macro ne traitent que la première checkbox rencontrée dans ma ligne de code et s'arrête une fois le fichier associé traité.

C'est comme si excel sortait de la macro du fichier en cours de saisi, traite le fichier destination et ne revient pas dans le fichier d'origine pour finir de lire le reste de mon code.

Exemple:
Comportement attendu:
Fichier A ouvert et en cours de saisi, checkbox fichier B et C cochée.
Fin de traitement du fichier A, ouverture et traitement du fichier B.
Fin de traitement du fichier B, fermeture du fichier B,
Ouverture et traitement du fichier C.
Fin de traitement du fichier C, fermeture du fichier C et retour dans fichier A qui n'avait pas été fermé.

Comportement réalisé:
Cas 1
Fichier A ouvert et en cours de saisi, une seule checkbox cochée = fichier B.
Fin de traitement du fichier A, ouverture et traitement du fichier B.
Fin de traitement du fichier B, fermeture du fichier B,
Retour dans fichier A qui n'avait pas été fermé

Cas 2
Fichier A ouvert et en cours de saisi, une seule checkbox cochée = fichier C.
Fin de traitement du fichier A, ouverture et traitement du fichier C.
Fin de traitement du fichier C, fermeture du fichier C,
Retour dans fichier A qui n'avait pas été fermé.

Cas 3
Fichier A ouvert et en cours de saisi, checkbox fichier B et C cochées.
Fin de traitement du fichier A, ouverture et traitement du fichier B.
Fin de traitement du fichier B, fermeture du fichier B,
Retour dans fichier A qui n'avait pas été fermé

J'imagine à quel point cela doit être compliqué à interpréter mais si une bonne âme a une idée pour qu'à partir du fichier B je revienne dans le fichier A pour interpréter le reste de mon code, je lui serais vraiment très reconnaissant.

Ça fait 3 jours que je suis dessus et je ne sais pas quoi faire.

En attendant une bonne idée, je continue de me gratter la tête :confused: et de faire des tests.
 

Nairolf

XLDnaute Accro
Re : Entrer et sortir d'une macro d'un fichier à un autre

Salut Lancelot,

Quelqu'un pourrait peut-être trouver une solution à ton problème, mais malheureusement sans fichier exemple, ça me semble impossible.
Donc, joint un fichier et ça nous aideras à t'aider.
 

Lancelot

XLDnaute Nouveau
Re : Entrer et sortir d'une macro d'un fichier à un autre

Bonjour à tous les deux,

Avant toutes choses, je vous remercie et salue votre courage! :)

Pour le fichier, compte tenu de mon code, je vais avoir du mal : c'est un code que j'ai écrit au fur et à mesure des années et le dépoiler pour qu'il soit digeste à la résolution de pb ne me semble pas réalisable à mon niveau.

Par contre, je vous mets les endroits qui me semblent poser pb dans les trois fichiers. Soyez indulgent, je suis timide :eek: , j'ai appris sur le tard et je ne suis pas programmeur de formation :rolleyes:.
J'ai dégagé les lignes qui n'ont pas d’interactions avec les autres fichiers et qui ne font que des choses sur le tableau excel en cours.

Vous noterez qu'il y a beaucoup de commentaire parce que c'est un code que je touche qu'une fois par an et pour m'y retrouver j'ai besoin de commentaires.

Ensuite afin d'être le plus explicite possible: je passe à chaque fois par un Userform pour que l'utilisateur soit plus alaise dans la saisi des informations ce qui a la fâcheuse tendance, au pour moi, à compliquer beaucoup les choses.

Code Fichier A
Code:
Private Sub CommandButton1_Click()

[...]

    Unload UserForm1

' ******* Prise en compte de l'évènement pour Fichier B********

' Copier/coller des informations dans l'autre classeur si la demande est faite (CheckBox29 cochée)
    If CheckBox29 = True Then ' test pour savoir si l'utilisateur a coché le fichier B
        On Error Resume Next ' Verification que le fichier B n'est pas déjà ouvert
[...]
            Set wbcible = Workbooks.Open("Fichier B.xlsm")
[...]
        wbcible.Activate ' Activation du fichier B
        Application.Run "'fichier B.xlsm'!Copie_FT2"
    End If
    
' **** Fin Prise en compte de l'évènement pour Fichier B *******

' **** Prise en compte de l'évènement pour Fichier C****

' Copier/coller des informations dans l'autre classeur si la demande est faite (CheckBox30 cochée)
    If CheckBox30 = True Then ' test pour savoir si l'utilisateur a coché le fichier C
        On Error Resume Next ' Verification que le fichier C n'est pas déjà ouvert
[...]
            Set wbcible = Workbooks.Open("fichier C.xlsm")
[...]
        wbcible.Activate ' Activation du fichier C
        Application.Run "'fichier C.xlsm'!Copie_FT2"
    End If
    
' ***** Fin Prise en compte de l'évènement pour Fichier C****

End sub

Code fichier B appelé par le fichier A
Code:
Sub Copie_FT2()

Dim nligne_gen As Integer
Dim debut_gen As Integer
Dim Aref As String
Dim Atitre As String
Dim Asynth As String
Dim Wbk As Workbook
Dim classeur_B As String
Dim classeur_A As String


Set wbsource = ThisWorkbook
debut_gen = 6
nligne_gen = debut_gen

' Stockage des noms de classeur ouverts s'ils correspondent au Fichier A ou au Fichier B
For Each Wbk In Application.Workbooks
    If Wbk.Name = "Fichier B.xlsm" Then
    classeur_B = Wbk.Name
    End If
    If Wbk.Name = "Fichier A.xlsm" Then
    classeur_A = Wbk.Name
    End If
Next Wbk

' ***** Traitement de l'évènement provenant du FICHIER A *******
' Détermination de la dernière ligne renseignée dans le classeur d'origine
If classeur_A = "FICHIER A.xlsm" Then
    Windows("FICHIER A.xlsm").Activate
    Sheets("Générique").Select
    
    While ((Sheets("Générique").Cells(nligne_gen, 1) <> "") Or (Sheets("Générique").Cells(nligne_gen, 2) <> "") Or (Sheets("Générique").Cells(nligne_gen, 3) <> "") Or (Sheets("Générique").Cells(nligne_gen, 

4) <> ""))
        nligne_gen = nligne_gen + 1
    Wend
    
    nligne_gen = nligne_gen - 1
    
    If Range("A" & nligne_gen) <> 0 Then
        Aref = Range("A" & nligne_gen)
        wbsource.Activate
        UserForm1.OptionButton1 = True
    End If
    Windows("FICHIER A.xlsm").Activate
    
    If Range("B" & nligne_gen) <> 0 Then
        Aref = Range("B" & nligne_gen)
        wbsource.Activate
        UserForm1.OptionButton2 = True
    End If
    Windows("FICHIER A.xlsm").Activate
    
    If Range("C" & nligne_gen) <> 0 Then
        Aref = Range("C" & nligne_gen)
        wbsource.Activate
        UserForm1.OptionButton3 = True
    End If
    Windows("FICHIER A.xlsm").Activate
    
    If Range("D" & nligne_gen) <> 0 Then
        Aref = Range("D" & nligne_gen)
        wbsource.Activate
        UserForm1.OptionButton4 = True
    End If
    Windows("FICHIER A.xlsm").Activate
    
    Atitre = Range("E" & nligne_gen).Value ' Récupération du titre du FT issue du FICHIER A
    Asynth = Range("AE" & nligne_gen).Value ' Récupération de la donnée de synthèse du FICHIER A
    
    wbsource.Activate
    
' Stockage des informations récupérées dans le userform du FICHIER B(ce workbook) et inhibition des checkbox programmes (29 et 30)
    With UserForm1
        .TextBox1 = Aref
        .TextBox2 = Atitre
        .TextBox3 = Asynth
        .CheckBox29.Enabled = False
        .CheckBox30.Enabled = False
    End With
    
    ' Détermination des vols actifs
    For i = 1 To Sheets.Count
        If Sheets(i).Name Like "*VV*" And Sheets(i).Cells(3, 1).Value = "Ouvert" Then
            nb_vol_ouvert = nb_vol_ouvert + 1
            If nb_vol_ouvert > 4 Then
            MsgBox Title:="Erreur", prompt:="Nombre de vols actifs > 4 !" & vbCr & "Merci de clore des vols actifs" & vbCr & "et réessayer.", Buttons:=vbOKOnly
            Exit Sub
            Else: j = nb_vol_ouvert + 4
            UserForm1.Frame3.Controls("CheckBox" & j).Caption = Sheets(i).Name
            UserForm1.Frame3.Controls("CheckBox" & j).Enabled = True
            End If
        End If
    Next
    
        UserForm1.Show ' Affichage de la saisi du nouveau FT pour FICHIER B en provenance de FICHIER A
        
'     Fermeture du classeur FICHIER B et retour sur le FICHIER A
        Workbooks("FICHIER B.xlsm").Close savechanges:=True
End If

' ****** Fin Traitement de l'évènement provenant du FICHIER A ******
[...]

End Sub

Le code du fichier C appelé par le fichier A est identique à celui ci-dessus à l'exception de la dernière ligne où je ferme le fichier C.
 
Dernière édition:

Lancelot

XLDnaute Nouveau
Re : Entrer et sortir d'une macro d'un fichier à un autre

Voilou, j'ai mis en dispo 3 fichiers.
J'ai simplifié le code à l'extrême et le symptôme persiste.

Dans le fichier A j'ai même tenté la syntaxe en CASE SELECT en désespoir de cause mais ça change rien.

Tout s'arrête après la ligne de commande Workbooks("Classeur x.xlsm").close Save:=True, alors que je souhaiterais revenir dans la macro initiale.

Note: il faut modifier les chemins d'accès dans les trois fichiers pour qu'ils puissent se parler entre eux :p

HEEELPPP :D
 

Pièces jointes

  • Classeur A.xlsm
    31.7 KB · Affichages: 41
  • Classeur B.xlsm
    28.1 KB · Affichages: 37
  • Classeur C.xlsm
    28.4 KB · Affichages: 31
  • Classeur A.xlsm
    31.7 KB · Affichages: 42
  • Classeur B.xlsm
    28.1 KB · Affichages: 42
  • Classeur A.xlsm
    31.7 KB · Affichages: 42
  • Classeur B.xlsm
    28.1 KB · Affichages: 38
Dernière édition:

Lancelot

XLDnaute Nouveau
Re : Entrer et sortir d'une macro d'un fichier à un autre

Vraiment personne pour me filer un coup de main? Je sais que le sujet est épineux et peut-être mal expliqué mais avec les fichiers ca devrait être plus clair, non ?

Need help....
 

Dranreb

XLDnaute Barbatruc
Re : Entrer et sortir d'une macro d'un fichier à un autre

Bonsoir.
Je n'ai pas ouvert vos fichiers, mais au vu de votre Sub CommandButton1_Click j'ai quand même envie de faire 3 observations :
1) - Il n'est pas logique de demander un Unload d'un userform dont on a encore l'intention d'examiner des valeurs de contrôles longtemps après : Faite Me.Hide à la place, et seulement tout à la fin Unload Me.
2) - Pour vérifier si un classeur est déjà ouvert, c'est mieux d'essayer d'abord non pas de l'ouvrir mais de l'activer. Ensuite seulement si Err on tente de l'ouvrir.
3) - Ne comparez pas des CheckBox à True, c'est idiot : Une comparaison sert à former une expression Boolean valant True ou False. Lorsqu'elle est utilisée dans un If, c'est donc de manière à ce que ça se ramène soit à If True Then soit à If False Then, sachant que ce qui est derrière le Then n'est exécuté que si ça se ramène à If True Then. Or la valeur d'un CheckBox est déjà Boolean, elle se suffit donc à elle même comme condition puisque :
True = True vaut True, et que
False = True vaux False, il s'en suit que
CheckBox29 = True vaut donc CheckBox29 tout seul, et
CheckBox29 = False vaut Not CheckBox29
 

Lancelot

XLDnaute Nouveau
Re : Entrer et sortir d'une macro d'un fichier à un autre

Merci bien pour ces remarques que je prends avec joie et qui me permettront d'alléger mon code. Toutefois, malheureusement cela ne réponde pas à mon pb principal qui est pour moi littéralement bloquant.
Par ailleurs, comme j'avais essayé de le faire comprendre je ne suis pas programmeur pour un clou et n'ait pas la prétention de dire que mon code est intelligent, je cherche à le faire fonctionner sans anomalie. Je peux donc concevoir que bon nombre de mes lignes sont idiotes.
 

Dranreb

XLDnaute Barbatruc
Re : Entrer et sortir d'une macro d'un fichier à un autre

La 1ère remarque pouvait être en rapport avec le problème: l'espace mémoire consacré au CheckBox30 peut avoir été consacré à autre chose du fait qu'il a été libéré par le Unload.
P.S. La 2ième n'y était pas complètement étrangère non plus: vous faites On Error Resume Next mais vous ne faites jamais On Error GoTo 0 derrière le groupe d'instructions pouvant engendrer une erreur. Il s'en suit que si le retour se fait bien dans cette procédure vous ne pourriez pas voir une erreur au test de CheckBox30 du genre "L'objet s'est déconnecté de ses clients" toujours due au Unload.
Essayez comme ça :
VB:
Option Explicit
Const Chemin = "C:\Users\AE40209\Documents\00 - Métier Q\17 - Outils\Tests macros\"

Private Sub CommandButton1_Click()
Me.Hide
If Me.CheckBox1 Then LancerCopie_FT2 "Classeur B.xlsm"
If Me.CheckBox2 Then LancerCopie_FT2 "Classeur C.xlsm"
Unload Me
End Sub

Private Sub LancerCopie_FT2(ByVal NomClass As String)
On Error Resume Next
Workbooks(NomClass).Activate
If Err Then Err.Clear: Workbooks.Open Chemin & NomClass
If Err Then MsgBox "Impossible d'ouvrir """ & NomClass & """." & vbLf _
    & Err.Description, vbCritical, Me.Caption: Exit Sub
On Error GoTo 0
Application.Run "'" & NomClass & "'!Copie_FT2"
End Sub
Cela dit, après avoir ouvert un de vos autres classeurs, compris qu'il devait y avoir une certaine symétrie de l'ensemble, m'être dit dans un 1er temps qu'il vaudrait mieux pour simplifier que cette procédure soit écrite de telle sorte que le classeur appelant reste actif, je ne comprends même plus pourquoi vous exécutez une procédure de l'autre classeur au lieu d'effectuer les modifs depuis celui ci.
Possible aussi qu'il vaudrait mieux que toute la programmation soit dans un 4ième classeur ne contenant que des macros, en quelque sorte chef d'orchestre.
 
Dernière édition:

Lancelot

XLDnaute Nouveau
Re : Entrer et sortir d'une macro d'un fichier à un autre

Avant tout: merci! :)


La 1ère remarque pouvait être en rapport avec le problème: l'espace mémoire consacré au CheckBox30 peut avoir été consacré à autre chose du fait qu'il a été libéré par le Unload.
Ok, j'ai remplacé le Unload par un .Hide => malheureusement ça change rien.

P.S. La 2ième n'y était pas complètement étrangère non plus: vous faites On Error Resume Next mais vous ne faites jamais On Error GoTo 0 derrière le groupe d'instructions pouvant engendrer une erreur. Il s'en suit que si le retour se fait bien dans cette procédure vous ne pourriez pas voir une erreur au test de CheckBox30 du genre "L'objet s'est déconnecté de ses clients" toujours due au Unload.
Essayez comme ça :
VB:
Option Explicit
Const Chemin = "C:\Users\AE40209\Documents\00 - Métier Q\17 - Outils\Tests macros\"

Private Sub CommandButton1_Click()
Me.Hide
If Me.CheckBox1 Then LancerCopie_FT2 "Classeur B.xlsm"
If Me.CheckBox2 Then LancerCopie_FT2 "Classeur C.xlsm"
Unload Me
End Sub

Private Sub LancerCopie_FT2(ByVal NomClass As String)
On Error Resume Next
Workbooks(NomClass).Activate
If Err Then Err.Clear: Workbooks.Open Chemin & NomClass
If Err Then MsgBox "Impossible d'ouvrir """ & NomClass & """." & vbLf _
    & Err.Description, vbCritical, Me.Caption: Exit Sub
On Error GoTo 0
Application.Run "'" & NomClass & "'!Copie_FT2"
End Sub
Cela dit, après avoir ouvert un de vos autres classeurs, compris qu'il devait y avoir une certaine symétrie de l'ensemble, m'être dit dans un 1er temps qu'il vaudrait mieux pour simplifier que cette procédure soit écrite de telle sorte que le classeur appelant reste actif, je ne comprends même plus pourquoi vous exécutez une procédure de l'autre classeur au lieu d'effectuer les modifs depuis celui ci.
Possible aussi qu'il vaudrait mieux que toute la programmation soit dans un 4ième classeur ne contenant que des macros, en quelque sorte chef d'orchestre.

Il faut simplement se dire que j'ignore 90% des commandes disponibles de VBA et que je "programme" avec ce que j'apprends à chaque fois que je m'attache à faire évoluer cet ensemble de fichiers. Du coup, forcément, ça donne des lignes de code tordues.

Sinon, le 4ème classeur est effectivement un idée à laquelle j'avais pensée mais impliquerait, si nous parlons bien de la même chose, un changement dans les habitudes des utilisateurs que je n'ai pas encore anticipé et donc planifié. Mais j'y pense fortement.

Je vais tenter votre proposition et je vois ce que ça donne :)

J'espère que ça va marcher.
 

Lancelot

XLDnaute Nouveau
Re : Entrer et sortir d'une macro d'un fichier à un autre

Re bonjour,

J'ai fait un test mais cela ne change rien au symptôme : l’exécution se fait bien sur le premier If, une fois le premier classeur refermé : plus rien. Le 2ème if est oublié

Je ne comprends vraiment pas pourquoi...
 

Dranreb

XLDnaute Barbatruc
Re : Entrer et sortir d'une macro d'un fichier à un autre

Bonjour.
Alors je ne vois pas. Mettez des points d'arrêt un peu partout et dérouler en pas à pas pour voir où l'exécution est abandonnée.
Essayez de remplacer les Application.Run par les instructions qui effectuent ce que ça devrait faire.
 

Dranreb

XLDnaute Barbatruc
Re : Entrer et sortir d'une macro d'un fichier à un autre

Un point d'arrêt devant If Me.CheckBox2 Then ne se produit plus ?
Essayez à tout hasard de passer la propriété ShowModal du Userform à False.
Mais je crois qu'il vaudrait mieux faire les modifs de cellules dans celui ci que d'appeler une procédure de l'autre classeur qui les fait.
 

Lancelot

XLDnaute Nouveau
Re : Entrer et sortir d'une macro d'un fichier à un autre

Hello,

Alors showmodal ne change rien au pb.
J'ai tenté de reprendre tout mon code issue de copieFT2 mais cela ne change car il faudrait que je fasse appelle au UF des différents classeur et si j'ai bien compris pour faire ça il faut que je fasse la même commande que pour une macro Application.Run.

En effet, dans l'exemple des fichiers je n'ai pas fait apparaitre la raison de tout ceci, mea culpa. :eek:
Je dois utiliser des Userform différents mais avec des données récupérées d'un autre classeur.

L'UF du classeur A doit être capable, sur demande, de s'afficher avec certaines données issues de l'UF des classeurs B ou C
L'UF du classeur B doit être capable, sur demande, de s'afficher avec certaines données issues de l'UF des classeurs A ou C
L'UF du classeur C doit être capable, sur demande, de s'afficher avec certaines données issues de l'UF des classeurs A ou B

Vraiment pas simple... je désespère
 

Discussions similaires

Membres actuellement en ligne

Statistiques des forums

Discussions
314 628
Messages
2 111 337
Membres
111 104
dernier inscrit
JEMADA