XL 2021 Enregistrer les modifications faites par VBA sur un Userform

  • Initiateur de la discussion Initiateur de la discussion mojales
  • Date de début Date de début

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 !

mojales

XLDnaute Nouveau
Bonjour à tous,

Je cherche une solution afin de faire une modification permanente d'un Userform, plus particulièrement des propriérés d'un Userform.
Je m'explique :
Dans mon programme j'ai plusieurs Userform, chacun possède plusieurs buttonCommand.
Avec un module de classe, j'ouvre une macro a chaque click qui permet de changer le caption et/ou le backcolor.

Par contre, je ne sais pas comment faire pour enregistrer ces modifications lors de la réouverture du fichier.
A chaque nouvelle ouverture du fichier, les modifications sont perdues et le Userform s'initialise comme à l'origine.

Je vous ai joint une partie du fichier pour comprendre ma demande.

Merci à vous.

Mojales
 

Pièces jointes

Solution
Bonjour @mojales 🙂, @patricktoulon 😉,

Une solution possible qui utilise une feuille "très cachée" pour stocker la couleur de fond, la couleur du texte et le caption des commanbuttons de l'userform "Userform1".
Le code est relativement simple, concis et je pense assez compréhensible.

Module de classe "classe1" :
  • on stocke le nom du contrôle sur lequel on a cliqué
  • on lance l'userform "Statuts"

Userform "Statuts" :
  • suivant l'option choisie, on applique les nouvelles couleurs ou le nouveau texte au commandbutton sur lequel on a cliqué
  • et on sauvegarde les couleurs appliquées ou le nouveau caption du bouton sur lequel on a cliqué sur la feuille cachée "userform"...
@mapomme, ah oui, intéressant et potentiellement utile.

Pour moi le OnTime Now sous la seconde c'est une découverte !
Si je l'eu su plus tôt j'en eu m'être servi avant ! Mince alors !
Par contre il faut tester avant car chez moi + 0.000005 c'est 1/10ème et + 0.00001 ça varie de presque rien à 1 seconde.
VB:
Option Explicit

Dim t As Single

Sub a()
    Application.OnTime Now + 0.000005, "b"
    'Application.OnTime Now + 0.00001, "b"
    'Application.OnTime Now + TimeSerial(0, 0, 1), "b"
    t = Timer
End Sub

Sub b()
    MsgBox Format(Timer - t, "0.00")
End Sub
 
Un arrondi au 1/100ème ça me suffit car si je temporise je n'irai jamais au 1/1.000ème ou 1/10.000ème.
De toutes façons, ce test permet finalement de voir que le OnTime Now + X déclenche un peu quand il veut avant l'échéance fixée. Par exemple Application.OnTime Now + TimeSerial(0, 0, 1), "b" c'est en gros entre 1/2 seconde et 1 seconde et parfois bien moins.
 
tiens allez une demo encore plus dingue et en plus je suis quasiment sur que ca va t'intérésser
on va prendre 2 userform dans les quels je vais mettre deux bouton à chacuns
1693250858955.png

dans le userform1 je met ce code
VB:
Public WithEvents bt As msforms.CommandButton
Dim cls(1 To 4) As New UserForm1

Private Sub CommandButton2_Click()
UserForm2.Show 0
Set cls(1).bt = UserForm2.Controls(0)
Set cls(2).bt = UserForm2.Controls(1)
End Sub

Private Sub UserForm_Activate()
Set cls(1).bt = Me.Controls(0)
Set cls(2).bt = Me.Controls(1)
End Sub

Private Sub bt_Click()
MsgBox " je suis dans le " & bt.Parent.Name
End Sub

dans le userform2 jet rien du tout comme code

je lance le userform1
et je lance le userform2 a partir du userform1
et je clique sur tout les boutons du 1 et du 2
demo.gif


🤣🤣🤣🤣🤣🤣
en fait pas si dingue ça un module classe sert à ça non🤣🤣
 
Bonjour les enregistreurs de UserForm,
Je reviens sur OnTime en ayant fait cette petite expérience intéressante.
Le OnTime ne se déclenche pas avant la terminaison du Sub a().
Edit: Seul un DoEvents peut permettre l'exécution de Sub b() avant la fin de Sub a().

C'est ce qui me fait dire qu'une séquence de Unload de UserForm, qui en plus doit être protégée dans sa continuité sinon ce serait le chaos dans Excel, ne laissera pas démarrer un OnTime avant la fin de son exécution.

Edit: Alors certes, dans le QueryClose(), le processus d'Unload n'a pas commencé, mais il commence dès lors que l'on quitte le QueryClose() sans Cancel, ce qui se produit après le OnTime. Ça introduit quand même un petit doute sur le synchronisme du Unload à la sortie du QueryClose() !

VB:
Option Explicit

Dim t As Single

Sub a()
    Dim i As Long
 
    Application.OnTime Now, "b"
    t = Timer
    For i = 1 To 100000
        'DoEvents
        Range("A" & i) = i
    Next i
End Sub

Sub b()
    MsgBox Format(Timer - t, "0.00")
End Sub
 
Dernière édition:
Je ne sais pas ce que tu veux démontrer avec ce classeur.
Si on retire la temporisation, ça continue de fonctionner, comme prévu, et chez toi aussi j'en suis sûr.
VB:
Sub memoattente()
    'Application.OnTime Now + 0.000005, "memo"
    Application.OnTime Now, "memo"
End Sub
Tu dis ne pas pouvoir capter la fin du Unload. Et pourquoi devrait-on le faire ?
Pourquoi ne pas vouloir aussi capter la fin de l'affectation des valeurs d'un Range dans une table t = range("A10:B10000") ?
On n'en a rien à faire. Excel fait son boulot. Tu ne t'imagines quand même pas pouvoir exécuter du code au milieu du process Excel de l'Unload avec un OnTime ! Si c'était seulement possible, ce serait la cata.
 
Dernière édition:
La preuve en est que si on place un Timer dans ta séquence:
Code:
Public tbl(1 To 100, 1 To 5)

Dim t As Single

Sub memoattente()
    'Application.OnTime Now + 0.000005, "memo"
    Application.OnTime Now, "memo"
    t = Timer
End Sub

Sub memo()
    Dim uf As vbcomponent, i&
    [A1].Value = Format(Timer - t, "0.00")
On récupère toujours une valeur positive (chez moi de l'ordre d'1/10ème de seconde).
Ce temps correspond à l'exécution du Unload.
Car si ce n'était pas la cas, ce temps serait = zéro puisque le OnTime est sans temporisation.
 
Si tu restes préoccupé par la fin de l'Unload, alors moi non plus je ne peux plus rien pour toi.

Et preuve supplémentaire, j'ai remplacé ton OnTime par un SetTimer API qui lui n'est pas un tendre en matière d'interruption.
-> SetTimer à 1 millisecondes
-> Intervalle résultat toujours de l'ordre du 1/10ème de seconde (soit 100 millisecondes)
D'où vient la différence selon toi ?
Et toujours par de plantage, preuve que l'Unload est terminé.
VB:
Public tbl(1 To 100, 1 To 5)

Dim t As Single

Sub memoattente()
    'Application.OnTime Now + 0.000005, "memo"
    'Application.OnTime Now, "memo"
    Call SetTheTimer(1, "memo")
    t = Timer
End Sub

Sub memo()
    Dim uf As vbcomponent, i&
    [A1].Value = Format(Timer - t, "0.000")
 

Pièces jointes

l'accès au "Designer" est impossible si une instance de l'userform sous quelque forme que ce soit est en mémoire
je suis catégorique
Ben oui ! Je suis d'accord. Tu n'as pas besoin de l'écrire en rouge taille 26.
Mais ce n'est pas du tout la question que je n'évoque plus car pour moi c'est bouclé et ça sert à rien de faire diversion avec des points annexes pour simplement polémiquer sans fin.
 
ca fonctionne par ce que chez toi la gestion d'attente n'est pas nécessaire (et tant mieux pour toi)
moi aussi je t'ai prouvé en video en plus que chez moi et même au boulot sans
Tu l'as "prouvé" avec un fichier bancale sur des On Error je sais pas quoi...
Est-ce que tu as essayé le fichier du Post #11 qui lui tient la route ?
Si tu me rapportes que ce fichier ne fonctionne pas chez toi alors je commencerai à douter en voulant le voir en TeamViewer !
1693317802464.gif
 
- 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

Retour