XL 2021 Enregistrer les modifications faites par VBA sur un Userform

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

  • Nouveau Feuille de calcul Microsoft Excel (3).xlsm
    33.1 KB · Affichages: 13
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"...

Dudu2

XLDnaute Barbatruc
@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
 

Dudu2

XLDnaute Barbatruc
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.
 

patricktoulon

XLDnaute Barbatruc
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🤣🤣
 

Dudu2

XLDnaute Barbatruc
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:

Dudu2

XLDnaute Barbatruc
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:

Dudu2

XLDnaute Barbatruc
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.
 

Dudu2

XLDnaute Barbatruc
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

  • exemple userform memo couleur et position SetTimer.xlsm
    30.5 KB · Affichages: 2

Dudu2

XLDnaute Barbatruc
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.
 

Dudu2

XLDnaute Barbatruc
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
 

Discussions similaires

Statistiques des forums

Discussions
312 215
Messages
2 086 322
Membres
103 178
dernier inscrit
BERSEB50