Les UserForms et la mémoire

Boostez vos compétences Excel avec notre communauté !

Rejoignez Excel Downloads, le rendez-vous des passionnés où l'entraide fait la force. Apprenez, échangez, progressez – et tout ça gratuitement ! 👉 Inscrivez-vous maintenant !

Eric_49

XLDnaute Junior
Bonjour,

On connaît tous les instructions Show et Load qui chargent un formulaire en mémoire et l'instruction Unload pour le décharger.

Cependant, certaines instructions chargent implicitement le formulaire en mémoire sans qu'on ne s'en aperçoive. Et si un code est placé dans l'évènement "Initialise", il sera exécuté lors de la 1ère instruction. L'évènement "Activate", quant à lui, ne sera pas appelé.

Pour exemple, l'instruction suivante, qui extrait le contenu du "Label1" du formulaire "UserForm1"
VB:
a$ = UserForm1.Label1.Caption
Charge le formulaire en mémoire. Il y restera tant qu'un "Unload" n'aura pas été effectué (explicite ou via un QueryClose).
Selon l'application et le nombre de formulaires utilisés, la mémoire peut, à un certain moment, être bien occupée.

Ce n'est pas un problème en soi ; la mémoire sera vidée, de toute façon, à la fermeture du classeur.

Cependant, il faudra être vigilant sur l'exécution du code placé dans l'évènement "Initialise" (si code présent).
En reprenant l'exemple :
Code:
a$ = UserForm1.Label1.Caption ' 1er appel au formulaire ; il est chargé en mémoire et l'Initialise est exécuté
...
Plus loin dans l'application
...
Code:
UserForm1.Show ' Affiche le Formulaire. Seul l'évènement "Activate" est exécuté.

Pour que le code d'initialisation soit réexécuté, il faudra le décharger de la mémoire avant (Unload UserForm1 avant le Show).

Un autre souci peut également survenir :

Si l'on souhaite enregistrer en "Dur" des données dans un formulaire, pour les récupérer à la prochaine ouverture du classeur, une erreur 91 "Variable objet ou variable de bloc With non définie" sera générée si celui-ci est en mémoire.

Il faudra s'assurer qu'il est bien déchargé avant d'exécuter l'instruction.

(L'usage d'un formulaire dédié, pour stocker des informations peut s'avérer très utile (Paramètres, dernières saisies, données diverses, etc.))

Dans le classeur joint, vous trouverez plusieurs macros explicatives sur le maniement des formulaires.
Exécutez le code en mode "Pas à Pas" en commençant par la procédure Test1.

J'espère que cela vous sera utile, surtout si vous débutez en VBA.

Eric

Ps : Pensez à débloquer le classeur après téléchargement.
 

Pièces jointes

Bonjour.
En fait c'est toute mention externe du UserForm pour quelque raison que ce soit qui provoque son chargement et son initialisation, comme s'il existait dans un module standard une déclaration Public UserForm1 As New UserForm1
 
bonjour pour le fait que le la classe (et je dis bien la classe) userform soit chargé a partir du moment ou tu modifie quoi que ce soit dedans sans même l'ouvrir,je suis d'accords et c'est tout a fait normal l'appel par nomuserform.quelquechose instancie implicitement une instance de classe userform

par contre le .initialise qui n'est pas executé apres un appel implicite + un show , je n'ai pas ce soucis chez moi office 2013 et 2016
je rappelle a toute fin utile que les modules userform sont des modules classe avant tout
 
bonjour pour le fait que le la classe (et je dis bien la classe) userform soit chargé a partir du moment ou tu modifie quoi que ce soit dedans sans même l'ouvrir,je suis d'accords et c'est tout a fait normal l'appel par nomuserform.quelquechose instancie implicitement une instance de classe userform

par contre le .initialise qui n'est pas executé apres un appel implicite + un show , je n'ai pas ce soucis chez moi office 2013 et 2016
je rappelle a toute fin utile que les modules userform sont des modules classe avant tout
Bonsoir Patrick

Si tu ajoute ce petit bout de code à la procédure Test1 et que tu fais du pas à pas (après réinit du projet)
VB:
With UserForm1             ' Charge l'Userform1 en mémoire et déclenche l'évènement "Initialise"
    Bck_color = .BackColor ' L'évènement "Activate" n'est pas exécuté
    a$ = .Label1.Caption   ' Le formulaire est déjà en mémoire, donc pas d'évènement
End With

' Plus loin dans la procédure (ou autre procédure)
UserForm1.Show ' Ici seul l'activate est exécuté puisque le form est encore en mémoire

Chez moi (Excel 2016) l'initialise n'est pas exécuté.

Ce petit tuto est principalement destinés aux néophytes ; je l'utilise dans mon association pour les démos.

On peut faire plus simple, pour ne pas avoir à décharger l'UserForm, comme par exemple :
Code:
With New UserForm1         ' Charge l'Userform1 en mémoire et déclenche l'évènement "Initialise"
    Bck_color = .BackColor ' L'évènement "Activate" n'est pas exécuté
    a$ = .Label1.Caption
End With                   ' Le formulaire est déchargé de la mémoire

Le New créé une nouvelle instance du formulaire qui est vidée au End With.
Cela demande une certaine attention, surtout si le code, entre le With et le End With, est très important et qu'il fait appel à d'autres formulaires ou d'autres procédures.

Bonne soirée

Eric.
 
Bonsoir @Eric_49
With New UserForm1 ' Charge l'Userform1 en mémoire et déclenche l'évènement "Initialise"
Bck_color = .BackColor ' L'évènement "Activate" n'est pas exécuté
a$ = .Label1.Caption
End With ' Le formulaire est déchargé de la mémoire
On est bien d'accord que cela ne touche en rien l'état de l'exemplaire Public par défaut nommé UserForm1 ?
 
Bonsoir @Eric_49

On est bien d'accord que cela ne touche en rien l'état de l'exemplaire Public par défaut nommé UserForm1 ?
Bonjour à tous,
Oui tout à fait, dans ce cas tout se passe dans l'instance créée par New, pas l'instance par défaut (https://learn.microsoft.com/en-us/o.../ms-vbal/189fb41b-cc3a-4999-a6d2-ba89f72d2870).
Par contre il faut bien faire attention à "qui l'on se réfère". Avec le With et les ".Propriétés" on est sûr de ne pas se tromper. Sinon il faut stocker la nouvelle instance dans un objet, comme une classe classique oui.

Personnellement je trouve assez paradoxal que les UF aient, par défaut, cette auto-instantiation. Ca n'a pas beaucoup de sens et je pense que d'avoir fait le choix simple de demander un "New" aurait permis à beaucoup de débutants de mieux comprendre certains soucis rencontrés, puisqu'à ce moment-là on comprend directement que l'on crée quelque chose de temporaire.
C'est pratique dans les modèles plus avancés avec factory ou autre mais en VBA c'est souvent contre intuitif cette auto-instantiation (à mon avis).
 
Bonsoir,

Pour conforter ce qui a été dit, on peut insérer ce bout de code dans le classeur de démo (Procédure Test1)
VB:
Dim Bck_color1 As Long, Bck_color2 As Long

With New UserForm1              ' Charge l'Userform1 en mémoire et déclenche l'évènement "Initialise"
    Bck_color1 = .BackColor     ' Sauve la couleur de l'arrière plan
    .BackColor = vbYellow       ' Modifie
    With UserForm1              ' Charge une autre instance du Form (déclenche l'Initialise)
        Bck_color2 = .BackColor ' Récupère la couleur d'arrière plan
    End With                    ' Cette instance n'est pas déchargée de la mémoire
End With                        ' Ferme la 1ère instance du Form

La valeur de Bck_color2 est bien la couleur d'arrière plan du formulaire telle qu'elle est définie dans les propriétés (= Bck_color1)

Bonne soirée
 
- Navigue sans publicité
- Accède à Cléa, notre assistante IA experte Excel... et pas que...
- Profite de fonctionnalités exclusives
Ton soutien permet à Excel Downloads de rester 100% gratuit et de continuer à rassembler les passionnés d'Excel.
Je deviens Supporter XLD

Discussions similaires

V
Réponses
2
Affichages
2 K
VOILLOT
V
D
Réponses
11
Affichages
8 K
D
P
Réponses
14
Affichages
3 K
T
Réponses
2
Affichages
1 K
Tsoin42
T
J
Réponses
4
Affichages
2 K
Jonathan1986
J
J
Réponses
2
Affichages
2 K
jimmy59940
J
Retour