Fonction "Call" ne fonctionne pas toujours

Bonjour à tous,

Je fais une fois de plus appel à vos lumières concernant un soucis récurent dans un de mes programmes VBA.

J’exécute un UserForm, qui me permet de recueillir des informations. Après validation je fait un Unload Me pour revenir au Module et enchainer le reste du code, dans ce dernier j'ai créé des Fonctions et des Sub pour simplifier mon code (Une fonction création de dossier Windows, et deux Sub pour envoi de mails). Je les appelle donc simplement avec un Call.

J'ai beaucoup de mal à identifier pourquoi, mais il arrive souvent que le programme s'arrête sans avoir exécuté les Call. Un point certain c'est en cas de bug, je sais que les Call ne fonctionneront pas. Pareil si je retourne dans le code et essayer de tester après, je dois quitter et ré-ouvrir, pourquoi, je ne sais pas...? Mais parfois cela peut-être après avoir cliqué sur mon bouton "Annuler" qui fait un simple unload me et un Exit Sub dans le module.

Le programme VBA est assez complexe donc je le partagerai qu'en cas de blocage car beaucoup de boulot pour une faire une version "partageable" mais si vous avez des idées en amont comme souvent ça été le cas se serait top.

Merci.

Bonsoir,

A tout hasard, n'aurais tu pas appelé ton module et ta procédure par le même nom ?
C'est peut être une idée sans fondement mais ne sait on jamais

Je connais déjà ce soucis, j'ai:

- Module -> M1_Créér_Offre

- UserForm -> U1_Créér_Offre

Donc pas de soucis de ce côté

Bien, mais désolé, je ne vois pas comment t'aider

Bonjour @ vous deux !

Si vos différentes procédure n'ont pas de paramètre à recevoir, essayez de supprimer le "Call" et ne mettre que le nom de la procédure.

Ces procédures sont-elles dans un module standard ? Sont-elles placées dans le code du USF, ou bien d'une feuille ?

@ bientôt

LouReeD

Salut LouReed,

Les Call sont supprimés, il n'y a que le nom de la procédure avec parenthèse ou crochets si j'ai un ou des arguments. Mais dans la grande majorité des cas j'ai des variables en début de procédure ce qui m'évite de devoir ajouter des arguments.

Les procédures appelées sont dans le module standard, celui qui appelle le userform.

Salut Heelflip

Tu nous dis

J'ai beaucoup de mal à identifier pourquoi, mais il arrive souvent que le programme s'arrête sans avoir exécuté les Call. Un point certain c'est en cas de bug, je sais que les Call ne fonctionneront pas. Pareil si je retourne dans le code et essayer de tester après, je dois quitter et ré-ouvrir, pourquoi, je ne sais pas...?

Je pense que tu as des instructions du style "Application.EnableEvents = False"

Donc si tu arrêtes un débogage, il est normal que plus rien ne fonctionne après !
Bien souvent, il suffit de saisir l'inverse "Application.EnableEvents = True" dans le fenêtre d'exécution pour que tout refonctionne

A+

Salut JExceL2fr,

Je n'ai aucun "Application.EnableEvents = False" il est assez rare que j'en utilise donc ce n'est pas le cas ici.

Cordialement.

Salut Heelflip,
Salut les devins,

car, sans fichier ni même une ligne ou 2 de code, comment diable veux-tu être aidé?

Bon, allons-y de notre petite voyance : n'y aurait-il pas un ou des...

On Error Resume Next

... qui cacheraient des erreurs aléatoires ? Ça m'est déjà arrivé!

Bonne recherche!
A+

Salut Curulis,

Je suis en train de l'adapter pour le poster justement, mais c'est assez chronophage

Je n'utilise jamais On Error Resume Newt justement pour éviter ce genre de bug qu'on ne voit pas

Merci pour l'idée.

Bonjour à tous,

En attendant le fichier,

Suivant les macros, si vous faites appel à d'autres App (comme Outlook pour l'envoi de mails), il est parfois nécessaire d'ajouter un DoEvents avant/après l'appel extérieur.

Comme indiqué par @LooReeD l'instruction "Call" est obsolète, et il me semble qu'elle fait évaluer les paramètres dans les parenthèses, ce qui pourrait planter avec les objets COM ?

Bonjour,

J’exécute un UserForm, qui me permet de recueillir des informations. Après validation je fait un Unload Me pour revenir au Module et enchainer le reste du code, dans ce dernier j'ai créé des Fonctions et des Sub pour simplifier mon code (Une fonction création de dossier Windows, et deux Sub pour envoi de mails). Je les appelle donc simplement avec un Call.

Le Call n'a rien à voir avec votre souci et ce, que vous le mettiez ou pas. Pour ma part j'utilise toujours le CALL pour qu'à la lecture du code ce soit plus visible que l'on fait appel à une procédure.

Par contre, le CALL est placé avant le UNLOAD Me je suppose ?
Essayez aussi de placé un point d'arrêt juste en regard de l'instruction CALL afin de voir si votre code s'arrête sur cette ligne lors de l'exécution. (Pour placer un point d'arrêt placé le curseur sur la ligne puis appuyez sur F9 de votre clavier. La ligne d'instruction se coloriera en brun.

Cordialement

Salut Dan,

Le call est placé après le unload, mais j'ai avant récupéré avec des variables mes infos.

Je vais regarder le point d'arrêt. Là je suis en train de fait un fichier test pour le poster ici mais c'est assez long à faire pour qu'il soit facilement exploitable par ceux qui veulent m'aider, le but étant de ne pas vous faire galérer étant donné que le fichier est assez complexe, le but est de reproduire le bug et franchement c'est pas si évident vu que c'est "aléatoire"

EDIT: J'ai cherché un point d'arrêt qui fonctionnait et j'ai trouvé le bon endroit... Dans mon module j'ai un petit bout de code qui dit que si j'appuie sur le bouton annuler du Userform, je quitte le Sub du module pour ne pas continuer le programme -> If T1_Quitter = 1 Then Exit Sub

Dans le code du userform j'ai ce code:

Private Sub btnQuitter_Click()

    'Fertemure de la fenêtre
    Unload Me
    T1_Quitter = 1

End Sub

Lors du test avec l'arrêt j'ai pu voir que ma variable T1_Quitter était égale à 1 et que j'ai donc quitté le programme. Pourtant, seul le code du dessus (Bouton quitter) utilise cette variable, il faut donc que je comprenne pourquoi, soit le programme passe par le Sub "Quitter" ce qui semble assez improbable, soit la variable passe à 1 quelque part...

Merci pour l'astuce en tout cas, d'un coup je franchis une étape

EDIT2: Bon... Ça y est j'ai trouvé le soucis. Quand je clique sur annuler, ma variable T1_Quitter passe à 1 et quitte le programme. Quand je relance le programme, ma variable est toujours à 1 donc une fois le userform unload, quand il arrive sur le code qui test la valeur de "T1_Quitter", il la trouve égale à 1 et ferme le programme...

Alors pourquoi ma variable reste à 1 ? Lorsque je code If T1_Quitter = 1 Then Exit Sub normalement je quitte le sub donc les variables ne sont pas censées être réinitialisées quand je relance le programme ? Est-ce parce que c'est une variable Public qu'elle ne revient pas a zéro ?

EDIT3: Désolé pour les pavés, j'ai relu les cours sur les variables et je pense que j'avais compris de travers... Le but de mes variables public c'est de récupérer des infos depuis le Userform et de les utiliser dans le module après le Unload du Userform. Aurais-je du utiliser du Static ou plutôt initialiser mes variables à zéro au lancement du programme ?

Bon... Et bien un grand merci à toi Dan, le simple bouton arrêt m'a permis de trouver l'erreur, je n'initialisais pas mes variables public croyant qu'elle étaient réinitialisés en début de programme, grosse erreur de ma part... Le problème semble réglé. Cette règle là je ne suis pas près de l'oublier.

Bonjour

Merci du retour.
Sans voir le projet, c'était difficile pour chacun de vous aider.

je n'initialisais pas mes variables public croyant qu'elle étaient réinitialisés en début de programme, grosse erreur de ma part...

En principe elles le sont. C'est une fonctionnalité de la variable Public . Le tout est de les placer en entête de module (donc avant tous les codes Sub...). Là on ne sait pas où vous les avez mises.
Attention avec ce type de variable Public (c'est souvent une erreur que je vois), vous devez garder en tête qu'un fois le fichier ouvert, elles sont initialisées et conservent toujours leur valeur (sauf si vous changez la valeur en cours de code)

Pour votre code, j'aurais plutôt placé l'instruction avant le Unload Me (à voir bien entendu si cela affecte quelque chose)

Cordialement

En effet c'est pour cela que j'étais en train de faire une version partageable mais plus nécessaire maintenant.

Mes variables Public sont placés en tête du module qui lance le Userform uniquement. Je démarre donc le module avec une initialisation des variables comme cela elle sont bien définies avant de lancer le programme.

En tout cas un grand merci pour la découverte de la fonction arrêt, je me galérais avec les tests ligne par ligne (F8 sur des boucles de 4000 valeurs ça peut être long...), alors que la je peux pointer ou je veux pour tester c'est vraiment intéressant.

Bonjour à tous,

Oui les breakpoints ainsi que l'explorateur de variables sont vraiment d'excellents outils (à utiliser sans modération). Petite astuce avec les breakpoints :

Mise en situation (très simple mais c'est pour l'exemple) :

Tu as une liste de 4000 variables et tu dois itérer dessus pour afficher 1/variable. Normalement, toutes tes variables sont <> 0. Mais sans trop savoir pourquoi quand tu lances le code ça plante avec une erreur div/0. Pour éviter le plantage (qui parfois peut faire crasher Excel, notamment si tu utilises des COM – ça m'est souvent arrivé avec AutoCAD), tu ajoutes avant la ligne qui va planter :

If mesvariables(i) = 0 Then 
    Debug.print i
End If

Et tu mets le breakpoint sur le Debug. Comme ça toutes les variables passent sans problème sauf celle qui va faire planter, et là ça t'arrête proprement le code et tu peux trouver pourquoi.

Pour info pour placer un breakpoint, une alternative est de simplement cliquer sur le bord gauche de la fenêtre de code (l'icône de souris se tourne vers la gauche sur la zone cliquable) et ça place un point. On peut lui recliquer dessus pour l'enlever.

image

J'ai fait un petit test pour voir et en effet c'est assez sympa, j'avais jamais trop compris le Debug merci pour le complément d'information

Rechercher des sujets similaires à "fonction call fonctionne pas"