Le forum (ô combien francophone) des utilisateurs de Powerbuilder.
Bonjour,
je veux creer un window d'une façon dynamique pour le lancer par la suite comme suit:
WindowObject lwo_Control DataWindow ldw_dw r_amort_surcote_decote iw_oati iw_oati = CREATE r_amort_surcote_decote //Iinitialisations des différents datawindows li_max = UpperBound(iw_oati.Control[]) FOR li_i=1 TO li_max lwo_Control = iw_oati.Control[li_i] IF lwo_Control.TypeOf() = DataWindow! THEN ldw_dw = lwo_Control OpenUserObject(ldw_dw) ldw_dw.SetTransObject (sqlca) END IF NEXT //Déclencher l'évenement open pour les initialisations iw_oati.TriggerEvent("open")
le seul probleme est que le nom du window est récupéré à partir d'un fichier donc c'est une chaine de caractère et non pas un type comme c'est le cas pour l'exemple ci-dessus (r_amort_surcote_decote).
Aves-vous des suggestions pour résoudre ce problème?
Merci d'avance.
Dernière modification par Amine (29-05-2012 09:09:17)
Hors ligne
Si c'est un objet descendant de fenêtre, je propose (non testé)
WindowObject lwo_Control DataWindow ldw_dw window lw_win lw_win= CREATE USING "r_amort_surcote_decote" //Iinitialisations des différents datawindows li_max = UpperBound(lw_win.Control[]) FOR li_i=1 TO li_max lwo_Control = lw_win.Control[li_i] IF lwo_Control.TypeOf() = DataWindow! THEN ldw_dw = lwo_Control // OpenUserObject(ldw_dw) <-- ??? ldw_dw.SetTransObject (sqlca) END IF NEXT //Déclencher l'évenement open pour les initialisations lw_win.TriggerEvent("open")
Je ne comprends pas l'intérêt de la ligne avec OpenUserObject(). OpenUserObject sert à ajouter dynamiquement des contrôles à un objet visuel (fenêtre, tabcontrol). Si le type r_amort_surcote_decote contient des DW, elles seront créées lors de la création de l'objet (ça se voit dans "Edit source", dans l'évènement système
on r_amort_surcote_decote.create
)
Par ailleurs, c'est une mauvaise conception de créer un objet puis de gérer ses SetTransObject() de l'extérieur.
- Déjà ça oblige l'"utilisateur" d'un objet à en connaître les détails internes (mauvaise encapsulation),
- ensuite, si on utilise r_amort_surcote_decote plusieurs endroits différents, il faudra copier / coller le code d'initialialisation à chaque appel (duplication de code + couplage fort).
Il vaut mieux déplacer ce code à l'intérieur de l'objet, par exemple dans l'évènement open() qui est déclenché sur l'objet.
Hors ligne
Merci seki pour ta réponse, si je me trompe pas j'ai déjà essayé avec ta méthode et je reçoit un message d'erreur lors de la compilation qui me dit que "r_amort_surcote_decote" est un type inconnu. en tout cas je vais réessayer pour en être sur.
Pour ce qui est de la conception je t'explique le cadre général:
Il s'agit d'un module pour un recorder qui reçoit un fichier trace des actions effectuées puis reprend ce script pour le dérouler d'une façon automatique.
cette fonction aura comme paramètre le nom du Window ainsi qu'une liste des critères de sélection par exemple.
Hors ligne
Amine a écrit:
Merci seki pour ta réponse, si je me trompe pas j'ai déjà essayé avec ta méthode et je reçoit un message d'erreur lors de la compilation qui me dit que "r_amort_surcote_decote" est un type inconnu. en tout cas je vais réessayer pour en être sur.
- Attention aux doubles quotes ici on utilise une chaîne qui contient le type et pas directement le type.
- Cette chaîne serait à remplacer par un variable qui contiendra le type d'objet à créer (suivant ce qui est lu dans le fichier).
En me relisant je réalise que ce code est faux, pour ouvrir une fenêtre dynamiquement c'est
open(lw_win, "r_amort_surcote_decote")
plutôt que create using.
Amine a écrit:
Pour ce qui est de la conception je t'explique le cadre général:
Il s'agit d'un module pour un recorder qui reçoit un fichier trace des actions effectuées puis reprend ce script pour le dérouler d'une façon automatique.
cette fonction aura comme paramètre le nom du Window ainsi qu'une liste des critères de sélection par exemple.
Certes, mais ça n’empêche pas que moins le code "client" d'un objet / fenêtre en sait sur la structure interne de l'objet utilisé, mieux c'est. Ça évite les couplages forts et ça facilite la maintenance. Si vraiment on a besoin d'infos qui sont à l'intérieur de l'objet, il faut passer par des accesseurs (getters / setters) mais ne pas y accéder directement.
Dans le cas présent, on a un module qui instancie une fenêtre, et qui va ensuite initialiser les transactions des DW de la fenêtre. C'est mieux si la fenêtre fait elle-même cette opération pour ses propres DW. Bon, certes ici le code est assez dynamique pour continuer à fonctionner si on ajoute des DW, ou si il un jour il n'y en avait plus. Mais si on souhaite ouvrir la même fenêtre depuis un autre module, il faudrait recopier la même boucle ailleurs, c'est mal.
Edit : je déplace cette discussion dans un forum plus adapté, puisqu'il ne s'agit pas de bug PB.
Dernière modification par seki (29-05-2012 10:42:42)
Hors ligne
Petite remarque en passant pour Amine:
Ca facilitera la lecture du code.
Hors ligne