Bonjours, Ms et Mrs les windeveurs.
Aujourd'hui je vais vous parler d'un outils incontournable dans windev, le Groupware Utilisateur alors nous allons commencer par savoir ce qu'est ce Groupware et ce qu'il fait
Groupware Utilisateur??
C'est le module de windev qui s'occupe de la gestion des utilisateurs et de leurs droits dans le logiciel.Son fonctionnement est simple. Il énumère tous les champs et fenêtres et vous donne une interface bien aboutis pour gérer les droit d’accès des utilisateur ou des groupes.
Les informations sont par la suite enregistrée dans des tables de base de données crypté. Le reste, il le fait tout seul.
au premier lancement, le système crée automatiquement un utilisateur avec les droit de super administrateur (Superviseur) avec login et mot de passe par défaut (superviseur/superviseur)
C'est à partir de lui que vous commencer à créer des utilisateurs, des groupes et de gérer leurs droits.
Par exemple
Vous creez un utilisateur "X", et vous indiquez que "X" ne doit pas voire le bouton "BTN_b" dans la fenêtre "Fen_F". lorsque Mr "X" ouvre le logiciel avec son login et mot de passe, il ne trouve pas le bouton "BTN_b" dans la fentre "FEN_F"
Comment intégrer le groupware utilisateur??
C'est trés simple. Même plus simple que tous ce que vous imaginez. Allez dans le menu "Atelier->Paramétrer le Groupware utilisateur", Une interface apprêt avec 3 onglets(générale, fichier,LDAP).
Dans l'onglet "générale" vous cochez "Activez la gestion du groupware utilisateur" pour l'activer et puis vous choisissez intégration par défaut ou personnalisable.
Je vous conseille l'intégration personnalisable, celle ci vous ajoute les interfaces du groupware afin de les modifier et c'est d’ailleurs la partie la plus intéressante.
Et après y'a démarrage automatique ou manuel.
le démarrage automatique lance le groupware sans aucun appel au lancement de l'application mais avec le démarrage manuelle, vous choisissez le moment du lancement avec l'appel de la fonction "gpwlogin".
Je vous laisse avec les 2 autres onglets faire ce qui vous semble le mieux et maintenat nous allons passer à la personnalisation du groupware.
les interfaces du groupware
Comment je vous l'ai déjà dis, l'integration personnalisé vous ajoute les interfaces du groupeware et nous allons les voir rapidement:GPWLogin
c'est la première interface, et celle qui est ouverte lors du lancement du groupware
Vous pouvez dés à présent modifier son apparence et même son comportement si vous le souhaitez. Il suffit de parcourir les élément de l'interface et son code afin de comprendre son fonctionnement. Nous verrons plus de détails par la suite mais pour la personnalisation de l'affichage c'est simple. Vous pouvez obtenir un résultat semblable à celui si sans effort.
GPWMenuSuperviseur
Cette interface appert lorsque l'utilisateur ce connecte avec un compte Superviseur.
Rien de compliqué, y a pas grand chose à modifier dans cette interface, juste les textes et l'apparence.
Inutile de vous expliquez à quoi sert chaque bouton mais je doit notifier que le bouton "Configurer le groupware" ouvre la partie de la gestion des utilisateurs et donc l'interface suivante est "GPWAssociationConfiguration"
GPWAssociationConfiguration
Cette interface est très importante. c'est celle à partir de laquelle on peut choisir le groupe de chaque utilisateur et définir ses paramètres.
on peut y appliquer quelques modification au niveau du comportement. afin d’empêcher un utilisateur de se supprimer lui même ou alors de s'enlever les mode superviseur.
nous y reviendrons plus tard pour ça.
GPWDetailsConfiguration
Son utilisation est un peut difficile pour les client (utilisateurs finaux de l'application) à cause de l’énumération des champs et des fenêtres qui sont affichés selon leurs noms physiques. Alors si vous utilisez une nomination qui n'est pas très claires, vos clients ferons appel à vous à chaque fois qu'ils ont besoin de changer les droit d'un utilisateur. Nous allons nous occupez plus tard de la rendre plus simple et plus compréhensible à utiliser.
GPWChoixConfiguration
Y a pas grand choses à dire sur cette interface. Modifiez simplement son apparence.
GPWFicheConfiguration
Encore la y a pas grand chose à dire. cette interface s'occupe de l'ajout et la modification d'un groupe.
GPWFicheUtilisateur
Cette interface à de l'importance. c'est celle ou on ajoute et on modifie les paramètres généraux d'un utilisateur.
La structure de la base de données du groupware
la base de donnée est constitué de 5 tables.
GPWConfiguration
Caractéristiques des rubriques :
Nom | Explication | Type | Taille | Clé |
---|---|---|---|---|
Configuration | Nom du groupe d'utilisateurs ou de l'utilisateur | Chaîne de caractères | 255 caractères | Unique |
Application | Nom de l'application | Chaîne de caractères | 255 caractères | Avec doublons |
Groupe | Définit si la configuration correspond à un groupe d'utilisateurs ou à un utilisateur | Booléen | ||
Groupe_Configuration | Clé composée des rubriques Groupe et Configuration | Clé composée | Unique | |
Application_Configuration | Clé composée des rubriques Application et Configuration | Clé composée | Avec doublons |
GPWConfigurationElément
Caractéristiques des rubriques :
Nom | Explication | Type | Taille | Clé |
---|---|---|---|---|
Configuration | Nom du groupe d'utilisateurs ou de l'utilisateur | Chaîne de caractères | 255 caractères | Avec doublons |
Etat | Etat de l'élément (grisé, inactif, ...) | Sélecteur | Entier non signé sur 1 octet | Avec doublons |
Element | Nom de l'élément | Chaîne de caractères | 255 caractères | Avec doublons |
Configuration_Element | Clé composée des rubriques Configuration et Element | Clé composée | Unique |
GPWElément
Caractéristiques des rubriques :
Element | Nom de l'élément | Chaîne de caractères | 255 caractères | Unique |
Type | Type de l'élément (champ de saisie, table, ...) | Numérique | Entier sur 4 octets | Avec doublons |
GPWHistoriqueConnexion
Caractéristiques des rubriques
Nom | Explication | Type | Taille | Clé |
---|---|---|---|---|
IDLogConnexion | Identifiant | Identifiant | Unique | |
Application | Nom de l'application | Chaîne de caractères | 255 caractères | Avec doublons |
Login | Login de l'utilisateur. Ce login correspond à l'identifiant de l'utilisateur lors de sa connexion à l'application | Chaîne de caractères | 255 caractères | Avec doublons |
DateConnexion | Date de la connexion à l'application | Date | 8 caractères | Avec doublons |
HeureConnexion | Heure de la connexion à l'application | Heure | 4 caractères | Avec doublons |
AdresseIP | Adresse IP du poste | Chaîne de caractères | 39 caractères | Avec doublons |
GPWUtilisateur
Caractéristiques des rubriques :
Login | Login de l'utilisateur. Ce login correspond à l'identifiant de l'utilisateur lors de sa connexion à l'application | Chaîne de caractères | 255 caractères | Unique |
Nom | Nom de l'utilisateur | Chaîne de caractères | 255 caractères | |
Prenom | Prénom de l'utilisateur | Chaîne de caractères | 255 caractères | |
MotPasse | Mot de passe de l'utilisateur | Chaîne de caractères | 255 caractères | |
Superviseur | Définit si l'utilisateur est un superviseur | Booléen | ||
MotPasseASaisir | Définit si l'utilisateur peut modifier son mot de passe lors de sa première connexion | Booléen |
GPWUtilisateurConfiguration
Caractéristiques des rubriques :
Nom | Explication | Type | Taille | Clé |
---|---|---|---|---|
Configuration | Nom du groupe d'utilisateurs ou de l'utilisateur | Chaîne de caractères | 255 caractères | Avec doublons |
Login | Login de l'utilisateur. Ce login correspond à l'identifiant de l'utilisateur lors de sa connexion à l'application | Chaîne de caractères | 255 caractères | Avec doublons |
Login_Configuration | Clé composée des rubriques Login et Configuration | Clé composée | Avec doublons | |
Application | Nom de l'application | Chaîne de caractères | 255 caractères | Avec doublons |
Login_Application | Clé composée des rubriques Login et Application | Clé composée | Unique | |
Application_Configuration | Clé composée des rubriques Application et Configuration | Clé composée | Avec doublons |
Corriger une faille dans le groupware utilisateur
Une faille?
Oui une faille. Il y en a pas mal de failles mais celle ci est particulière.
lors de la première utilisation du groupeware les fichier des données sont vides. donc le système ajoute automatiquement les données de bases comme l'utilisateur "Superviseur" avec le mot de passe "Superviseur".
Et comme les fichiers existe en dur sur le disque dur du serveur, il suffit de les supprimer pour que tout soit réinitialisé.
Pour y remédié rien de plus simple.
Allez Maintenant sur l'interface "GPWLogin"=>code d'initialisation.
Après la dernière ligne nous allons ajouter une petite partie de code:
Voila c'est pas compliqué. Et maintenant nous allons mettre quelques mesure de sécurités supplémentaires.Oui une faille. Il y en a pas mal de failles mais celle ci est particulière.
lors de la première utilisation du groupeware les fichier des données sont vides. donc le système ajoute automatiquement les données de bases comme l'utilisateur "Superviseur" avec le mot de passe "Superviseur".
Et comme les fichiers existe en dur sur le disque dur du serveur, il suffit de les supprimer pour que tout soit réinitialisé.
Pour y remédié rien de plus simple.
Allez Maintenant sur l'interface "GPWLogin"=>code d'initialisation.
Après la dernière ligne nous allons ajouter une petite partie de code:
HLitRecherche(GPWUtilisateur,Login,"Superviseur") SI HTrouve(GPWUtilisateur) Alors SI GPWUtilisateur.MotPasse="Superviseur" GPWUtilisateur.MotPasse=" Votre Mot de passe ici" FIN FIN
Se supprimer
Un utilisateur superviseur (Admin) peut supprimer son propre compte, ce qui peut poser problème dans certains cas ou alors révoquer les droits admin pour tout les utilisateurs ce qui peut poser plus de problèmes.
La solution est très simple.
Allez dans l'interface "GPWAssociationConfiguration"=>bouton supprimer=>code=>clic et vous trouverez ce code la:
SI OuiNon("Voulez-vous vraiment supprimer l'utilisateur '"+Login+"' ?") ALORS // recherche du login dans le fichier de relation entre les login et les applications HLitRecherchePremier(GPWUtilisateurConfiguration,"Login",Login) TANTQUE HTrouve(GPWUtilisateurConfiguration) SI PAS HSupprime(GPWUtilisateurConfiguration) ALORS Erreur("Impossible de supprimer l'utilisateur.",HErreurInfo()) FIN HLitSuivant(GPWUtilisateurConfiguration,"Login") FIN // recherche de l'utilisateur HLitRecherchePremier(GPWUtilisateur,"Login",Login) SI HTrouve(GPWUtilisateur) ALORS SI PAS HSupprime("GPWUtilisateur") ALORS Erreur("Impossible de supprimer l'utilisateur.",HErreurInfo()) FIN FIN // rafraichissement de la table AfficheTable() FIN
SI Login=gpwRecupInfoUtilisateur(gpwInfoLogin) Erreur("Impossible de supprimer l'utilisateur") SINON SI OuiNon("Voulez-vous vraiment supprimer l'utilisateur '"+Login+"' ?") ALORS // recherche du login dans le fichier de relation entre les login et les applications HLitRecherchePremier(GPWUtilisateurConfiguration,"Login",Login) TANTQUE HTrouve(GPWUtilisateurConfiguration) SI PAS HSupprime(GPWUtilisateurConfiguration) ALORS Erreur("Impossible de supprimer l'utilisateur.",HErreurInfo()) FIN HLitSuivant(GPWUtilisateurConfiguration,"Login") FIN // recherche de l'utilisateur HLitRecherchePremier(GPWUtilisateur,"Login",Login) SI HTrouve(GPWUtilisateur) ALORS SI PAS HSupprime("GPWUtilisateur") ALORS Erreur("Impossible de supprimer l'utilisateur.",HErreurInfo()) FIN FIN // rafraichissement de la table AfficheTable() FIN
SELECT * FROM GPWUtilisateur WHERE Superviseur=1
en bas nous allons modifier la partie:
// modification de l'utilisateur SINON // modifie l'enregistrement dans le fichier SI PAS hmodifie("GPWUtilisateur") ALORS Erreur("Impossible de modifier l'utilisateur."+RC+HErreurInfo()) FIN FIN
// modification de l'utilisateur SINON bModif_ok est boolean=vrai // modifie l'enregistrement dans le fichier SI GPWUtilisateur.superviseur=faux ALORS HExécuteRequête(REQ_liste_superviseur,hRequêteDéfaut) SI HNbEnr(REQ_liste_superviseur)=1 ALORS Erreur("Impossible de révoquer le mode superviseur à cet utilisateur.+RC+"Cet utilisateur est le seul superviseur") bModif_ok=faux FIN FIN SI bModif_ok=vrai ALORS SI PAS hmodifie("GPWUtilisateur") ALORS Erreur("Impossible de modifier l'utilisateur."+RC+HErreurInfo()) FIN FIN FIN
Faciliter la gestion des droits
J'ai déjà dis que l'utilisation de la gestion des droits dans la groupware n'est pas facile pour les clients à cause des noms physiques des champs et des fenêtres. Et pour facilité son utilisation, nous allons devoir modifier certaines choses et inscrire manuellement les champs que nous voulons. mais pour il faut comprendre le fonctionnement de l'interface "GPWDetailconfiguration"
Comprendre le fonctionnement de base
Cette interface est constitué de 5 parties:
- Combo utilisateur/groupe: c'est la combo qui défini sur quelle configuration nous allons modifier les droits. Nous n'allons pas y toucher
- Boutons (ajouter/modifier/supprimer): il agisse sur la configuration sélectionnée. Nous n'allons pas y toucher non plus
- Combo Nom de la fenêtre: cette combo est remplie par l’énumération des fenêtres de l'application et du coup elle comprend la liste de toutes les fenêtres avec leurs noms physiques. Nous allons la remplir de façon manuelle et changer son comportement.
- La liste Type: c'est une liste qui nous permet de choisir quel type de champs nous voulons afficher dans la liste des champs. Nous pouvons nous en débarrasser, ce serai plus simple pour l'utilisateur final qui ne fait pas la différence entre une liste et une combo ou alors sélecteur et interrupteur.
- Le tableau des objets: c'est la liste des champs dans une fenêtre. et c'est l'endroit ou nous choisissons l’état du champs (droit). Bien évidement nous allons changer ça façon de se remplir et ça façon d'interagir.
Après avoir pris connaissance de ce que nous allons faire il va falloir voire tous ça de plus près.
Alors nous allons ouvrir le code de l'interface=>déclaration globale.
Nous y trouverons, la déclaration des tables de base de données, puis la déclaration des constantes du type de champs. Dans notre cas ils ne nous aiderons pas beaucoup mais pour ceux qui désire utiliser les types des champs ce serais intéressant.
Apres la déclaration globale, nous trouvons l'initialisation de la fenêtre. On y trouve un petit code:
// remplit la combo InitComboConfiguration() // sélection de la bonne configuration SelectConfiguration() // rafraichissement de la fenêtre Rafraichissement()
Je pense que tout est claire, inutile de détailler la dessus mais il faut savoir que la fonction Rafraichissement() est la fonction qui remplit le tableau des objets en prenant en compte le type du champs et la fenêtre et voici son code avant modification:
// Rafraichissement de la fenêtre en fonction de la sélection de la fenêtre et de la configuration PROCEDURE Rafraichissement() // propose d'activer les options du menu "?" SI Fenetre[Fenetre]="FI_MenuHWinDevHelp" ALORS SI ListeOccurrence(ColEtat)<>5 ListeAjoute(ColEtat,"Actif") FIN SINON SI ListeOccurrence(ColEtat)=5 ALORS ListeSupprime(ColEtat,5) FIN // vide la table TableSupprimeTout(EtatObjet) // filtre le fichier de configiguration des éléments HFiltre("GPWConfigurationElement","Configuration",ComboConfiguration) // selon la sélection dans la liste // il faut remplir correctement selon type cas eTOUS : RemplirTous(Fenetre[Fenetre]) cas eGROUPE : Remplirparent(Fenetre[Fenetre],typGrp) cas eMENU : RemplirMenu(Fenetre[Fenetre]) cas eMENUCONTEXTUEL : RemplirMenuContextuel(Fenetre[Fenetre]) cas eBOUTON : RemplirElement(Fenetre[Fenetre],typBouton) cas eSAISIE : RemplirSaisie(Fenetre[Fenetre]) cas eLIBELLE : RemplirElement(Fenetre[Fenetre],typLibellé) cas eLISTE : RemplirElement(Fenetre[Fenetre],typListe) cas eCOMBO : RemplirCombo(Fenetre[Fenetre]) cas eSELECTEUR : RemplirElement(Fenetre[Fenetre],typSélect) cas eINTERRUPTEUR : RemplirElement(Fenetre[Fenetre],typInterr) cas eTABLE : RemplirElement(Fenetre[Fenetre],typTable) cas eBARREOUTILS : RemplirElement(Fenetre[Fenetre],typBarreOutils) cas eIMAGE : RemplirImage(Fenetre[Fenetre]) cas eONGLET : Remplirparent(Fenetre[Fenetre],typOnglet) cas eVOLET : RemplirVolet(Fenetre[Fenetre]) CAS eSUPERCHAMP : RemplirParent(Fenetre[Fenetre],typSuperChamp) cas eAUTRE : RemplirAutre(Fenetre[Fenetre]) cas eBOITEOUTILS : Remplirparent(Fenetre[Fenetre],typBoîteAOutils) FIN
Mise en place des éléments
Comme nous l'avons déjà dis, nous allons remplacer le système d’énumération automatique par un système manuel. et pour ça nous devons préparer la liste de nos éléments dans la déclaration de la fenêtre.Ma méthode consiste à utiliser des structure de données et des tableaux comme cela:
STChamp est une structure xChamp_type est un numérique=0 sNom_champ est une chaîne="" sLib_champ est une chaîne="" sNom_physique_champ est une chaîne="" sGroupe_champ est une chaîne="" FIN STFenetre est une structure sNom_fenetre est une chaîne="" sNom_physique_fenetre est une chaîne="" ptabListe_champ est un tableau dynamique de STChamp FIN gtabListe_fenetre est un tableau de 2 STFenetre gAux_fenetre est STFenetre gtabAux_liste_champs est un tableau dynamique de STChamp Dimension(gtabAux_liste_champs,1) gAux_fenetre:sNom_fenetre="Agenda" gAux_fenetre:sNom_physique_fenetre="FEN_agenda" gtabAux_liste_champs[1]:sLib_champ="Votre Agenda" gtabAux_liste_champs[1]:sNom_physique_champ="AGD_Agenda" gtabAux_liste_champs[1]:sNom_champ="Agenda" gtabAux_liste_champs[1]:xChamp_type={"FEN_agenda.AGD_Agenda",indGPW}..Type gtabAux_liste_champs[1]:sGroupe_champ={"FEN_agenda.AGD_Agenda",indGPW}..Groupe gAux_fenetre:ptabListe_champ=gtabAux_liste_champs gtabListe_fenetre[1]=gAux_fenetre Dimension(gtabAux_liste_champs,3) gAux_fenetre:sNom_fenetre="Saisie" gAux_fenetre:sNom_physique_fenetre="FEN_Saisie" gtabAux_liste_champs[1]:sLib_champ="premier champs de saisie" gtabAux_liste_champs[1]:sNom_physique_champ="SAI_champ_saisie_1" gtabAux_liste_champs[1]:sNom_champ="champs saisie 1" gtabAux_liste_champs[1]:xChamp_type={"FEN_Saisie.SAI_champ_saisie_1",indGPW}..Type gtabAux_liste_champs[1]:sGroupe_champ={"FEN_Saisie.SAI_champ_saisie_1",indGPW}..Groupe gtabAux_liste_champs[2]:sLib_champ="deuxieme champs de saisie" gtabAux_liste_champs[2]:sNom_physique_champ="SAI_champ_saisie_2" gtabAux_liste_champs[2]:sNom_champ="champs saisie 2" gtabAux_liste_champs[2]:xChamp_type={"FEN_Saisie.SAI_champ_saisie_2",indGPW}..Type gtabAux_liste_champs[2]:sGroupe_champ={"FEN_Saisie.SAI_champ_saisie_2",indGPW}..Groupe gtabAux_liste_champs[3]:sLib_champ="Bouton ok" gtabAux_liste_champs[3]:sNom_physique_champ="BTN_OK" gtabAux_liste_champs[3]:sNom_champ="OK" gtabAux_liste_champs[3]:xChamp_type={"FEN_Saisie.BTN_OK",indGPW}..Type gtabAux_liste_champs[3]:sGroupe_champ={"FEN_Saisie.BTN_OK",indGPW}..Groupe gAux_fenetre:ptabListe_champ=gtabAux_liste_champs gtabListe_fenetre[2]=gAux_fenetre
Je sais que c'est pas évident de passer en revue toutes les fenêtres et entrer tout les champs mais je vous assure que le gain généré plus tard dans la configuration et la formation chez les clients et le suivie en vaux la peine.
Mais comment allons nous utiliser cette liste??
Liste des fenêtres
Nous avons maintenons la liste des fenêtres et leurs champs. Mais nous n'allons pas les remplir une par une. Il suffit d'aller dans le code d’initialisation de la combo fenêtre, commenter le code existant (afin de pouvoir revenir en arrière en cas de besoin) et mettre ce bout de code:
ListeSupprimeTout(Fenetre) POUR i=1 A 2 ListeAjoute(Fenetre,gtabListe_fenetre[i]:sNom_fenetre) FIN Fenetre=1
Liste des champs
Dans cette partie nous allons nous intéresser à la fonction rafraichissement() puisque c'est elle qui remplit la liste des champs. Nous allons la modifier de la sorte:
// Rafraichissement de la fenêtre en fonction de la sélection de la fenêtre et de la configuration PROCEDURE Rafraichissement() // propose d'activer les options du menu "?" //si Fenetre[Fenetre]="FI_MenuHWinDevHelp" alors SI gtabListe_fenetre[Fenetre]:sNom_physique_fenetre="FI_MenuHWinDevHelp" ALORS SI ListeOccurrence(ColEtat)<>5 ListeAjoute(ColEtat,"Actif") FIN SINON SI ListeOccurrence(ColEtat)=5 ALORS ListeSupprime(ColEtat,5) FIN // vide la table TableSupprimeTout(EtatObjet) // filtre le fichier de configiguration des éléments HFiltre("GPWConfigurationElement","Configuration",ComboConfiguration) // selon la sélection dans la liste // il faut remplir correctement //selon type // cas eTOUS : RemplirTous(Fenetre[Fenetre]) // cas eGROUPE : Remplirparent(Fenetre[Fenetre],typGrp) // cas eMENU : RemplirMenu(Fenetre[Fenetre]) // cas eMENUCONTEXTUEL : RemplirMenuContextuel(Fenetre[Fenetre]) // cas eBOUTON : RemplirElement(Fenetre[Fenetre],typBouton) // cas eSAISIE : RemplirSaisie(Fenetre[Fenetre]) // cas eLIBELLE : RemplirElement(Fenetre[Fenetre],typLibellé) // cas eLISTE : RemplirElement(Fenetre[Fenetre],typListe) // cas eCOMBO : RemplirCombo(Fenetre[Fenetre]) // cas eSELECTEUR : RemplirElement(Fenetre[Fenetre],typSélect) // cas eINTERRUPTEUR : RemplirElement(Fenetre[Fenetre],typInterr) // cas eTABLE : RemplirElement(Fenetre[Fenetre],typTable) // cas eBARREOUTILS : RemplirElement(Fenetre[Fenetre],typBarreOutils) // cas eIMAGE : RemplirImage(Fenetre[Fenetre]) // cas eONGLET : Remplirparent(Fenetre[Fenetre],typOnglet) // cas eVOLET : RemplirVolet(Fenetre[Fenetre]) // CAS eSUPERCHAMP : RemplirParent(Fenetre[Fenetre],typSuperChamp) // cas eAUTRE : RemplirAutre(Fenetre[Fenetre]) // cas eBOITEOUTILS : Remplirparent(Fenetre[Fenetre],typBoîteAOutils) //FIN POUR i=1 _A_ TableauOccurrence(gtabListe_fenetre[ListeSelect(Fenetre)]:ptabListe_champ) TableAjoute(EtatObjet) EtatObjet[i].ColElement=gtabListe_fenetre[ListeSelect(Fenetre)]:ptabListe_champ[i]:sLib_champ EtatObjet[i].ColGroupe=gtabListe_fenetre[ListeSelect(Fenetre)]:ptabListe_champ[i]:sGroupe_champ EtatObjet[i].ColNom=gtabListe_fenetre[ListeSelect(Fenetre)]:ptabListe_champ[i]:sNom_champ EtatObjet[i].ColType=gtabListe_fenetre[ListeSelect(Fenetre)]:ptabListe_champ[i]:xChamp_type EtatObjet[i].NomLogique=gtabListe_fenetre[ListeSelect(Fenetre)]:sNom_physique_fenetre+"."+gtabListe_fenetre[ListeSelect(Fenetre)]:ptabListe_champ[i]:sNom_physique_champ HLitRecherche(GPWConfigurationElement,Configuration_Element,ComboConfiguration..ValeurAffichée+","+EtatObjet[i].NomLogique,hIdentique) SI HTrouve(GPWConfigurationElement) ALORS EtatObjet[i].ColEtat=GPWConfigurationElement.etat SINON EtatObjet[i].ColEtat=1 FIN FIN
Et voila nous avons presque terminé tout ce qui nous reste c'est une petite modification sur l’état afin de prendre en charge le nom de la fenêtre.
C'est juste une petite ligne à modifier.
Dans la procédure mofietat():
// vérification de la dissociation d'un groupe //c'est la ligne d'origine //VerifDissociation(ComboConfiguration, Fenetre[Fenetre], sElement, nEtat, sListeGroupe, nType) //c'est la nouvelle ligne VerifDissociation(ComboConfiguration, gtabListe_fenetre[ListeSelect(Fenetre)]:sNom_physique_fenetre, sElement, nEtat, sListeGroupe, nType)
j’espère que ça vous sera utile.
N'hésitez pas à mettre des commentaire ou à me contacter en cas de besoin.
A la prochaine.