IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

WinDev Discussion :

Utilsation de la POO avec Windev [WD23]


Sujet :

WinDev

  1. #1
    Membre chevronné Avatar de wd_newbie
    Homme Profil pro
    Développeur
    Inscrit en
    Mars 2007
    Messages
    760
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2007
    Messages : 760
    Par défaut Utilsation de la POO avec Windev
    Bonjour à tous,

    Après bien des années sous Windev, comme j'ai un nouveau projet en vue ... c'est mon propre CRM , donc idéal pour faire des tests ... je vais tenter de faire ça en POO.
    (sous d'autre langages ça me semble naturel ... mais je n'ai pas eu le déclic sous WD)

    Je viens de parcourir la doc en ligne , suivi pas mal de tuto et pour une partie de mes besoins, je pense que c'est par trop mal, mais une question simple :

    - dans un fichier, clients pour ne pas le nommer, j'ai des liaisons avec des autres fichiers Clients_Types, Clients_Contatcs, etc.

    Il est simple de créer un classe depuis une description de fichier , en suite de lui adjoindre des méthodes et propriétés.

    Là ou ma compréhension bloque :

    1 - comment ressortir les informations liées clients + clients_types , je mets une requête dans une méthode ?
    2 - une fois les données récupérées au point 1 , je les place dans un tableau, un tableau de structures, une source de données pour le renvoyer (comme je ne dois pas traiter l'UI dans la classe)
    3 - S'il est simple de faire un SourceVersEcran() pour les données d'un enregistrement ... comment le faire pour les tables / listes / ... un parcours du tableau et TableAjouteLigne() ?

    J'ai créé des fenêtre de test avec le code du RAD POO, mais je n'ai pas trop compris la philosophie et çA semple plus fouille que de le faire de manière traditionnelle, et l'exemple POO simple avec les éléphants ...

  2. #2
    Membre chevronné
    Avatar de Narwe
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2013
    Messages
    257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Mayenne (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2013
    Messages : 257
    Par défaut
    Dans mes classes, j'utilise un membre PUBLIQUE LOCAL CONSTANT (donc accessible lecture mais pas en écriture) de type Enregistrement de <NomFichier>
    Lorsqu'il y a des "sous-fichier" (ligne de commande par exemple) ma classe Commande contient un tableau d'objet de type Ligne de Commande (membre PRIVEE) renvoyer par une méthode DonneLigne() pour éviter de charger les lignes (et les lire en base) tant que ce n'est pas nécessaire. Lorsque j'affiche la liste des commandes, je n'ai donc que les entêtes de charger et je charge les lignes que pour afficher le détail.

    Pour les fichiers de base (Client par exemple), j'ai un membre GLOBAL PRIVE qui contient l'ensemble des clients pour ne les charger qu'une fois en mémoire et ne pas avoir à les recharger lorsqu'ils sont utilisé à différents endroits dans l'application.
    Pour récupérer un client précis, j'ai une méthode GLOBAL DonneClient(<IdClient>) qui va lire dans ce tableau GLOBAL (et qui les charge si nécesaire, c'est-à-dire si vide ou si la valeur renvoyer par HVersion a été modifié depuis le dernier chargement). Je ne fait jamais de requête pour lire un seul client.
    Dans un de mes constructeur, j'ai un paramétre qui prend une variable de type Enregistrement.
    A noter, si on a une requête qui va lire le fichier Client (un SELECT * même si je n'aime pas faire de SELECT *), on peut faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    enClient est un Enregistrement de CLIENT = REQ_Client // Dans une boucle
    enClient.IDCLIENT= REQ_Client.IDCLIENT // Car l'affectation ci-dessus ne reprend pas les IdAutoIncrement en Windev 23
    TableaAjoute(gp_LstClient, allouer un cClient(enClient))

  3. #3
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2022
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Congo-Kinshasa

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2022
    Messages : 16
    Par défaut
    Citation Envoyé par Narwe Voir le message

    Je ne fait jamais de requête pour lire un seul client.
    Et comment faites-vous pour récupérer un enregistrement ??
    Je suis curieux de le savoir, ça peut m'aider toujours.

    A supposer que j'ai le fichier Clients avec rubriques IDClients , Nom.

    Avec une classe MClients qui mappe le fichier Clients.

    Les rubriques de la classe sont :
    mn_IDClients, ms_Nom.

    Comment je fais pour récupérer un client sont ID = 20 par exemple

  4. #4
    Membre émérite
    Homme Profil pro
    Chef de projet
    Inscrit en
    Mars 2017
    Messages
    343
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Chef de projet
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2017
    Messages : 343
    Par défaut
    D'après tes dires tu veux faire de la POO mais surtout un ORM. Qui te permettra de manipuler les données de la base au travers d'objet.

    1) Si ta classe MClient mappe le fichier Client de la base, alors cette classe contient un objet lié (si la relation en base est one to one) MClient_type qui représente une ligne de la table Client_type.
    Effectivement à un moment pour récupérer la donnée il faudra requêter. Personnellement je ne requête rien car mon ORM écrira la requête lui même pour récupérer ce qui lui est nécessaire (pour le savoir, il fait de l'introspection sur les classes et il a une base assez formalisée pour l'aider). Ces requêtes sont dans des méthodes mais tu verras vite qu'elles vont être très similaires et que tu feras beaucoup de copier coller. Ainsi, ces codes pourront être factorisés dans une classe mère dont dériverons les classe qui mappent les fichiers.

    A n'en pas douter si tu pars sur ça, ça n'est pas une mince affaire en dev. L'ORM m'a pris des semaines et désormais il sait faire oClient._getByID(2) -> et me renvoie un objet MClient issu de la base sans même que j'ai eu à écrire du SQL, en gérant les JOIN sur les objets liés (il me renverrait donc avec cette seule ligne l'objet MClient_type) ainsi que les tableau d'objets liés si je lui demande (il me renverrrait donc aussi le tableau d'objets MLigne_Commande issu de la table MLigne_Commande.

    Et ensuite un oClient._save() se chargerait de faire l'UPDATE (ou l'INSERT, il se débrouille). Mais de l'entité racine seulement, je n'ai pas codé la profondeur.

    Rien que ça si c'est ce que tu as en tête, c'est pas simple à faire proprement et ça nécessite encapsulation, héritage, et polymorphisme.

    2) Je ne comprends pas bien la question car si tout est objet, pourquoi tu parles de structure ou de source de données? Tu gèreras des objets, et des tableau d'objets, rien d'autre si ce n'est des énumérations pour sécuriser le code. Par exemple si tu as des types de client, les identifier par l'ID n'est pas forcément l'idée du siècle pour retrouver un type particulier plus tard. Certes l'ID est celui qui vis à travers les données de la base mais pour mettre la main sur un type mieux vaut une KEY qui sera sécurisée dans une énum et qui te permettra facilement de retrouver ta donnée dans la table des types de client.

    3)C'est du databinding. Par exemple dans une fenêtre je déclares un objet global à la fenêtre tabClients qui est un tableau d'objets MClient et je choisis une variable dans la partie liaison des 7 onglets.

  5. #5
    Expert confirmé
    Avatar de Voroltinquo
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Juin 2017
    Messages
    2 949
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Chef de projet en SSII

    Informations forums :
    Inscription : Juin 2017
    Messages : 2 949
    Billets dans le blog
    1
    Par défaut
    Bonjour,
    J'ajouterai une chose à ce qui a déjà été écrit, dans ton cas "FichierVersMémoire" ainsi que ses fonctions connexes vont être utiles dans la mesure où tu utilises des classes mappées.
    e.g. (en reprenant les fonction évoquées par kunnskap)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    FONCTION _GetByID(pkClient est entier sur 8,clClient est MCient) :boléen
    HLitRecherchePremier(pkClient)
    FichierVersMémoire(clClient,Client)
    //en supposant que ta classe possède un tableau
    REQ_ListeCommandes.pClient=pkClient
    HExécuteRequête(REQ_ListeCommandes)
    FichierVersTableau(clClient.tabCommandes,REQ_ListeCommande)
    RENVOYER Vrai
     
    CAS EREUR :
         RENVOYER Faux
    avec REQ_ListeCommandes
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    SELECT 
         NoCommande
    FROM
         Commande
    WHERE
         FK_Client={pClient}

  6. #6
    Membre chevronné
    Avatar de Narwe
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2013
    Messages
    257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Mayenne (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2013
    Messages : 257
    Par défaut
    Citation Envoyé par Franklin_de Voir le message
    Et comment faites-vous pour récupérer un enregistrement ??
    Je suis curieux de le savoir, ça peut m'aider toujours.
    Je considère le fichier des clients comme un fichier de base qui n'est que très peu modifié en cours de journée et dont le nombre de données est limité (comme une table Unité par exemple).
    Donc, je charge l'ensemble des clients dans un tableau en mémoire (un tableau de de cette classe) et qui y reste tout le temps d'exécution du programme (Je ne charge que le fichier "de base", pas ces informations liées comme la liste des contacts du client ou autres).

    Lorsque je recherche un client par un Id, je fais une recherche dans ce tableau.
    Je n'ai fait aucune mesure mais avec un petit millier de client, je pense qu'il est plus rapide de faire une seule demande à la base en début de journée que d'en faire une centaine tout au long de la journée parfois en demandant la même information.

    Dans le principe, Je n'ai qu'une classe Client, je n'ai pas de classe Client_Liste.
    Dans cette classe client, j'ai des membres globaux (donc commun à toutes les instances de Client et qui reste actifs même s'il n'y a pas d'instance de Client en cours)
    J'ai aussi un membre qui contient la valeur de HVersion du fichier HF au moment de la récupération de cette liste client et lorsque je demande un client, je vérifie la valeur de HVersion actuel à celle stocké dans ce membre pour savoir si je dois recharger la liste des clients à partir de la base.

    Si j'ai par la suite besoin d'avoir la liste des contacts de ce client, je vais appelé une méthode DonneLstContact qui fonctionnera de la même façon (si j'ai les contacts de ce client en mémoire je la renvoi directement sinon, j'interroge la base, je la stock en mémoire au niveau de l'instance de la classe et ce cette valeur qui sera directement renvoyée la prochaine fois).

    Mon but et d'éviter d'interroger la base de données inutilement.

    Donc j'ai une classe de ce type (version simplifiée) :

    Déclaration
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    cClient est une Classe
    	GLOBAL PRIVÉ CONSTANT
    		g_tLstClient			est un tableau de cClient dynamique
    		g_nHVersion				est un entier
     
    	LOCAL PUBLIC CONSTANT
    		m_nIdTiers				est un entier 							// C'est juste pour l'avoir plus facilement mais c'est la même chose que m_eTiers.IDTIERS
    		m_eTiers				est un Enregistrement de TIERS
     
    FIN
    Constructeur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    PROCÉDURE PRIVÉ Constructeur(	LOCAL pe_EnregTiers		est un Enregistrement de TIERS	)
     
    LOCAL
     
     
    :m_nIdTiers		= pe_EnregTiers.IDTIERS
    :m_eTiers		= pe_EnregTiers
    La procédure que j'appelle pour avoir mon instance
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    PROCÉDURE GLOBAL DonneClient(	LOCAL p_nIdClient	est un entier	) : cClient
     
    LOCAL
    	nIndTab		est un entier
    	clClient	est une clClient dynamique
     
     
    :Pp_cahrgeData()
    nIndTab	= TableauCherche(::g_tLstclClient, tcLinéaire, "m_nIdTiers", p_nIdClient)
    SI nIndTab>0 ALORS
    	clClient	<- ::g_tLstTiers[nIndTab]
    SINON
    	clClient	= allouer un clClient(p_nIdClient)
    FIN
     
    RENVOYER oTiers
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    PROCEDURE GLOBAL PRIVEE Pp_cahrgeData() : Tableau de cClient dynamique
     
    LOCAL
    	nHVersion			est un entier
     
     
    nHVersion	= HVersion(CLIENT)
    SI pas nHVersion>::g_nHVersion ALORS RENVOYER ::g_tLstClient
     
    ::g_nHVersion	= nHVersion
    TableauSupprimeTout(::g_tLstClient)
    POUR TOUT CLIENT
    	TableauAjoute(::g_tLstClient, allouer un cClient(CLIENT))
    FIN
     
    RENVOYER ::g_tLstClient
    Utilisation
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    clClient 	est un cClient dynamique
    clClient 	<- cClient::DonneClient(1)

  7. #7
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2022
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Congo-Kinshasa

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2022
    Messages : 16
    Par défaut
    J'ai étudié votre code mais il y a des lignes qui me semblent confuses

    Je veux comprendre un peu la provenance de cette ligne
    m_eTiers est un Enregistrement de TIERS

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    cClient est une Classe
    	GLOBAL PRIVÉ CONSTANT
    		g_tLstClient			est un tableau de cClient dynamique
    		g_nHVersion				est un entier
     
    	LOCAL PUBLIC CONSTANT
    		m_nIdTiers				est un entier 	
    		m_eTiers				est un Enregistrement de TIERS
     
    FIN
    Et dans le Constructeur de la classe cClient, vous avez déclaré un paramètre de type Enregistrement de TIERS.
    Je voudrais être éclairé là dessus.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    PROCÉDURE PRIVÉ Constructeur(	LOCAL pe_EnregTiers		est un Enregistrement de TIERS	)
     
    LOCAL
     
     
    :m_nIdTiers		= pe_EnregTiers.IDTIERS
    :m_eTiers		= pe_EnregTiers
    Dans cette procédure, vous avez instancié la classe cClient comme ceci
    clClient = allouer un clClient(p_nIdClient)
    Et pourtant le constructeur attend un argument de type Enregistrement de TIERS
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    PROCÉDURE GLOBAL DonneClient(	LOCAL p_nIdClient	est un entier	) : cClient
     
    LOCAL
    	nIndTab		est un entier
    	clClient	est une clClient dynamique
     
     
    :Pp_cahrgeData()
    nIndTab	= TableauCherche(::g_tLstclClient, tcLinéaire, "m_nIdTiers", p_nIdClient)
    SI nIndTab>0 ALORS
    	clClient	<- ::g_tLstTiers[nIndTab]
    SINON
    	clClient	= allouer un clClient(p_nIdClient)
    FIN
     
    RENVOYER oTiers

  8. #8
    Membre chevronné
    Avatar de Narwe
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2013
    Messages
    257
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Mayenne (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2013
    Messages : 257
    Par défaut
    La variable de type ENREGISTREMENT permet d'avoir une sorte de structure contenant l'ensemble des champs de la table indiqué.
    Grâce à cela, je ne fais pas de MAPPING et lorsque je modifie la structure de la table, lorsque j'ajoute un champ, je n'ai pas à modifié la classe.
    J'accède aux différentes valeur en utilisant : <Nom de la variable Enregistrement>.<Nom du champ dans la table HF>

    Pour le constructeur manquant, en effet, j'ai oublié d'indiqué que j'ai un 2e constructeurs de ce type afin que la méthode DonneClient me renvoi toujours un objet valide même lorsque je demande un client qui n'existe pas (les informations sont vides dans ce cas). Cela m'évite de faire un test au retour de cette fonction pour savoir si l'objet est null ou non.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    PROCÉDURE PRIVÉ Constructeur( LOCAL p_nIdClient est un entier	)
     
    LOCAL
     
    :m_nIdClient = p_nIdClient
    SI PAS HLitRecherchePremier(CLIENT, IDCLIENT, :m_nIdClient) ALORS HRAZ(CLIENT)
    :m_eTiers		= CLIENT

  9. #9
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2022
    Messages
    16
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Congo-Kinshasa

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2022
    Messages : 16
    Par défaut
    Je comprend.

    Mais moi, je trouve le MAPPING a beaucoup d'avantages car il permet le bidding entre mes champs et l'objet.

  10. #10
    Membre chevronné Avatar de wd_newbie
    Homme Profil pro
    Développeur
    Inscrit en
    Mars 2007
    Messages
    760
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2007
    Messages : 760
    Par défaut
    Bon, j'en suis toujours a essayer de créer un simple classe ...

    Pour un cas simple (oui j'en suis là ... ) , je crée une classe MSponsoring qui représente un sponsoring de la part d'un membre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    MSponsoring est une Classe <MAPPING=Sponsoring>
     
    	// Le code se trouvant entre <MAPPING> et <FIN> est généré automatiquement.
    	// Il sera effacé et recréé entièrement à chaque génération depuis l'analyse.
    	<MAPPING>
    	m_nSP_ID		est un entier sur 8 octets	<MAPPING=SP_ID, clé unique>
    	m_dSP_Validite	est une Date				<MAPPING=SP_Validite>
    	m_sSP_remarque	est une chaîne ANSI			<MAPPING=SP_remarque>
    	m_nSP_Employeur	est un entier sur 8 octets	<MAPPING=SP_Employeur>
    	<FIN>
     
    FIN
    OK, je peux récupérer mes sponsoring au moyen d'un tableau d'objet dans un méthode de classe

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    PROCÉDURE PUBLIQUE GLOBALE ListeSponsoring()
     
    tabListeSponsors est un tableau de MSponsoring
    FichierVersTableau(tabListeSponsors,rs)
    RENVOYER tabListeSponsors
    Jusque là je suis juste ? Par contre je me retrouve avec une liste avec un m_nSP_ID qui représente l'ID de mon fichier.
    L'idée serait de récupérer le nom du membre ... ce serait quand même plus lisible ...

    Si je mets un propriété "NomMembre" a ma classe qui reprend par requête ce nom et l'associe à ma propriété ce serait une idée ... mais je vais faire une requête par objet retourné ... pas optimal quand même

    Il me semble que la fonction FichierVersTableau() prend également en paramètre une requête, mais là je ne pourrais plus retourner des objets mSponsoring ...

    - il faudrait faire une classe sur une requête ?

    - mettre un méthode globale qui me retournerait une source de données ? (mais ça semble ne pas fonctionner , le code ci-dessus plante "source de donnée non initialisée )

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    PROCÉDURE PUBLIQUE GLOBALE Employeurs_Sponsors()
     
    rs est une Source de Données
     
    sql est une chaîne
    sql = [
    	SELECT * from Sponsoring  INNER JOIN ... WHERE ...
    ]
     
    HExécuteRequête(rs,hRequêteDéfaut,sql) 
     
    RENVOYER rs
    et dans ma fenêtre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    rs est une Source de Données = MSponsoring.Employeurs_Sponsors()
     
     
    POUR TOUT rs 
    	Trace(rs.SP_ID) 
    FIN

  11. #11
    Expert confirmé
    Avatar de Voroltinquo
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Juin 2017
    Messages
    2 949
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Chef de projet en SSII

    Informations forums :
    Inscription : Juin 2017
    Messages : 2 949
    Billets dans le blog
    1
    Par défaut
    Bonjour,
    Une solution consiste à te créer une propriété (getter) p_NomEmployeur définie comme suit (par exemple) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    FONCTION p_NomEmployeur :Chaine
    HLitRecherchePremier(Employeur,PK_Employeur,:m_nSP_Employeur)
     
    RENVOYER Employeur.NomEmployeur
    Tu accèdes alors aux nom des sponsors de la manière suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    nIndice est entier
     
    POUR nIndice=1 _A_ tabListeSponsor..Occurence
         Trace(tabListeSponsor[nIndice]:p_NomEmployeur)
    FIN
    Par ailleurs, si tu remplis un champ table par data binding, la propriété ainsi créée sera proposée. Et heureusement car c'est le seul moyen d'avoir accès à tes membres qui au minimum devraient être déclarés en PROTEGE. ... Sauf si tu as besoin de sérialiser en JSON ou en XML.

    Une autre solution, qui diminue les lectures de la base mais plus gourmand en mémoire, est "d'embarquer" les données de MEmployeur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    MSponsoring est une Classe <MAPPING=Sponsoring>
            PRIVE
    	<MAPPING>
    	m_nSP_ID		est un entier sur 8 octets	<MAPPING=SP_ID, clé unique>
    	m_dSP_Validite	est une Date				<MAPPING=SP_Validite>
    	m_sSP_remarque	est une chaîne ANSI			<MAPPING=SP_remarque>
    	m_nSP_Employeur	est un entier sur 8 octets	<MAPPING=SP_Employeur>
    	<FIN>
            m_clrefEmployeur est MEmployeur
     
    FIN
    m_clrefEmployeur est défini dans le constructeur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    PROCÉDURE Constructeur()
    HLitRecherchePremier(Employeur,PK_Employeur,:m_pkEmployeur)
    FichierVersMémoire(m_clrefEmployeur,Employeur)
    p_NomEmployeur devient alors
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    FONCTION p_NomEmployeur() : chaîne
     
    RENVOYER :m_clrefEmployeur:p_saNomEmployeur
    p_saNomEmployeur étant le getter de m_saNomEmployeur dans la classe MEmployeur

  12. #12
    Membre chevronné Avatar de wd_newbie
    Homme Profil pro
    Développeur
    Inscrit en
    Mars 2007
    Messages
    760
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2007
    Messages : 760
    Par défaut
    Je dois être un peu blond ...

    J'ai créé un nouvelle attribut m_sRaisonSociale dans la définition

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    MSponsoring est une Classe <MAPPING=Sponsoring>
     
    	// Le code se trouvant entre <MAPPING> et <FIN> est généré automatiquement.
    	// Il sera effacé et recréé entièrement à chaque génération depuis l'analyse.
    	<MAPPING>
    	m_nSP_ID		est un entier sur 8 octets	<MAPPING=SP_ID, clé unique>
    	m_dSP_Validite	est une Date				<MAPPING=SP_Validite>
    	m_sSP_remarque	est une chaîne ANSI			<MAPPING=SP_remarque>
    	m_nSP_Employeur	est un entier sur 8 octets	<MAPPING=SP_Employeur>
    	<FIN>
    	m_sRaisonSociale  est une chaîne ANSI  // recuperation de la valeur 
     
    FIN
    Une nouvelle propriété Nom_sponsors

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    PROCÉDURE PROTÉGÉE Nom_Sponsors()
         HLitRecherchePremier(Employeurs,E_ID,:m_nSP_Employeur)
         RENVOYER Employeurs.E_RaisonSociale
    Et dans le constructeur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    PROCÉDURE Constructeur()
    :m_sRaisonSociale = Nom_Sponsors
    Mais rien ne fonctionne le HLitPremier() me donne toujours 0 ... je suppose que lorsque l'on construit ... la valeur de m_nSP_Employeur n'est pas encore définie ...

  13. #13
    Expert confirmé
    Avatar de Voroltinquo
    Homme Profil pro
    Chef de projet en SSII
    Inscrit en
    Juin 2017
    Messages
    2 949
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Chef de projet en SSII

    Informations forums :
    Inscription : Juin 2017
    Messages : 2 949
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par wd_newbie Voir le message
    je suppose que lorsque l'on construit ... la valeur de m_nSP_Employeur n'est pas encore définie ...
    En effet, tu nous as parlé d'un tableau de MSponsoring donc une affectation via FichierVersTableau qui récupère les données puis exécute le constructeur.
    Pour une utilisation "individuelle", il faut modifier le constructeur comme suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    PROCEDURE Constructeur(pkSponsoring est entier sur 8=0)
    SI pkSponsoring<>0 ALORS
         HLitRecherchePremier(Sonsoring,SP_ID,pkSponsoring)
         FichierVersMémoire(objet,Sponsoring)  //Affectation des données mappées
    FIN
         //On termine les affectation des membres non mappés
         HLitRecherchePremier(Employeurs,E_ID,:m_nSP_Employeur)
         :m_saRaisonSociale=Employeur.E_RaisonSociale
    Utilisation :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    clMonSponsoring est MSponsoring
    clMonSponsoring=allouer un MSponsoring(2) //

  14. #14
    Membre chevronné Avatar de wd_newbie
    Homme Profil pro
    Développeur
    Inscrit en
    Mars 2007
    Messages
    760
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2007
    Messages : 760
    Par défaut
    je voulais bien faire un tableau d'objets.

    J'ai refait tout le truc et cette fois ça marche ... j'avais dû faire une bourde (laquelle ?? ...)

    En mettant "simplement"
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    PROCÉDURE PUBLIQUE Nom_Sponsors()
     
    HLitRecherchePremier(Employeurs,E_ID,:m_nSP_Employeur)
    RENVOYER Employeurs.E_RaisonSociale

    J'ai bien le nom du sponsor qui remonte

    Merci pour votre aide ! Je vais certainement en avoir encore besoin en POO

    Une chose : quelqu'in connait et utilise ce framework Wx ?

    https://wlplus.org/fr/betula/start/

  15. #15
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Janvier 2005
    Messages
    59
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations forums :
    Inscription : Janvier 2005
    Messages : 59
    Par défaut Utilisation de Betula
    Bonjour,
    J’utilise Betula pour windev et cela simplifie beaucoup la conception de mon programme et le rend sécuritaire

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. POO design pattern Singleton avec Windev
    Par Atsibat dans le forum Contribuez
    Réponses: 2
    Dernier message: 30/11/2012, 13h57
  2. Langages POO avec template
    Par kot dans le forum Langages de programmation
    Réponses: 6
    Dernier message: 05/05/2006, 12h23
  3. Réponses: 9
    Dernier message: 20/03/2006, 17h40
  4. [MVC]Modélisation POO avec BD
    Par fremsoi dans le forum MVC
    Réponses: 1
    Dernier message: 08/11/2005, 13h53

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo