XL 2010 Combobox liées

cathodique

XLDnaute Barbatruc
Bonjour,

Je voudrais lier les 3 combobox et que les 2 textboxs se complètent suivant les données des comboboxs.
Je sais que Dranreb a développé des modules de services dans ce sens.
Toute proposition est la bienvenue.

Avec mes remerciements anticipés.

Bonne journée.
 

Dranreb

XLDnaute Barbatruc
Pour ce qui est du fonctionnement interne, c'est via une invocation de Parent.CAM_Change Me depuis le CAsso spécifique.
Pour qu'il puisse être pris en charge dans l'UserForm il faut que le ControlsAssociés ait été déclaré avec l'attribut WithEvents, or il est relativement rare qu'on ait absolument besoin de se servir de ces évènements, donc on ne le met pas toujours.
Comme d'habitude la procédure de prise en charge s'installe à l'aide des listes déroulantes qui surmontent la fenêtre de code.
 
Dernière édition:

patricktoulon

XLDnaute Barbatruc
re
bonjour à tous
du coup je crois que l'on a perdu @cathodique ;) 🤣

j'ai lu jusqu’à la page 3 puis j'ai jumpé à la fin 🤯
c'est quoi le problème pour lier 2 combobox (voir lier aussi les textbox a ces combo pour leur click ou change )

perso moi aussi je pige pas la combo rubrique qui devrait être selon moi un textbox puisque il y a un seul item résultant des deux autres choix combo 1 et 2


10 lignes de code suffisent amplement dans un tout petit module classe pour faire ce genre de truc

sauf erreur de ma part et que je n'eusse pas compris la question ;)
 

Dranreb

XLDnaute Barbatruc
Donc, pour résumer, avec ça comme déclaration dans le Temp.xlsm :
VB:
Private WithEvents CLs As ComboBoxLiées, WithEvents CAs As ControlsAssociés, LCou As Long, TVL()
le CAs vient se trouver une place dans la liste de gauche, et dans celle de droite on a les Change, Click, KeyDown, KeyPress et KeyUp qui peuvent être installés.
 
Dernière édition:

laurent950

XLDnaute Accro
Re @Dranreb

J'ai trouvé un exemple qui peut résumer la classe CAsso

J'ai trouvé un aide qui explique l'implémentation :
J'ai donc adapté se code :

Donc une interface (VoitureInterface) représenterait toutes les caractéristiques communes
Peugeot et Renault (sont deux marques différentes) mais une voiture aura toujours :
Un Nom
Une Vitesse Maximum

Créer un module de classe interface : VoitureInterface / Entre les classes
VB:
'Class Nom : VoitureInterface
Public Nom As String
Public VitesseMax As Long
Public Sub ImpressionInfo(): End Sub

alors : Fichier exemple (V1) ci-dessous en relation avec le code
on créait 2 modules de Classes Peugeot et Renault
Pour implémenter la classe VoitureInterface
il faut cette instruction en en-têtes de ces deux modules de classes (Peugeot et Renault)
------->>>>> Implements VoitureInterface (A recopier)

' l'astuce est ici : VoitureInterface_ImpressionInfo
ce sera la connexion vers la classe VoitureInterface pour l'impression

Private Sub VoitureInterface_ImpressionInfo()
Debug.Print "Marque et modèle de voiture: " & VoitureInterface_Nom
Debug.Print "Vitesse maximale de la voiture: " & VoitureInterface_VitesseMax
End Sub

* Les Modules de Classes Peugeot et Renault (Ci-Dessous)

VB:
'Class nom : PeugeotClass
Implements VoitureInterface

'Variables pour l'implémentation de VoitureInterface, le préfixe n'a pas d'importance
Private i_Nom As String
Private i_VitesseMax As String
'L'implémentation des variables VoitureInterface nécessite l'implémentation des propriétés Let et Get
Private Property Let VoitureInterface_Nom(ByVal Nom As String)
    i_Nom = Nom
End Property
Private Property Get VoitureInterface_Nom() As String
   VoitureInterface_Nom = i_Nom
End Property
Private Property Let VoitureInterface_VitesseMax(ByVal VitesseMax As Long)
    i_VitesseMax = VitesseMax
End Property
Private Property Get VoitureInterface_VitesseMax() As Long
   VoitureInterface_VitesseMax = i_VitesseMax
End Property

'Implémentation des méthodes VoitureInterface.
Private Sub VoitureInterface_ImpressionInfo()
    Debug.Print "Marque et modèle de voiture: " & VoitureInterface_Nom
    Debug.Print "Vitesse maximale de la voiture: " & VoitureInterface_VitesseMax
End Sub

'Define Peugeot unique valeurs
Private Sub Class_Initialize()
    i_Nom = "Peugeot 3008"
    i_VitesseMax = "210"
End Sub


VB:
'Class nom : RenaultClass
Implements VoitureInterface

'Variables pour l'implémentation de VoitureInterface, le préfixe n'a pas d'importance
Private i_Nom As String
Private i_VitesseMax As String
'L'implémentation des variables VoitureInterface nécessite l'implémentation des propriétés Let et Get
Private Property Let VoitureInterface_Nom(ByVal Nom As String)
    i_Nom = Nom
End Property
Private Property Get VoitureInterface_Nom() As String
   VoitureInterface_Nom = i_Nom
End Property
Private Property Let VoitureInterface_VitesseMax(ByVal VitesseMax As Long)
    i_VitesseMax = VitesseMax
End Property
Private Property Get VoitureInterface_VitesseMax() As Long
   VoitureInterface_VitesseMax = i_VitesseMax
End Property

'Implémentation des méthodes VoitureInterface.
Private Sub VoitureInterface_ImpressionInfo()
    Debug.Print "Marque et modèle de voiture: " & VoitureInterface_Nom
    Debug.Print "Vitesse maximale de la voiture: " & VoitureInterface_VitesseMax
End Sub

'Define Renault unique valeurs
Private Sub Class_Initialize()
    i_Nom = "Renault Twingo 2"
    i_VitesseMax = "155"
End Sub


Le Module Standard pour faire fonctionner cette interface :
VB:
Sub Main()
    Dim Peugeot As New PeugeotClass
    Dim Renault As New RenaultClass
    Dim Voitures(0 To 1) As VoitureInterface
    Dim i As Integer

    Set Voitures(0) = Peugeot
    Set Voitures(1) = Renault

    'Print all car info
    For i = LBound(Voitures) To UBound(Voitures)
        Voitures(i).ImpressionInfo
    Next i
End Sub

@Dranreb j'ai trouvé l'explication sur ce site :

J'ai modifié le code du module standard tous simplement car il n'y a pas les listes après le Point
Voiture . PrintInfo

VB:
Sub Main()
    Dim Peugeot As New PeugeotClass
    Dim Renault As New RenaultClass
    Dim Voitures(0 To 1) As VoitureInterface, Voiture As Variant

    Set Voitures(0) = Peugeot
    Set Voitures(1) = Renault

    'Print all car info
    For Each Voiture In Voitures
        Voiture.PrintInfo
    Next Voiture
End Sub

Voici l'exemple :
dans la classe : VoitureInterface
Public Sub ImpressionInfo(): End Sub

Alors la question est la suivante :
Comment substituez-les (Let / Set / Get) des modules de classes : Peugeot et Renault
avec des fonctions pour ces 2 Modules de classes : Peugeot et Renault

Vous @Dranreb :
VB:
À la réflexion, il serait possible de la définir comme une variable Public dans l'interface. Mais dans ce cas, dans les classes qui l'implémentent, le contrôleur de classe réclamerait pour elle toutes les procédures Property possibles: Set, Let et Get. Or moi je veux qu'elle soit en lecture seule, et ne puisse être établie que par sa méthode Init, elle même invoquée par la méthode Add du ControlsAssociés.

Je poste les deux fichiers en rapport avec les exemples du site.
Peut on reproduire ce que vous dite dans l'encadré ci-dessus pour :
pour faire fonctionner cette interface comme vous le faite fonctionner votre interface CAsso en rapport avec ControlsAssociés

Dison que :
* CAsso c'est l'équivalent de VoitureInterface
* CAssoTBx (Private Function et Private Sub) et l'équivalent de Peugeot (Avec Let / Set / Get)
* ControlsAssociés (Je ne sais pas l'équivalent)

A partir de cet exemple Modules de Classes Peugeot et Renaut
Comment remplacer les (Let / Set / Get) par des Sub et Function

********************************************************************************************

Ps : Vous pouvez en créer la même choses dans le module de classe VoitureInterface

Public Sub Init ? () : End Sub
'

Function !!!() As ????: End Function
Function !!!() As ????: End Function
'
Puis aussi (J'ai pas compris cela ?)

Property Let Valeur(ByVal V): End Property
Property Get Valeur(): End Property

Je ne suis plus c'est dernière instruction pour les faires fonctionné, j'en n'ai pas l'idée ?


J'ai compris cela déjà... vous Pouvez Modifier le fichier V1 et l'adapter (Pour que je comprenne s'il vous plait @Dranreb) avec votre méthode propre à ce module de classe spécifique.

* Public Sub ImpressionInfo(): End Sub
'
Merci pour toute vos explication @Dranreb
 

Pièces jointes

  • Dranreb_Implement_Exemple_Tres_Simple_V0.xlsm
    19.1 KB · Affichages: 17
  • Dranreb_Implement_Exemple_Tres_Simple_V1.xlsm
    21.1 KB · Affichages: 3
Dernière édition:

patricktoulon

XLDnaute Barbatruc
re
Bonjour laurent
une classe d'object ou de valeur ou ce que tu veux ,peut se faire de différente manière

1°soit on la pilote d'un autre module que la classe et on instancie autant d'instance que le besoin et on peu utiliser le let/ set/ get
a l'aide d'un tableau ou d'une collection


2° soit on instancie une classe avec une fonction init dans la classe et dans la quelle on instanciera des sub classes pas forcement besoin de let/set/get , un set instancedeclasse.object = ... suffira (ps :eek:n vide les toute les instances en libérant l'instance 1 de la classe ça peut être avantageux ) ;)

pour l'exemple de tes voitures pour 2 property je me serais contenté d'une variable type
principe bien trop souvent oublié et qui est pourtant bien plus facile a maîtriser que les classes
et qui au final fonctionne exactement comme une classe

dans le contexte ou vous l'utilisez
exemple
VB:
Type typ
couleur As String
marque As String
'etc...
'etc...
End Type
Dim voiture() As typ ' tableau d'instance

Sub test()
Dim I&

marques = Array("renault", "peugeuot", "dacia", "BMW", "mercedes")
couleurs = Array("rouge", "verte", "bleu", "noire", "blanche")

ReDim Preserve voiture(0 To UBound(marques)) 'on redim le tableau d'intances du meme nombre que l'array des marques

Randomize
'instruction des instances
For I = LBound(voiture) To UBound(voiture)
voiture(I).marque = marques(I)
voiture(I).couleur = couleurs((Round(Rnd * (UBound(couleurs) - 1)))) ' je met les couleurs au hasard
Next
End Sub
Sub lecture()
'lecture des property
For I = 0 To UBound(voiture)
With voiture(I)
 MsgBox "la " & .marque & " est de couleur " & .couleur
End With
Next
End Sub

on peut même imbriquer des property avec des variables type aussi dans une liste de classe d’élève par exemple ou autre

les modules classe, perso c'est pour les controls ou object pour les quels on devrait gérer un ou plusieurs de leurs événement
 

cathodique

XLDnaute Barbatruc
re
bonjour à tous
du coup je crois que l'on a perdu @cathodique ;) 🤣

j'ai lu jusqu’à la page 3 puis j'ai jumpé à la fin 🤯
c'est quoi le problème pour lier 2 combobox (voir lier aussi les textbox a ces combo pour leur click ou change )

perso moi aussi je pige pas la combo rubrique qui devrait être selon moi un textbox puisque il y a un seul item résultant des deux autres choix combo 1 et 2


10 lignes de code suffisent amplement dans un tout petit module classe pour faire ce genre de truc

sauf erreur de ma part et que je n'eusse pas compris la question ;)
Bonjour,

@patricktoulon : Je suis désolé que tu aies écumé tous les posts de ce fil. Je me suis trompé en ouvrant cette discussion. Et, ici je pense que ça signifié que je laissais tomber car quelques soient les explications données. Je n'aurai rien compris de toutes les façons.
J'ouvrirai une autre discussion quand j'aurai fini de préparer le fichier à joindre.

Merci à tous.

Bon dimanche.
 

Dranreb

XLDnaute Barbatruc
Je dé
discussion. Et, ici je pense que ça signifié que je laissais tomber car quelques soient les explications données. Je n'aurai rien compris de toutes les façons.
Eh bien il fallait ensuite en poser d'autres qui vous auraient permis de les comprendre, je ne sais pas moi, qu'est ce que c'est qu'une classe, une propriété, une méthode, que signifient les mots clés Public et Private, mais bien sûr si au bout du compte ça ne vous intéresse pas et que vous ne voulez pas comprendre c'est votre problème, mais alors résignez vous à ne jamais rien programmer de sérieux ni simple du coté applicatif (la programmation de service ça ne compte pas, puisqu'on n'a jamais à la retoucher. Quoi qu'il en soit la mienne reste minuscule en terme de volume de programmation à coté de tout ce qui ne sert pratiquement jamais dans la bibliothèque Excel par exemple).
 

laurent950

XLDnaute Accro
Bonjour @patricktoulon, @Dranreb

J'ai trouvé un exemple, et je voulais simplement (enfin c'est pas si simple) de comprendre le chemin du code de @Dranreb.

Je te remercie @patricktoulon pour ces explications précieuse et qui montre d'autre solution. c'est vrais que la variable type est une solution.

Cela dit j'ai envie de comprendre cette solution qui serait de substituer les Let / Set / Get
Par la méthode @Dranreb

C'était le but de cette exemple vraiment très simple pour l'adapter au principe @Dranreb mais que je n'ai pas encore su réaliser

Merci @patricktoulon pour ta réponse, et aussi merci à @Dranreb pour le suivie de ce poste est les réponses apportées.

Peut être que @Dranreb poursuivra pour résoudre la fin de ce code et pour que je comprenne le fonctionnement avec la procédure Sub Init et fonctions.
 
Dernière édition:

patricktoulon

XLDnaute Barbatruc
c'est vrai que pour celui qui n'en a jamais fait il est difficile de faire la relation de classe ,d'instance,et "get/set/propertie"
mais c'est assez simple en fait
en simple on peut très bien faire la même chose avec une variable
disons que propertie nous permet d'avoir une variable(propriété ou méthode") complètement dynamique
lecture et écriture ou même d'un âne tu peux en faire un cheval de course
 

Dranreb

XLDnaute Barbatruc
@laurent950 L'intérêt c'est quand même que vu du coté utilisation l'objet soit du type du nom de l'interface. Il n'y a que l'expression qui l'initialise par un Set qui doit être du type spécifique approprié.
Vous voyez bien, dans l'objet ComboBoxLiées le TCAssos() global est un tableau de CAsso. C'est suffisant pour qu'on puisse et même doive lui affecter un objet qui l'implémente: New CAssoTBx ou New CAssoCkx etc. Et aussitôt qu'il est défini ainsi il est perçu de l'extérieur comme un CAsso banalisé, avec les méthodes et propriétés de l'interface. Le type exact n'est plus connu à priori de l'extérieur et conditionne seulement la façon exacte dont il fonctionne en interne.
Qu'est ce que vous ne comprenez pas dans les substitutions ?
C'est simple au lieu de déclarer des variables dans l'interface vous écrivez les procédures qu'il faudra, convenablement paramétrées mais vides de code, donc aussitôt suivies de leurs End TypeProc. Vous verrez qu'en l'implémentant dans une autre classe il vous sera réclamé les procédures correspondantes dont les modèles seront disponible dans les listes déroulantes Objet et Procédure au dessus de la fenêtre de code. À gauche vous trouvez le nom de la classe implémentée, à droite les noms des procédures à installer obligatoirement.
Comme pour les évènements leurs noms se retrouvera dans le code sous forme de Private TypeProc Classe_NomProc (avec TypeProc: Sub, Function ou Property Let, Get ou Set).
 
Dernière édition:

laurent950

XLDnaute Accro
Re @Dranreb

Votre classe CAsso"C'est Implémenter une classe abstraite" ?
J'ai traduit cela par ce cours ici :

Par contre j'ai pas compris cela : dans le Module de classe Polygone
' On peut donc éventuellement prévoir de générer une erreur dans la procédure _
Class_Initialize afin d'empêcher l'application de créer un objet qui serait _
vide de contenu et donc de sens.

Module standard : Main
VB:
Sub Test()
   Dim i As Long
   Dim P(1 To 2) As Polygone     'Déclare un tableau contenant 2 polygones
   Dim R As Rectangle
   Dim C As Cercle
 
   Set P(1) = New Rectangle      'Instancie un rectangle
   Set R = P(1)
   With R
      .Height = 10
      .Width = 20
   End With
 
   Set P(2) = New Cercle         'Instancie un cercle
   Set C = P(2)
   C.Ray = 10
 
   For i = 1 To 2
      Debug.Print "Surface: " & P(i).Surface & " Perimetre: " & P(i).Perimeter
   Next
End Sub

Module de classe : Polygone (C'est cette classe l'interface)
VB:
'Dans la classe Polygone
Public Function Perimeter() As Double
   'Renvoie le périmètre d'un Polygone
End Function

Public Function Surface() As Double
   'Renvoie la surface d'un Polygone
End Function

Private Sub Class_Initialize()
   Err.Raise vbObjectError + 50, , "Impossible de créer une instance de la classe Polygone"
End Sub


Module de classe : Rectangle
VB:
'Dans la classe Rectangle
    Implements Polygone
Public Height As Double    'Hauteur du rectangle
Public Width As Double     'Largeur du rectangle

Private Function Polygone_Perimeter() As Double
    Polygone_Perimeter = 2 * (Height + Width)
End Function

Private Function Polygone_Surface() As Double
    Polygone_Surface = Height * Width
End Function

'Dans les classes Cercle et Rectangle
Public Function Perimeter() As Double
   Perimeter = Polygone_Perimeter
End Function

Public Function Surface() As Double
   Surface = Polygone_Surface
End Function

Module de classe : Cercle
VB:
'Dans la classe Cercle
    Implements Polygone
Public Ray As Double       'Rayon du cercle

Private Function Polygone_Perimeter() As Double
    Polygone_Perimeter = Ray * 3.141592 * 2
End Function

Private Function Polygone_Surface() As Double
    Polygone_Surface = Ray * Ray * 3.141592
End Function

'Dans les classes Cercle et Rectangle
Public Function Perimeter() As Double
   Perimeter = Polygone_Perimeter
End Function

Public Function Surface() As Double
   Surface = Polygone_Surface
End Function
 

Discussions similaires

Membres actuellement en ligne

Statistiques des forums

Discussions
312 229
Messages
2 086 426
Membres
103 206
dernier inscrit
diambote