J'ai moi aussi un peu pataugé au début sur ce sujet avant de trouver une bonne méthode.
J'aurais beaucoup aimé trouver à l'époque un post expliquant clairement une telle méthode. Alors le voici.
Voilà comment je procède pour toutes mes éditions effectuées par programmation (une autre possibilité facile est un état basé sur une table déjà présente dans une fenêtre, là tout est quasiment automatique mais c'est une autre sujet).
C'est du coup très facile et très souple :
a) j'ai en général une fenêtre qui présente tous les critères possibles de sélection et le choix parmi les éditions disponibles. En bas de cette fenêtre (exemple "FEN_Edition_Client") dans le bouton de validation je remplis un tableau associatif de chaines "TabCriteres" avec les différents critères sélectionnés par l'utilisateur :
Code : Tout sélectionner
TabCriteres["DateDebut"] = SAI_Critere_DateDebut
TabCriteres["DateFin"] = SAI_Critere_DateFin
...
b) sur l'état j'ajoute donc dans l'ouverture la déclaration de la procédure avec le nom de l'état et dedans j'ajoute le paramètre TabCriteres.
Code : Tout sélectionner
Procedure ETAT_Client_Liste(TabCriteres est un tableau associatif de chaîne)
Code : Tout sélectionner
STLigne est une structure
sCodeClient est une chaîne
sNomClient est une chaîne
...
FIN
UneLigne est une STLigne
TabLigne est un tableau de STLigne
en utilisant tous les critères contenus dans mon tableau TabCriteres pour cosntruire le "WHERE" de la requête SQL.
J'exécute la requête (SQLExec...) et je balaye les résultat. Je remplis ainsi ma variable structure UneLigne puis je l'ajoute dans mon tableau de structure TabLigne.
Code : Tout sélectionner
TANTQUE SQLAvance("Q") = 0
// On remplit la structure ligne
UneLigne.sCodeClient = SQLLitCol("Q",1)
UneLigne.sNomCLient = SQLLitCol("Q",2)
...
// On l'ajoute dans le tableau de structure
Ajoute(TabLigne,Uneligne)
FIN
SQLFerme("Q")
L'état lui même est créé avec l'option "par databinding sur une variable existante" (la variable sera TabLigne)
Pour pouvoir atteindre si nécessaire (cf la fin du post) en cours de lecture des données, une ligne précise de notre tableau de structure TabLigne on va définir un paramètre global I de type entier toujours dans le code d'ouverture de l'état après le SQLFerme.
Code : Tout sélectionner
I est un entier = 0 // Suit la ligne parcourue
Code : Tout sélectionner
I++
f) Parfois (pour ne pas trop alourdir notre requête initiale) on n'a pas récupéré toutes les informations nécessaires dans notre Tableau de structure TabLigne alors on va pouvoir utiliser notre pointeur de ligne (la variable I) pour aller dans le code du bloc souhaité (un bloc de rupture, ou le bloc Corps par exemple) dans l'événement "Avant impression" récupérer encore d'autres informations par exemple stockées dans un tableau global ou via d'autres requêtes ou une méthode.... Tout est possible.
Exemple : on a une rupture dans notre édition sur le CodeClient et on veut afficher un cumul de facturation que l'on a pas pris soin d'inclure dans notre requête initiale mais on dispose d'une méthode CalcCumulFact qui prend en paramètre un CodeClient et renvoi le montant attendu. Et bien dans le code du bloc concerné on va récupérer le bon CodeClient par l'accès à
Code : Tout sélectionner
TabLigne[I].sCodeCLient.
Voilà j'espère que ce descriptif détaillé pourra aider tout ceux qui démarrent avec la programmation d'états sous windev.
Côme, Clairinfo