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 :

Etat composite ou états enchaînés ?


Sujet :

WinDev

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    117
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2004
    Messages : 117
    Points : 90
    Points
    90
    Par défaut Etat composite ou états enchaînés ?
    Bonjour à tous,

    Après avoir cherché je me décide à poster et m'en remets à votre sagacité.

    J'avance petit à petit sur Windev, et je suis aussi pataud qu'un nouveau-né. Donc, si mes questions vous paraissent naïves, ne m'en tenez pas rigueur.
    (Petit aparté : j'arrive à prendre en mains cet EDI sans être informaticien de formation. Je développe pour mon entreprise. J'essaie, autant que faire se peut d'être rigoureux. Je suis arrivé sans trop de difficultés à utiliser des outils comme l'indirection (notion qui me faisait assez peur de prime abord), je requête en sql natif, etc. Je suis en tout cas agréablement surpris par l'EDI... Par contre, la partie Etats ne laisse de me perturber tant je n'arrive pas à m'approprier la logique de fonctionnement de ceux-ci !)

    En gros : j'aimerais arriver à un résultat tel que celui-ci : http://doc.pcsoft.fr/fr-FR/?9000128&...iner_des_etats

    Le besoin réside dans un mailing qui est composé d'un courrier, recto-verso, par client.
    Le recto et le verso sont respectivement en portrait et paysage, et comporte des informations de nature très différente (vraiment l'exemple de PCSoft).

    L'idée, bien entendu, est d'avoir un seul document qui est balancé sur l'imprimante.

    J'ai donc créé deux états distincts, chacun alimenté par des requêtes paramétrées distinctes. Jusque-là, pas de soucis. Chaque état s'imprime comme il faut.

    Là où la doc de PcSoft est quelque peu trompeuse, ou en tout cas simpliste (et détrompez-moi le cas échéant), c'est que tant l'état composite que l'état enchaîné génère tout d'abord tous les états 1, ensuite tous les états 2.
    Autrement dit, contrairement à l'exemple de PcSoft, on a à la queue-leu-leu tous les recto et ensuite tous les versos. Pour la sortie imprimante, ça ne le fait pas !

    Première question :

    Est-ce que j'ai mal cherché ? Est-il possible d'organiser la manière dont les états s'enchaînent, étant entendu que cela serait une fonctionnalité et/ou une option qui existe dans l'EDI ?
    Bref, une case à cocher ou une ligne de code assez simple ?
    Si cette fonction existe, inutile d'aller plus loin dans le développement qui suit.

    Deuxième question :

    En considérant que le comportement des enchaînements est bien celui que j'ai découvert, il faut donc réaliser, à travers une boucle, l'enchainement des recto et des verso.
    Pour ce faire, j'abandonne les états composites et j'utilise IEnchainement : http://doc.pcsoft.fr/fr-FR/?1000020059

    L'enchainement est de ce type (code simplifié) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SI HExécuteRequête(REQ_FACTURES,hRequêteDéfaut) = Vrai ALORS 
    HLitPremier(REQ_FACTURES)
    TANTQUE PAS HEnDehors(REQ_FACTURES)
    iEnchaînementAjoute(EtatFacture,REQ_FACTURES.IDClient)
    iEnchaînementAjoute(EtatDetailFacture,REQ_FACTURES.IDClient)
    HLitSuivant(REQ_FACTURES)
    FIN
    Et là, je cale ! Car je passe le paramètre IDClient à mon état, mais je ne sais pas quoi en faire !?!
    J'ai bien cherché de la doc sur le bloc Filtre d'un état, c'est très peu documenté, et je ne trouve aucun exemple un peu parlant (doc PcSoft : http://doc.pcsoft.fr/fr-FR/?1011037&...n_etat#NOTE4_1 )

    J'ai quelques intutions de la manière d'évaluer ce paramètre, notamment en le comparant à l'IDClient du bloc en cours de traitement.

    D'où

    Troisième question :

    L'IDClient n'est pas imprimé sur les documents (j'ai utilisé le concept de client et de facture pour rendre le cas accessible). Je n'ai aucune utilité de cette information pour l'impression.
    Par contre, j'ai bien une rupture sur l'IDClient. Cette donnée fait partie de la source (requête).

    Est-il possible d'avoir accès à cette information lors du processus d'impression sans avoir un champ de l'état qui pointe expressément vers cette donnée ?

    Pour l'instant, je n'ai trouvé qu'une alternative :
    Créer un champ IDClient... et le rendre invisible.
    Dans le traitement filtre, comparer la valeur de ce champ avec la valeur renvoyée par la requête.

    Je trouve cette manière de fonctionner avec un champ invisible assez peu élégante, et ça me laisse sur ma faim.

    Avez-vous d'autres pistes, de manière générale ?

    Dernière précision : il est hors de question de relancer la requête en lui passant en paramètre le IdClient. En termes de traitement et de ressources, cette solution n'est pas envisageable.

    D'avance merci.

    X.

  2. #2
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    552
    Détails du profil
    Informations personnelles :
    Localisation : Laos

    Informations forums :
    Inscription : Mars 2003
    Messages : 552
    Points : 1 193
    Points
    1 193
    Par défaut
    Bonjour,

    Pour votre question 1 :
    Est-ce que l'aperçu avant impression donne le résultat attendu ? Je n'ai jamais essayé un recto/verso et en plus paysage/portrait. Mais en faisant un test rapide (sans imprimer) j'ai bien un enchainement correcte. Je vous l'accorde, ce n'est pas un gage de garanti du résultat final ^^ mais presque.

    Question 2 :
    Je n'ai pas compris votre question...

    Si vous passez un paramètre à votre état, et bien vous le récupérer dans l'état comme n'importe quelle procédure ou passage de paramètre d'une fenêtre à une autre.

    Question 3 :

    Je ne sais pas comment vous avez créer votre requête, mais si vous avez une rupture sur IDClient, alors vous savez récupérer sa valeur, non ?



    Cordialement.

  3. #3
    Expert éminent
    Avatar de frenchsting
    Homme Profil pro
    multitâches-multifonctions
    Inscrit en
    Juin 2003
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : multitâches-multifonctions
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2003
    Messages : 5 202
    Points : 9 190
    Points
    9 190
    Par défaut
    Je n'ai pas compris où était le problème. En effet, tu fais bien tes ienchainementajoute(...), il va "empiler" tes états.

    La question est peut être au niveau de l'état proprement dit : dans le code de l'état portait, il faut que tu fasses :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    PROCEDURE _EtatP(IdC)
    hlitrecherchepremier(Client, idClient,IdC)
    RUB_NomClient = Client.nom
    ...
    Même principe pour l'état paysage: tu as un tableau avec rupture sur le n° de facture. Tu fais un filtrage des factures sur l'idClient dans la description de ton état.

    Attention tout de même au nombre de pages que va générer ton traitement : passé 1000 en aperçu avant impression, ça merdouille un peu...

    Attention également au nombre de lignes sur l'état paysage : il y a "risque" de débordement sur une autre page...
    Commencez toujours appuyer sur la touche F1 et puis n'hésitez à passer par un moteur de recherche...
    Le forum est fait pour répondre aux questions : pas la peine de me les envoyer par MP. Merci.

    Sur internet, tout est vrai ! Honoré de Balzac
    Make it real not fantasy... Herman Rarebell

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    117
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2004
    Messages : 117
    Points : 90
    Points
    90
    Par défaut
    Bonjour,

    Merci d'avoir pris la peine de répondre. Je commence à désespérer. Je me prends tellement la tête, que je n'ai plus le recul...

    J'aurais pu moi-même répondre à ma 1e question en faisant un test basique.

    Donc, Ok, l'empilement "correct" est géré pas le l'enchainement.

    Reste à bien programmer... et de ce côté-là, si vous pouviez me donner des pistes (je ne demande pas du code tout fait, loin de là), mais des pistes.
    Je suis réellement perdu dans cette notion de programmation inhérente à l'état.

    Citation Envoyé par frenchsting Voir le message
    Je n'ai pas compris où était le problème. En effet, tu fais bien tes ienchainementajoute(...), il va "empiler" tes états.

    La question est peut être au niveau de l'état proprement dit : dans le code de l'état portait, il faut que tu fasses :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    PROCEDURE _EtatP(IdC)
    hlitrecherchepremier(Client, idClient,IdC)
    RUB_NomClient = Client.nom
    ...
    Même principe pour l'état paysage: tu as un tableau avec rupture sur le n° de facture. Tu fais un filtrage des factures sur l'idClient dans la description de ton état.
    C'est ce fameux filtrage que je n'arrive pas à mettre en place. Je ne vois pas où et comment dire à l'état d'en tenir compte.

    De plus, je me pose la question suivante : l'état paysage fait un regroupement sur rupture. Il travaille donc sur plusieurs enregistrements. (lesquels enregistrement ont été créés via une requête qui a déjà fait un 1er regroupement avec un SUM) Cette requête n'est pas la même que pour l'état portrait.
    Si je fais un HrecherchePremier (et suivant), je vais avoir un traitement "séquentiel". Comment "dire" à l'état que l'ensemble de ces enregistrement doivent former un tout sur lequel il fera les rupture qui le font bien ?

    Désolé si mes question ne sont pas claires : elles sont le reflet de la confusion que j'ai à comprendre la "logique" des états.

    D'avance merci pour vos pistes.

  5. #5
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    552
    Détails du profil
    Informations personnelles :
    Localisation : Laos

    Informations forums :
    Inscription : Mars 2003
    Messages : 552
    Points : 1 193
    Points
    1 193
    Par défaut
    Il existe plusieurs façon d'arriver à votre résultat, cela dépend essentiellement de la manière dont vous avez codé vos états.

    La source de données des états est fourni par programmation, c'est une requête intégré à l'état, c'est lié à une table dans une fenêtre ?

    Personnellement, j'ai une préférence "par programmation". (cela laisse plus de souplesse lors d'évolution des besoins)

    Quel est votre code SQL de l'état du "détail" ?

    Comment cette requête est implémenté dans votre algorithme ?

    Quel est actuellement votre code d'init de l'état ?

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    117
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2004
    Messages : 117
    Points : 90
    Points
    90
    Par défaut
    Bonjour,

    J'ai quelque peu délaissé ce problème, mais j'y reviens. Je ne désespère pas d'améliorer la performance de ces états, et surtout d'arriver à bien dominer les mécanismes de ces états.

    Donc, en résumé, mon recto reprend toutes les infos liées à mon client (adresse, etc.) et présente une somme globale.
    La requête indépendante à laquelle l'état est lié est la suivante :

    Code SQL : 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
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    SELECT Lots.IDCopaire AS IDCopaire
        ,SUM(ROUND(Budget.MontantBudget/Clef.QuotitesClef*Lots_Clef.QuotitesLot, 2)) AS Total
        ,Copaire.NOM
        ,Copaire.Prenom
        ,Copaire.Boite
        ,Copaire.Co
        ,Copaire.CodePostal
        ,Copaire.CommunicationStructuree
        ,Copaire.Courriel
        ,TO_CHAR(Copaire.DateSolde,'DD/MM/YYYY') AS DateSolde
        ,Copaire.GSM
        ,Copaire.NumeroRue
        ,Copaire.PAYS
        ,Copaire.Rue
        ,Copaire.Solde
        ,Copaire.Ville
        ,Civilite.Civilite
        ,Civilite.Politesse
        ,TypeEnvoi.IDTypeEnvoi
    FROM TypeEnvoi
    INNER JOIN (
        Civilite INNER JOIN (
            Copaire INNER JOIN (
                Lots INNER JOIN (
                    (
                        Clef INNER JOIN Budget ON Clef.IDClef = Budget.IDClef
                    ) INNER JOIN Lots_Clef ON Clef.IDClef = Lots_Clef.IDClef
                ) ON Lots.IDLots = Lots_Clef.IDLots
            ) ON Copaire.IDCopaire = Lots.IDCopaire
        ) ON Civilite.IDCivilite = Copaire.IDCivilite
    ) ON TypeEnvoi.IDTypeEnvoi = Copaire.IDTypeEnvoi
    GROUP BY Lots.IDCopaire
        ,Copaire.NOM
        ,Copaire.Prenom
        ,Copaire.Boite
        ,Copaire.Co
        ,Copaire.CodePostal
        ,Copaire.CommunicationStructuree
        ,Copaire.Courriel
        ,TO_CHAR(Copaire.DateSolde,'DD/MM/YYYY')
        ,Copaire.GSM
        ,Copaire.NumeroRue
        ,Copaire.PAYS
        ,Copaire.Rue
        ,Copaire.Solde
        ,Copaire.Ville
        ,Civilite.Politesse
        ,Civilite.Civilite
        ,TypeEnvoi.IDTypeEnvoi
    HAVING (((Lots.IDCopaire)={TriCopaire}) AND ((TypeEnvoi.IDTypeEnvoi)={TriTypeEnvoi}))
    ORDER BY Lots.IDCopaire;

    Pour alimenter le verso dont l'objectif est de détailler le montant global, je requête plus ou moins les mêmes données, sans les sommer, et triées suivant une autre clef (c'est là que les ruptures le feront bien, notamment).

    Code SQL : 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
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    SELECT Lots.IDCopaire AS IDCopaire
        ,Lots.IDLots
        ,TypeEnvoi.IDTypeEnvoi
        ,Civilite.Civilite
        ,Copaire.NOM
        ,Lots.NomLot
        ,Lots_Clef.QuotitesLot
        ,ROUND(Budget.MontantBudget/Clef.QuotitesClef*Lots_Clef.QuotitesLot, 2) AS Total
        ,Budget.TypeBudget
        ,Budget.MontantBudget
        ,Clef.QuotitesClef
    FROM TypeEnvoi
    INNER JOIN (
        (
            Civilite INNER JOIN (
                Copaire INNER JOIN Lots ON Copaire.IDCopaire = Lots.IDCopaire
            ) ON Civilite.IDCivilite = Copaire.IDCivilite
        ) INNER JOIN (
            (
                Clef INNER JOIN Budget ON Clef.IDClef = Budget.IDClef
            ) INNER JOIN Lots_Clef ON Clef.IDClef = Lots_Clef.IDClef
        ) ON Lots.IDLots = Lots_Clef.IDLots
    ) ON TypeEnvoi.IDTypeEnvoi = Copaire.IDTypeEnvoi
    GROUP BY Lots.IDCopaire
        ,Lots.IDLots
        ,TypeEnvoi.IDTypeEnvoi
        ,Civilite.Civilite
        ,Copaire.NOM
        ,Lots.NomLot
        ,Lots_Clef.QuotitesLot
        ,ROUND(Budget.MontantBudget/Clef.QuotitesClef*Lots_Clef.QuotitesLot, 2)
        ,Budget.TypeBudget
        ,Budget.MontantBudget
        ,Clef.QuotitesClef
    HAVING (((Lots.IDCopaire)={TriCopaire}) AND ((TypeEnvoi.IDTypeEnvoi)={TriypeEnvoi}))
    ORDER BY Lots.IDCopaire
        ,Lots.IDLots;

    La solution qui fonctionne, mais qui n'est ni élégante, ni performante (catastrophique, même...) c'est de jouer sur le code d'ouverture de l'état, puisque le iEnchainementAjoute rejoue le scénario complet de chaque état ajouté.
    J'ai donc dans mon code d'ouverture de l'état (le recto dans l'exemple ci-dessous) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    PROCEDURE InitialisationEtatAppel(gnLeIDCopaire est un entier système, gnLeTypeEnvoi est un entier système)
     
    iInitRequêteEtat(ETAT_Appel,gnLeIDCopaire,gnLeTypeEnvoi)
    Un code similaire se trouve à l'ouverture du verso.

    La procédure appelante du iEnchainementAjoute trie chaque client et renvoie, par une boucle, le ID client en paramètre d'ouverture de l'état en sorte que tant mon recto que mon verso sont liés au bon client (la requête est paramétrée, bien entendu).

    Le gros hic, c'est qu'à chaque ajout, je relance la requête !!! autrement dit, pour un mailing de 70 recto-verso, cela fait pas moins de 140 requêtes lancées !!!
    C'est typiquement la solution à laquelle je ne voulais pas arriver.

    Je reste donc avec mon questionnement initial : est-il possible d'initialiser une seule fois les requêtes nécessaires pour tous les états, et de "dire" à l'état qu'il ne doit, dans la source de données, ne sélectionner que le client qui lui sera passé en paramètres.

    Je continue à pédaler pour trouver cette solution de filtre interne à l'état.

    J'ai dernièrement eu une "idée" mais pas pratique non plus :
    Créer un état libre de toute sources de données (je me prive de certaines facilités) et utiliser des variables globales qui seraient alimentées par une boucle de lecture de la requête. (une forme de publipostage Word-Exel)
    Le contenu de ces variables changerait à chaque boucle. L'état n'aurait aucun traitement à réaliser : ses champs et libellés seraient mappés sur ces variables globales (ce qui devrait rendre l'impression plus rapide). Cela me contrait également à programmer les ruptures. Déjà que je ne suis pas un as...

    Je suis ouvert à toutes les pistes que vous me soumettrez.

    D'avance merci.

    Belle journée.

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    117
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2004
    Messages : 117
    Points : 90
    Points
    90
    Par défaut
    Je relisais le fil des réponses.

    La solution que tu proposes me permettrait effectivement de ne pas devoir rejouer ma requête.
    Cependant, cela entend que je doive programmer chaque champ et libellé "à la main" dans la procédure initiale ?
    Ce n'est que je suis fainéant, mais cela enlève une certaine facilité et rapidité, surtout si on doit faire évoluer l'état.

    C'est pour ça que l'idée d'un filtre me semblait plus intéressante : l'état ne se crée "automatiquement" que sur la seule plage du jeu de données qu'on lui dit de prendre en compte.
    Je ne dois donc pas manipuler les champs par programmation, un à un.

    Citation Envoyé par frenchsting Voir le message
    Je n'ai pas compris où était le problème. En effet, tu fais bien tes ienchainementajoute(...), il va "empiler" tes états.

    La question est peut être au niveau de l'état proprement dit : dans le code de l'état portait, il faut que tu fasses :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    PROCEDURE _EtatP(IdC)
    hlitrecherchepremier(Client, idClient,IdC)
    RUB_NomClient = Client.nom
    ...
    Même principe pour l'état paysage: tu as un tableau avec rupture sur le n° de facture. Tu fais un filtrage des factures sur l'idClient dans la description de ton état.

    Attention tout de même au nombre de pages que va générer ton traitement : passé 1000 en aperçu avant impression, ça merdouille un peu...

    Attention également au nombre de lignes sur l'état paysage : il y a "risque" de débordement sur une autre page...

Discussions similaires

  1. [AC-2003] [Etat]Impression d'état - portrait/paysage
    Par Alain6121967 dans le forum IHM
    Réponses: 7
    Dernier message: 24/04/2009, 15h06
  2. etat composite ou super état comment faire
    Par wxuserbrest dans le forum BOUML
    Réponses: 4
    Dernier message: 22/08/2008, 12h36
  3. [ETAT] rafraichir un état -> est impossible
    Par fredouf dans le forum IHM
    Réponses: 12
    Dernier message: 03/04/2007, 17h01
  4. Etat avec sous-état et variable commune
    Par Alain6121967 dans le forum IHM
    Réponses: 1
    Dernier message: 30/03/2007, 11h46
  5. Etat et sous état référence à une zone de texte
    Par flagfight dans le forum Access
    Réponses: 2
    Dernier message: 06/07/2006, 11h42

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