Icône de la ressource

Collection module classe 2024 patricktoulon (classe controls) gérer Enter/exit TextBox 1.0 1.0

Dudu2

XLDnaute Barbatruc
MsgBox Classe.Child(2).CallerUserForm.Classe.Name -> nom de la classe mère
MsgBox Me.Classe.Child(2).Name -> nom de la classe fille
Ce n'est pas du tout la même chose.
 

patricktoulon

XLDnaute Barbatruc
ce qui veut dire aussi que c'est faire des trucs pour rien
autant utiliser simplement une variable publique direct de l'userform
MsgBox Classe.Child(2).CallerUserForm.Classe.Name -> nom de la classe mère
MsgBox Me.Classe.Child(2).Name -> nom de la classe fille
Ce n'est pas du tout la même chose.

CallerUserForm.Classe référence la classe mère, celle-là:
Regarde la pièce jointe 1204234
oui j'ai corrigé je sais
 

Dudu2

XLDnaute Barbatruc
CallerUserForm.Classe référence la classe mère, celle-là:

1727603613101.png


C'est comme si tu faisais UserForm1.Classe

Mais pour être générique on ne peut pas référencer un nom réel de UserForm qui peut varier.
Donc on transmet l'objet UserForm CallerUserForm initialement défini à UserForm1 à toutes les instances et c'est cet objet qui est utilisé pour qualifier la Classe Public dans le UserForm. UserForm1.Classe -> CallerUserForm.Classe
 
Dernière édition:

patricktoulon

XLDnaute Barbatruc
C'est comme si tu faisais UserForm1.Classe
tu a tout dis
mais c'est bien je trouve d'échanger comme ça

maintenant essaie d'ajouter une propriété ou un membre appelle ça comme tu veux par exemple "age"
donne un age a la fille(2) par exemple et de la lire dans la classe de la fille(3)
et cela dans la classe sans aller chercher le userform ;)
 

Dudu2

XLDnaute Barbatruc
donne un age a la fille(2) par exemple et de la lire dans la classe de la fille(3)
Alors je n'ai pas eu ce cas dans le code Exit/Enter mais c'est possible puisque dans toutes les instances filles tu as accès à l'instance mère (celle Public du UserForm) qui stocke toutes les instances filles dans sa Collection Child.

Disons que fille(2) a 35 ans et tu es dans l'exécution de l'instance fille(3).
AgeFille2 = Me.CallerUserForm.Classe.Child(2).Age

et cela dans la classe sans aller chercher le userform
Si tu ne peux pas passer par l'instance mère (celle Public du UserForm) tu ne peux rien faire car aucun lien n'existe entre les filles. Et la liste des filles n'est connue que de l'instance mère du UserForm via la Collection Child.

D'ailleurs il y a un lien Mère -> Fille(s) grâce à la Collection Child.
Mais il n'y a aucun lien direct Fille(s) -> Mère ni Fille(s) -> Fille(s).
Créer ce lien direct reviendrait à retomber dans la problème des instances qui ne se terminent pas car faisant référence à d'autres instances non terminées.

Dans le fichier du post #39, toutes les instances mère et filles se terminent automatiquement à la fermeture du UserForm précisément parce qu'il n'y a aucun lien croisé d'instances.
 
Dernière édition:

Dudu2

XLDnaute Barbatruc
Dans le fichier du post #39, toutes les instances mère et filles se terminent automatiquement à la fermeture du UserForm précisément parce qu'il n'y a aucun lien croisé d'instances.
Encore que si on voulait vraiment chercher l'embrouille, il y a un lien entre l'instance mère du UserForm et les instances filles qui sont dans la collection de l'instance mère.

Alors pourquoi Exel accepte de terminer l'instance mère alors qu'elle fait référence à des instances filles non encore terminées, je ne sais pas. Mais c'est tant mieux pour notre affaire.
 

patricktoulon

XLDnaute Barbatruc
re
Si tu ne peux pas passer par l'instance mère (celle Public du UserForm) tu ne peux rien faire car aucun lien n'existe entre les filles. Et la liste des filles n'est connue que de l'instance mère du UserForm via la Collection Child.
voila...!! on y arrive ;)
avec mon modele oui
 

patricktoulon

XLDnaute Barbatruc
mais d"ans tout les cas
j'ai essayé de refaire un enter exit
et comme je l'ai dis tout a l'heure
l’accès au calleruserform.classe.oldcontrol n'est pas possible
chez moi calleruserform c'est "uf"
pour le coup je n'ai mis que 4 textbox dans mon userform juste pour le test
et d
"ans l’exécution de résultat de l'instance de classe du textbox
j'"ai une erreur sur uf.classe.oldcontrol qui ne gère pas l'object
exmple
le module classe
VB:
Public WithEvents TXTB As MSForms.TextBox
Public child As New Collection
Public OldControl As Object
Public uf As UserForm
Public nam As String
Public Function init(usf As UserForm)
    Dim cla As Classe1
    For Each ctrl In usf.Controls
        Set cla = New Classe1
        Set cla.TXTB = ctrl
        Set cla.uf = usf
        cla.nam = ctrl.Name
          Set Me.OldControl = usf.Controls(0)
        Me.child.Add cla
    Next
'MsgBox uf.classe.nam
End Function

Private Sub TXTB_KeyUp(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer): resultat: End Sub
Private Sub TXTB_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal x As Single, ByVal y As Single): resultat: End Sub

Private Sub resultat()
    Dim ControlIn As Object, ControlOut As Object
     Set ControlIn = uf.ActiveControl
    Set ControlOut = uf.ClaSSe.OldControl 'paff!! ca plante ici
    'envoie aux pseudo events
    If Not uf.ClaSSe.ControlOut Is Nothing Then
    If ControlIn.Name <> ControlOut.Name Then
        Control_Exit uf.Controls(ControlOut.Name)
        Control_Enter uf.Controls(ControlIn.Name)
    End If
   End If
   'on met a jour oldcontrol avec le control actif pour le prochain tour
    Set uf.ClaSSe.OldControl = ControlIn
End Sub

'les faux events Exit et Enter
Sub Control_Enter(ctrlY)
    Cells(Rows.Count, 1).End(xlUp).Offset(1) = " Enter : " & ctrlY.Name
End Sub
Sub Control_Exit(ctrlX)
    Cells(Rows.Count, 1).End(xlUp).Offset(1) = " Exit : " & ctrlX.Name
End Sub


Private Sub Class_Initialize()
End Sub

Private Sub Class_Terminate()
Cells(Rows.Count, 1).End(xlUp).Offset(1) = "classe " & Me.nam & "  terminée"
End Sub

le userform
VB:
Public ClaSSe As Classe1

Private Sub UserForm_Activate()
Set ClaSSe = New Classe1
ClaSSe.nam = "mère"
Me.ClaSSe.init Me
End Sub
alors si tu ouvre le userform et le ferme on voit bien les classes se fermer CA IL N Y A PAS DE SOUCIS
mais en ce qui concerne le membre oldcontrol qui change a chaque changement ben c'est mort j'ai tout essayé rien y fait je plante toujours là
Set ControlOut = uf.ClaSSe.OldControl 'paff!! ca plante ici
pour tant
1727608810775.png

je joins le classeur exemple
 

Pièces jointes

  • test new methode .xlsm
    17.4 KB · Affichages: 0

patricktoulon

XLDnaute Barbatruc
autant pour moi je match
Code:
Public WithEvents TXTB As MSForms.TextBox
Public child As New Collection
Public OldControl As Object
Public uf As Object
Public nam As String
Public Function init(usf As Object)
    Dim cla As Classe1
    For Each ctrl In usf.Controls
        Set cla = New Classe1
        Set cla.TXTB = ctrl
        Set cla.uf = usf
        cla.nam = ctrl.Name
        Set Me.OldControl = cla.uf.Controls(0)
        Me.child.Add cla
    Next
    'MsgBox uf.classe.nam
End Function

Private Sub TXTB_KeyUp(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer): resultat: End Sub
Private Sub TXTB_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal x As Single, ByVal y As Single): resultat: End Sub

Private Sub resultat()
    Dim ControlIn As Object, ControlOut As Object
    Set ControlIn = uf.ActiveControl
    Set ControlOut = uf.ClaSSe.OldControl 'paff!! ca plante ici
    'envoie aux pseudo events
    If Not ControlOut Is Nothing Then
        If ControlIn.Name <> ControlOut.Name Then
            Control_Exit uf.Controls(ControlOut.Name)
            Control_Enter uf.Controls(ControlIn.Name)
        End If
    End If
    'on met a jour oldcontrol avec le control actif pour le prochain tour
    Set uf.ClaSSe.OldControl = ControlIn
End Sub

'les faux events Exit et Enter
Sub Control_Enter(ctrlY)
    Cells(Rows.Count, 1).End(xlUp).Offset(1) = " Enter : " & ctrlY.Name
End Sub
Sub Control_Exit(ctrlX)
    Cells(Rows.Count, 1).End(xlUp).Offset(1) = " Exit : " & ctrlX.Name
End Sub


Private Sub Class_Initialize()
End Sub

Private Sub Class_Terminate()
    Cells(Rows.Count, 1).End(xlUp).Offset(1) = "classe " & Me.nam & " terminée"
End Sub
il faut que la classe instanciée dans l'userform soit en public
c'est une solution
 

patricktoulon

XLDnaute Barbatruc
du coup pour le fun j'ai refait le mien
au final je remplace memoire.oldcontrold par uf.ClaSSe.oldcontrol
et voila

VB:
Option Explicit
Public WithEvents TXTB As msforms.TextBox
Public WithEvents bouton As msforms.CommandButton
Public WithEvents opt As msforms.OptionButton
Public WithEvents Check As msforms.CheckBox
Public WithEvents toggle As msforms.ToggleButton
Public WithEvents LstBox As msforms.ListBox
Public WithEvents Combo As msforms.ComboBox
Public WithEvents Image As msforms.Image
Public WithEvents spin As msforms.SpinButton
Public WithEvents multi As msforms.MultiPage
Public WithEvents fram As msforms.Frame
Public WithEvents forme As UserForm
'Public WithEvents lsView As msforms.ListView
Public child As New Collection
Public OldControl As Object
Public uf As Object
Public nam As String
Public Function init(usf As Object)
    Dim cla As Classe1, CtrL
    For Each CtrL In usf.Controls
     Set cla = New Classe1
      If TypeOf CtrL Is TextBox Or TypeName(CtrL) = "TextBox" Then: Set cla.TXTB = CtrL: CtrL.Value = CtrL.Name
        If TypeOf CtrL Is OptionButton Or TypeName(CtrL) = "OptionButton" Then Set cla.opt = CtrL
        If TypeOf CtrL Is CommandButton Or TypeName(CtrL) = "CommandButton" Then Set cla.bouton = CtrL
        If TypeOf CtrL Is CheckBox Or TypeName(CtrL) = "CheckBox" Then Set cla.Check = CtrL
        If TypeOf CtrL Is ToggleButton Or TypeName(CtrL) = "ToggleButton" Then Set cla.toggle = CtrL
        If TypeOf CtrL Is ListBox Or TypeName(CtrL) = "ListBox" Then Set cla.LstBox = CtrL
        If TypeOf CtrL Is ComboBox Or TypeName(CtrL) = "Combobox" Then Set cla.Combo = CtrL
        If TypeOf CtrL Is Image Or TypeName(CtrL) = "Image" Then Set cla.Image = CtrL
        If TypeOf CtrL Is Frame Or TypeName(CtrL) = "Frame" Then Set cla.fram = CtrL
        If TypeOf CtrL Is SpinButton Or TypeName(CtrL) = "SpinButton" Then Set cla.spin = CtrL
        If TypeOf CtrL Is MultiPage Or TypeName(CtrL) = "multipage" Then Set cla.multi = CtrL
         Set cla.uf = usf
        cla.nam = CtrL.Name
        Set Me.OldControl = cla.uf.Controls(0)
        Me.child.Add cla
    Next
  End Function

Private Sub TXTB_KeyUp(ByVal KeyCode As msforms.ReturnInteger, ByVal Shift As Integer): resultat: End Sub
Private Sub opt_KeyUp(ByVal KeyCode As msforms.ReturnInteger, ByVal Shift As Integer): resultat: End Sub
Private Sub bouton_KeyUp(ByVal KeyCode As msforms.ReturnInteger, ByVal Shift As Integer): resultat: End Sub
Private Sub Combo_KeyUp(ByVal KeyCode As msforms.ReturnInteger, ByVal Shift As Integer): resultat: End Sub
Private Sub LstBox_KeyUp(ByVal KeyCode As msforms.ReturnInteger, ByVal Shift As Integer): resultat: End Sub
Private Sub image_KeyUp(ByVal KeyCode As msforms.ReturnInteger, ByVal Shift As Integer): resultat: End Sub
Private Sub toggle_KeyUp(ByVal KeyCode As msforms.ReturnInteger, ByVal Shift As Integer): resultat: End Sub
Private Sub Check_KeyUp(ByVal KeyCode As msforms.ReturnInteger, ByVal Shift As Integer): resultat: End Sub
Private Sub spin_KeyUp(ByVal KeyCode As msforms.ReturnInteger, ByVal Shift As Integer): resultat: End Sub
Private Sub LsView_KeyUp(KeyCode As Integer, ByVal Shift As Integer): resultat: End Sub

'les events mouse_Down
Private Sub bouton_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal x As Single, ByVal y As Single): resultat: End Sub
Private Sub opt_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal x As Single, ByVal y As Single): resultat: End Sub
Private Sub TXTB_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal x As Single, ByVal y As Single): resultat: End Sub
Private Sub LstBox_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal x As Single, ByVal y As Single): resultat: End Sub
Private Sub Combo_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal x As Single, ByVal y As Single): resultat: End Sub
Private Sub toggle_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal x As Single, ByVal y As Single): resultat: End Sub
Private Sub Check_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal x As Single, ByVal y As Single): resultat: End Sub
Private Sub image_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal x As Single, ByVal y As Single): resultat: End Sub
Private Sub Multi_MouseDown(ByVal Index As Long, ByVal Button As Integer, ByVal Shift As Integer, ByVal x As Single, ByVal y As Single): resultat: End Sub
Private Sub fram_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal x As Single, ByVal y As Single): resultat: End Sub
Private Sub LsView_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal x As stdole.OLE_XPOS_PIXELS, ByVal y As stdole.OLE_YPOS_PIXELS): resultat: End Sub
Private Sub Spin_SpinDown(): resultat: End Sub
Private Sub Spin_SpinUp(): resultat: End Sub

Private Sub resultat()
    Dim ControlIn As Object, ControlOut As Object
    Set ControlIn = uf.ActiveControl
    Set ControlOut = uf.ClaSSe.OldControl 'paff!! ca plante ici
    'envoie aux pseudo events
    If Not ControlOut Is Nothing Then
        If ControlIn.Name <> ControlOut.Name Then
            Control_Exit uf.Controls(ControlOut.Name)
            Control_Enter uf.Controls(ControlIn.Name)
        End If
    End If
    'on met a jour oldcontrol avec le control actif pour le prochain tour
    Set uf.ClaSSe.OldControl = ControlIn
End Sub

'les faux events Exit et Enter
Sub Control_Enter(ctrlY)
    Cells(Rows.Count, 1).End(xlUp).Offset(1) = " Enter : " & ctrlY.Name
End Sub
Sub Control_Exit(ctrlX)
    Cells(Rows.Count, 1).End(xlUp).Offset(1) = " Exit : " & ctrlX.Name
End Sub


Private Sub Class_Initialize()
End Sub

Private Sub Class_Terminate()
    Cells(Rows.Count, 1).End(xlUp).Offset(1) = "classe " & Me.nam & " terminée"
End Sub
même si je n'aime pas trop me ballader de module en module avec des variables surtout si c'est des classes ,je dois reconnaitre que ca fonctionne

merci pour cet échange👍
 

Dudu2

XLDnaute Barbatruc
Cool ! C'est la classe ! :cool:
Juste une petite remarque...
Vu que le Child ne sera une Collection que sur l'instance mère UserForm tu peux le déclarer en
Public child As Collection
et faire le seul New au début de la fonction init().
 
Dernière édition:

patricktoulon

XLDnaute Barbatruc
oui
ho mais c'est qu'il devient bon le dudu là 😁

je remet la condition textbox pour controlIN et ControlOut
VB:
Private Sub resultat()
    Dim ControlIn As Object, ControlOut As Object
    Set ControlIn = uf.ActiveControl
    Set ControlOut = uf.ClaSSe.OldControl 'paff!! ca plante ici
    'envoie aux pseudo events
    If Not ControlOut Is Nothing Then
        If ControlIn.Name <> ControlOut.Name Then
            If TypeName(ControlOut) = "TextBox" Then Control_Exit uf.Controls(ControlOut.Name)
            If TypeName(ControlIn) = "TextBox" Then Control_Enter uf.Controls(ControlIn.Name)
        End If
    End If
    'on met a jour oldcontrol avec le control actif pour le prochain tour
    Set uf.ClaSSe.OldControl = ControlIn
End Sub

ca sera une version alternative V 5
 

Pièces jointes

  • classe ENTER EXIT V 5 patricktoulon.xlsm
    23.5 KB · Affichages: 1
Dernière édition:

Statistiques des forums

Discussions
315 090
Messages
2 116 106
Membres
112 661
dernier inscrit
ceucri