Macro ferme VBA msgbox

Bonjour à tous,

J'ai plusieurs fichiers qui contiennent des macros au sein desquelles il y a des boites de dialogues, qui proposent par exemple de sauvegarder ou non une copie du fichier.

Je souhaite pouvoir faire tourner toutes ces macros à la suite automatiquement, mais les boites de dialogues en question posent problème, je ne sais comment les fermer automatiquement ou les désactiver.

Plusieurs idées :

  • faire en sorte que les boites de dialogue ne s'affiche pas si la macro est lancée par une autre macro ?
  • trouver un moyen de répondre "ok" quand les boites de dialogue s'affichent ?
  • faire disparaitre les boites de dialogue après quelques secondes?

Exemple de ces msg box:

''''

If MsgBox("do you want to save a copy of the file?", vbYesNo) = vbYes Then

Dim copy_name As String

Dim daily_date As String

daily_date = Day(Date) & "-" & Month(Date) & "-" & Year(Date)

copy_name = "R:\Market Data\Old\" & daily_date & " " & ActiveWorkbook.Name

ActiveWorkbook.SaveCopyAs copy_name

End If

'''''

J'apprécierais votre expérience sur le sujet, merci d'avance !

Bonjour,

Un sujet similaire a été traité ici : https://forum.excel-pratique.com/viewtopic.php?t=11221

Sinon, à voir avec la fonction

Application.EnableEvents = False/True

pour désactiver les événements

(plus d'explication ici : http://boisgontierjacques.free.fr/pages_site/evenements.htm)

Cependant, un fichier d'exemple permettrai de proposer de meilleurs solution...

Cordialement

Bonjour,

- faire en sorte que les boites de dialogue ne s'affiche pas si la macro est lancée par une autre macro ?

Exemple :

Sub MacroX(Optional auto As Boolean)
    [...]
    If Not auto Then
        If MsgBox(....
            [...]
        End If
    End If
    [...]
End Sub
Sub LancerMacroX()
    MacroX True
End Sub

La macro est dotée d'un argument optionnel booléen. Lancée par l'utilisateur, par exemple au moyen d'un bouton, la valeur de l'argument sera False. Les Msgbox ou autres apparaîtront. Lancée par une autre macro avec l'argument à True, les MsgBix (mis sous condition) n'apparaîtront pas...

NB- Affecter la macro à un bouton avant de placer l'argument optionnel dans le code, car ensuite elle n'apparaîtra plus dans la boîte de dialogue macro.

Cordialement.

Merci à vous,

J'ai essayé de "application.enableevents = False" mais pas de changement les msgbox s'affichent toujours.

Je trouve les "userform" assez difficile à utiliser donc pour l'instant je cherche une autre solution.

@MFerrand la solution a l'air prometteuse mais je ne comprends pas bien pouvez vous m'expliquer avec un peu plus de détail comment elle fonctionne ?

merci

Re,

Ne te laisse pas induire en erreur ! Pour que l'interruption des évènements joue un rôle il faut au moins qu'il y en ait ! Et l'apparition d'une MsgBox ne constitue pas un évènement, ni pour la feuille ni pour le classeur.

Je t'illustre volontiers la solution que j'indique, si la description ne te suffit pas, mais sur un fichier... !

40fichier-calcul.xlsb (13.67 Ko)
40commande-macro.xlsb (12.95 Ko)

Merci beaucoup,

J'ai mis deux fichiers d'exemple avec une macro dans chacun d'entre eux.

Le fichier commande macro s'ouvre et lance une macro qui ouvre le second fichier, y fait tourner une macro et le ferme.

Dans cette deuxieme macro une msgbox apparait pour proposer de sauvegarder une copie du fichier.

Il faudrait que cette msgbox n'apparaisse pas, et que la copie soit automatiquement sauvée.

Merci d'avance !

Je ne vois pas comment est lancée la macro (find_date) ?

Workbooks.Open Filename:= _

file_name

Set wb_open = ActiveWorkbook

If wb_open.ReadOnly Then

wb_open.Close savechanges:=False

Else

Application.Run macro_name

Calculate

wb_open.Close savechanges:=True

End If

macro_name = 'Fichier calcul.xlsb'!find_date

Tu m'as obligé à lire entièrement l'autre macro du coup !

La question qu'on traite était :

- faire en sorte que les boites de dialogue ne s'affiche pas si la macro est lancée par une autre macro ?

Donc un lancement par macro d'un côté (on l'a) et un lancement autre dans lequel le message s'affiche.

On n'a pas cet autre lancement ?

D'autre part le classeur Commande Macro.xlsb contient en A2 : \\wterparad02\Desktop\Commande Macro.xlsb

La macro de ce classeur affecte ce chemin et nom de fichier à une variable, puis ouvre le fichier ! Il me semble qu'il y a un petit problème, au moins sur le nom, car cela lance sa propre ouverture, ou celle d'un fichier de même nom, et non l'ouverture de Fichier calcul.xlsb qui contient la macro find_date.

Oui exactement merci je me suis trompé.

Du coup deux fichiers.

"Commande macro" lance "fichier calcul" par la macro suivante.

Sub open_second_file()

Dim wb_command As Workbook

Dim ws_command As Worksheet

Dim wb_open As Workbook

Set wb_command = ActiveWorkbook

Set ws_command = Worksheet("Sheet1")

Dim file_name As String

file_name = ws_command.Cells(2, 1)

macro_name = ws_command.Cells(2, 2)

Workbooks.Open Filename:= _

file_name

Set wb_open = ActiveWorkbook

If wb_open.ReadOnly Then

wb_open.Close savechanges:=False

Else

Application.Run macro_name

Calculate

wb_open.Close savechanges:=True

End If

End Sub

ce faisant, dans le deuxieme fichier est lancée la macro suivate.

Sub find_date()

Dim wb_calcul As Workbook

Dim ws_calcul As Worksheet

Set wb_calcul = ActiveWorkbook

Set ws_calcul = Worksheets("Sheet1")

ws_calcul.Activate

ws_calcul.Cells(1, 1) = Date

If MsgBox("do you want to save a copy of the file?", vbYesNo) = vbYes Then

Dim copy_name As String

Dim daily_date As String

daily_date = Day(Date) & "-" & Month(Date) & "-" & Year(Date)

copy_name = "\\wterparad02\Users\Desktop\Commande Macro.xlsb"

ActiveWorkbook.SaveCopyAs copy_name

End If

End Sub

C'est bien entendu un exemple car la macro sur laqeulle je travaille est évidemment plus compliquée !

Merci encore!

10commande-macro.xlsb (13.40 Ko)

Ok ! mais si le mode de lancement est toujours par macro et que tu ne veux pas les MsgBox, il suffit de les supprimer pour que l'enregistrement soit automatique.

D'où ma question sur le lancement pour lequel les MsgBox doivent s'afficher ?

S'il n'y en a pas, pas besoin de dispositif !

Bonjour,

Sans réponse sur la question du 2e lancement, j'ai supposé que c'était de façon classique par un bouton, de toute façon cela ne devrait pas avoir d'incidence puisque c'est par le mode lancement macro à partir d'un autre fichier que l'on bloque le message...

J'ai dû rectifier quelques incohérences et éléments paraissant en anomalie, notamment tu n'incorporais plus la date dans le nom du fichier enregistré en copie, le chemin était différent du préédent, et le nom reprenait celui du fichier lançant la macro, cela ne m'a pas paru logique, surtout l'enregistrer avec le nom d'un fichier ouvert... J'ai donc réintroduit la date et repris le nom du fichier. Si le chemin était effectivement modifié tu feras les rectifications.

J'en ai profité pour simplifier un peu le code...

Sub open_second_file()
    Dim wb_open As Workbook
    Dim file_name As String
    With ThisWorkbook.Worksheets("Sheet1")
        file_name = .Cells(2, 1)
        macro_name = .Cells(2, 2)
    End With
    Set wb_open = Workbooks.Open(file_name)
    If wb_open.ReadOnly Then
        wb_open.Close False
    Else
        Application.Run macro_name, True
        Calculate
        wb_open.Close True
    End If
End Sub
Sub find_date(Optional RegAuto As Boolean)
    Dim copy_name As String
    ThisWorkbook.Worksheets("Sheet1").Cells(1, 1) = Date
    If Not RegAuto Then
        RegAuto = MsgBox("do you want to save a copy of the file?", vbYesNo)
    End If
    If RegAuto Then
        copy_name = "R:\Market Data\Old\" & Format(Date, "dd-mm-yyyy") & " " _
         & ThisWorkbook.Name
        ThisWorkbook.SaveCopyAs copy_name
    End If
End Sub

Pour ce qui concerne l'objet de la discussion, cela repose sur un argument optionnel de la macro, booléen, qui peut donc prendre la valeur True ou False. Etant optionnel, on peut l'omettre, et dans ce cas, la valeur par défaut sera False.

Tu peux donc l'affecter à un bouton, ou le doter d'un raccourci, dans ce cas il faudra faire l'affectation sans l'argument et le remettre ensuite (car doté d'un argument, la macro n'apparaît plus dans la boîte de dialogue, et on passe en général par là pour faire l'affectation manuellement...)

Tu peux observer dans la 1re macro que le lancement de la 2e se fait avec l'argument True :

    Application.Run macro_name, True

Dans la seconde on teste l'argument une 1re fois pour savoir s'il est à False :

   If Not RegAuto Then

Si c'est le cas, c'est que la procédure n'a pas été lancée par la première macro, donc on affiche le message en recueillant la réponse dans la même variable RegAuto (qui sera donc éventuellement modifié par la réponse de l'utilisateur :

       RegAuto = MsgBox("do you want to save a copy of the file?", vbYesNo)

Si ce n'est pas le cas (déjà à True) cette ligne est sautée.

A suite on le reteste sur sa valeur True :

    If RegAuto Then

Si True on exécute l'enregistrement...

(Le True provenant soit de la 1re macro, sans affichage de message, soit non lancée par la macro du choix de l'utilisateur dans le message.)

Cordialement.

13commande-macro.xlsb (13.67 Ko)

Merci beaucoup pour ces réponses.

1) remplacer

file_name = ws_command.Cells(2, 1)

macro_name = ws_command.Cells(2, 2)

par

With ThisWorkbook.Worksheets("Sheet1")

file_name = .Cells(2, 1)

macro_name = .Cells(2, 2)

End With

c'est pour gagner du temps ? Ou parceque ça vous parait plus clair ?

2) Quel est le rôle du "true" dans "Application.Run macro_name, True" ? Pour l'instant mes macros se lancent bien sans !

3) Du coup pour RegAuto, VbYes est équivalent à True ? Et if not RegAuto, équivalent à if RegaAuto = false ?

4) RegAuto est il une variable qui pourrait donc avoir un autre nom ? dans ce cas je ne comprends pas à quel moment cet élément prend la valuer True or False.

5) je ne comprends pas bien "la macro n'apparait pas dans la boite de dialogue. Où est ce qu'on la trouve alors ?

Merci beaucoup pour votre aide très utile et pardonnez certaines questions qui peuvent vous paraitre élémentaires !

Bonjour,

Je ne vais pas avoir le temps de me lancer dans un cours VBA... On va sérier les questions :

3) Du coup pour RegAuto, VbYes est équivalent à True ? Et if not RegAuto, équivalent à if RegaAuto = false ?

Ça tu fais bien de le soulever, RegAuto est de type Boolean et vbYes une valeur Integer, tu vas donc modifier cette ligne ainsi :

        RegAuto = (MsgBox("do you want to save a copy of the file?", vbYesNo) = vbYes)

ce qui sera plus sûr pour obtenir le renvoi d'une valeur booléenne.

Par ailleurs lorsque tu testes une valeur booléenne, il est superflu de demander dans le test si =True ou si =False. La condition doit renvoyer True ou False et la valeur testée est déjà soit True soit False, demander si True=True ou si False=False est une comparaison strictement inutile, et fait faire un calcul à VBA alors qu'il a déjà le résultat !

2) Quel est le rôle du "true" dans "Application.Run macro_name, True" ? Pour l'instant mes macros se lancent bien sans !

Là on est au coeur de la question discutée ! Il est donc primordial que tu comprennes... La méthode Run te permet de lancer une macro en lui passant des arguments (si elle ne pouvait pas, la méthode ne servirait pas à grand chose car dès lors qu'une macro comporte des arguments elle ne pourrait plus être lancée !).

True mis à la suite du nom de la macro définit la valeur de l'argument RegAuto avec lequel tu vas la lancer.

Et c'est la prise en compte de cette valeur True par la macro lancée qui la conduit à ne pas afficher dans ce cas le MsgBox...

4) RegAuto est il une variable qui pourrait donc avoir un autre nom ? dans ce cas je ne comprends pas à quel moment cet élément prend la valuer True or False.

RegAuto est le nom de l'argument défini pour la macro find_date, c'est équivalent à une variable, élément nommé qui prend la valeur que tu lui donnes (en respectant le type que tu lui as défini). Tu peux lui donner le nom que tu veux, ce sera celui que tu utiliseras ensuite pour la doter d'une valeur. Mais comme toute variable, dès lors qu'elle est déclarée (et la ligne Sub... d'une procédure est une déclaration) elle a une valeur par défaut selon le type qui lui est attribué : type String elle a la valeur "" (texte vide), type numérique elle a la valeur 0, non typée (=type Variant) elle a la valeur Empty (vide), et type Boolean elle a la valeur False.

Elle a donc toujours une valeur qui sera False si tu ne définis pas le lancement de la macro avec True, dans ce cas ce sera True. L'argument étant optionnel, VBA ne te réclamera pas de le définir, donc si tu ne le fais pas, la macro sera lancée et l'argument sera à False (dans ce cas c'est la MsgBox qui te permettra en cours d'exécution de le modifier en True, ou non...)

5) je ne comprends pas bien "la macro n'apparait pas dans la boite de dialogue. Où est ce qu'on la trouve alors ?

Rien ne vaut l'expérimentation ! Tu déclares une macro, dans un module :

Sub MaMacro()

End Sub

Inutile de mettre autre chose, c'est juste pour la visualiser. Tu vas dans la boîte de dialogue : tu verras MaMacro dans la liste des macros.

Tu retournes dans le module et tu ajoutes un argument à la macro (inutile de se compliquer on fait au plus simple):

Sub MaMacro(m)

End Sub

Il y a maintenant un argument m, tu retournes dans la boîte de dialogue, la macro a disparu de la liste...

Tu ne peux plus l'affecter à un bouton parce cette méthode ne te permet pas de la lancer avec argument... Il faudra donc la lancer à partir d'une autre macro.

Mais si l'argument est optionnel :

Sub MaMacro(Optional m)

End Sub

Là la macro n'apparaît toujours pas dans la boîte de dialogue, mais elle peut être lancée sans argument. Tu peux donc la lancer avec un bouton... Mais pour l'affecter à un bouton, il est préférable de la voir, donc tu la déclares sans argument, tu l'affectes (elle est jusque là visible dans la boîte), puis tu retournes dans le module compléter ta déclaration avec argument optionnel, elle disparaît de la boîte mais son affectation au bouton demeure.

Pour ce qui est de la question 1, si j'ai un peu modifié le code, c'est pour illustrer que l'on peut écrire un certain nombre de commandes plus simplement, de façon à réduire le volume écrit, ou plus efficacement (commandes plus rapide à l'exécution ou qui réduisent le nombre d'opérations que le programme aura à réaliser), réduction du nombre de variables lorsque leur utilisation est à usage unique (donc à gain nul sinon négatif), utilisation de With efficace à la fois pour réduire l'écriture et augmenter la rapidité, etc.

En outre je présente toujours mon code en l'indentant systématiquement et en respectant scrupuleusement une certain nombre de règles que je considère indispensables (comme déclarer systématiquement toutes les variables utilisées et toujours en début de procédure avant tout code exécutable...)

Sur ce qui est purement formel, cela n'a pas d'incidence sur l'exécution, mais cela en a sur celui qui travaille sur le code... Mais il est de nombreuses règles qui ont, elles, une incidence sur la rapidité d'exécution.

En tout état de cause, lorsqu'on veut se mettre vraiment à coder en VBA, il est jusdicieux de s'y pencher pour se faciliter le travail et le rendre plus efficace.

NB- Tu devrais déjà commencer lorsque tu rédiges un post et que tu cites du code, à te pencher sur l'utilisation du bouton dont la suscription est </> qui te permet d'encadrer le texte avec des balises Code permettant de le faire apparaître dans une fenêtre, avec indentation conservée, et dans tous les cas plus aisément lisible que noyé dans le texte courant du post.

Cordialement.

C'est très sympa et très instructif. J'en profite pour me pencher sur la notion d'argument donc ça me prend un peu de temps, je m'excuse donc de ma réponse tardive. J'essaye de vous tenir informé de mes résultats dès que possible.

Merci beaucoup pour votre aide !

Cordialement.

Rechercher des sujets similaires à "macro ferme vba msgbox"