Le forum (ô combien francophone) des utilisateurs de Powerbuilder.
Bonjour,
Vous m'excusez de revenir sur ce thème, j'ai essayé les solutions qui ont été indiqué mais cela n'a pas marché dans mon cas notament cette solution http://pbadonf.fr/forum/viewtopic.php?pid=23646
Bon le mien c'est que je travaille avec des chaines de caractères du genre '0003038200118' qui est une clé primaire dans une table. Mon souci est de récupérer cette valeur sur le datawindow et l'exploiter. Mais ce message me parvient et là je ne sais plus trop koi faire
Voici ce que je fais dans le itemchange du datawindow:
ligne = dw_1.getrow() if dwo.name = "nomdelacolonnedatawindow" then string valeur=this.Object.nomdelacolonnedatawindow(ligne) exploitation(valeur) end if
Dernière modification par legagneur (29-11-2013 13:18:00)
Hors ligne
Bonsoir,
quelques remarques :
- Svp entoure ton code PB par (code=pb) au début et (/code) à la fin EN REMPLAçANT les parenthèses ( et ) par des crochets [ et ]
(je suis bien obligé de l'écrire avec des parenthèses pour que tu puisse le lire, sinon ça n'apparait pas mais ça te formate le texte entre les 2 balises comme du code PB, plus facile à lire.
- si tu es dans l'event itemchanged tu n'as pas besoin de faire
ligne = dw_1.getrow()
tu peux tout simplement utiliser l'argument row fournit par l'event.
-Pour régler ton problème : déjà identifier ce qui déclenche l'erreur, à priori je parierai plus sur la ligne "exploitation(valeur)", débugge pas à pas ton code afin de voir ce qui déclenche l'erreur, si c'est la ligne "string valeur=this.Object.nomdelacolonnedatawindow[ligne]" remplace là par un GetItem du type approprié
Hors ligne
J'ai essayé de mettre un messageBox à l'entrée du itemchanged mais je constate que le programme n'y entre même pas.
Je donne ici quelques proprietés de la colonne indiqué :*
Style type : Edit
Case : Any(0)
Je ne sais pas si le problème viendrai à ce niveau
Merci
Dernière modification par legagneur (28-11-2013 18:55:09)
Hors ligne
Salut,
Le problème doit venir de la longueur de ta colonne : exemple si ta colonne est de type char ou varchar et qu'elle fait 10 de long et que essaye de rentrer '0003038200118' soit 13 caractères alors tu auras le message "Item does not pass validation test" car avant de rentrer dans l'evt ITEMCHANGED Powerbuilder vérifie la validité de la donnée entrée. Ex si c'est bien que des chiffres dnasle cas ou la colonne est numérique , il vérifie que la longueur de la colonne est valide par rapport à la longueur de la donnée entré par l'utilisateur, que c'est si une date qu'elle soit valide etc...
C'est seulement après tout ces controles que l'evt itemchanged est déclenché. Si une seule erreur survient dans ces contrôles alors l'evt itemchanged n'est pas déclenché mais c'est l'evt Itemerror qui est déclenché et dans ton cas tu ne doit pas avoir de code ou tu effectues un return de 0 dans l'itemerror ce qui a pour effet d'afficher le message standart : "Item does not pass......."
Cdt
Yanis
Hors ligne
Attention, ne pas faire d'affectation a l'initialisation d'une variable, sauf si l'on sait ce que l'on fait!
Code: pb
string valeur=this.Object.nomdelacolonnedatawindow(ligne)
string valeur valeur=this.Object.nomdelacolonnedatawindow(ligne)
Ce qu'il se passe en affectant la variable à l'initialisation, c'est que la valeur est renseignée à la compilation et pas à l’exécution.
Hors ligne
Salut,
Code: pb
string valeur=this.Object.nomdelacolonnedatawindow(ligne)
Cette déclaration est de toute façon impossible à faire( que ce soit avec des parenthèses ????? ou avec des crochets ) donc il n'y a pas à ce poser de question si le contenu est affecté à l'exécution ou à la compilation. Si tu écris celà tu recevras l'erreur "Invalid variable declaration initialization"
Cdt
Yanis
Hors ligne
Yanis a écrit:
Salut,
Code: pb
string valeur=this.Object.nomdelacolonnedatawindow(ligne)Cette déclaration est de toute façon impossible à faire( que ce soit avec des parenthèses ????? ou avec des crochets ) donc il n'y a pas à ce poser de question si le contenu est affecté à l'exécution ou à la compilation. Si tu écris celà tu recevras l'erreur "Invalid variable declaration initialization"
Cdt
Yanis
A bah oui, il faudrait déjà des crochets, mais en plus le compilo interdit l'utilisation de THIS implicitement ou explicitement en initialisation.
Sinon je pensait à un fonctionnement comme celui ci :
string test = string( messagebox("test", "text") )
mais si le code qu'on nous donnes ne compile même pas alors là...
Hors ligne
Bonjour,
J'ai mis la limite de ma colonne à 13, mais le problème persiste. Cependant je vous remercie pour toutes les remarques concernant la déclaration et l'utilisation des variables.
A+
Hors ligne
Salut,
Est ce que ta colonne fait bien 13 de long. La proprité <limit> n'est qu'un mask pour interdire de saisir plus de 13 caractères il ne sagit en rien de la longueur de ta colonne.
Quand tu es dans le design de ta datawindow, click sur le menu <View> puis <Column spécification> et regarde ta colonne de quel type elle est et quelle est sa longueur.
Sinon met le source de ta datawindow et je te dirais pourquoi.
Cdt
Yanis
Hors ligne
Salut,
Merci Yanis, j'ai éditer le datawindow et j'ai constaté que la colonne précise avait un problème, la longueur du champ était de 11 au lieu du 13 que je voulais. Je pense que c'est peut être due au fait que j'ai voulu réutiliser un datawindow qui ressemblait beaucoup à ce que je voulais faire qui est la cause de cela. Car je n'ai pas voulu réprendre le design à zero de mon datawindow, il a fallu que je cree un de même et d'enlever quelques champs qui ne devaient pas me servir et j'obtenais exactement ce que je voulais. Pour toute fin utile, je pense que si vous réutiliser un datawindow qui marche, pour d'autres but, bien vouloir éditer la source pour vous rassurer que les différents champs qui sont restés ont des proprietés compatibles avec ce que vous voulez faire. Néansmoins deux questions me tiennent à coeur:
1- Pourquoi lors de la réutilisation d'un datawindow, l'ajout des champs et la suppression n'impacte pas sur la source du datawindow?
2- J'ai voulu récuperer le champ en question par:
string valeur valeur=dw_1.GetItemString(row,"Macolonnedatawindow")
Mais cela ne marche pas, quelle est l'intruction qui me permettra de récupérer le champ en question?
Merci
Hors ligne
legagneur a écrit:
Mais cela ne marche pas, quelle est l'intruction qui me permettra de récupérer le champ en question?
Quelle est la nature du "non fonctionnement" ? Un message d'erreur, un plantage, une valeur vide ou nulle ?
Est-ce que le type de la colonne est compatible avec GetItemString() ? Autant SetItem() est très accomodant (une seule méthode pour tous les types de colonnes), autant il faut absolument utiliser le bon GetItemxxx() sous risque de plantage.
Hors ligne
Pour m'assurer que j'ai récupérer la bonne valeur, j'utilise un messageBox pour pouvoir m'assurer que j'ai effectivement la bonne valeur. Mais il n'en n'ai rien, aucun message ne m'est envoyé, en fait je n'ai rien. Disons qu'il ne renvoie rien et même le messageBox n'est pas affiché.
Hors ligne
Alors il est fort probable que le GetItemString() fonctionne mais que la valeur soit NULL et que MessageBox() ne fasse rien parce qu'on passe une chaîne nulle.
Le null est "contagieux" : si on concatène une chaine non vide et un null, le résultat est null. Un tas de fonctions PB ne fait rien d'autre que retourner null sans rien faire quand un des paramètres est null.
Un moyen de se protéger du null est
- soit de tester isNull(chaine) (bof, c'est lourd)
- de formater la chaine avec un format transformant le null en chaine vide :
valeur=string(dw_1.GetItemString(row,"Macolonnedatawindow"), "[general]")
Hors ligne
Tout à fait. C'est même d'ailleurs une des raisons pour lesquels l'utilisation du debugger
à la place des messagebox est plus que recommandé.
Hors ligne
OK, Je vous remercie tous pour vos contributions,
Pour récupérer la valeur de la colonne, il faut tout simplement utiliser Data qui est passé en paramètre de Itemchange. Un peu comme on a utilisé le row.
Je vous dit encore une fois merci
A+
Hors ligne
Bonjour,
J'ai lu un peu en diagonale :
Un GetItemString dans un événement ItemChanged sur la colonne ayant déclenché l'événement, tu récupères l'ancienne valeur courante de la colonne pas la nouvelle que tu viens de saisir.
La valeur que tu viens de saisir se trouve dans l'argument data de l'événement Itemchanged.
Ton code se réduit tout simplement :
if dwo.name = "nomdelacolonnedatawindow" then exploitation(data) end if
La nouvelle valeur saisie deviendra courante à l'issue de l'événement ItemChanged (avec un return 0)
J'ai rédigé ma réponse en parallèle semble t-il.
Hors ligne
foon a écrit:
Tout à fait. C'est même d'ailleurs une des raisons pour lesquels l'utilisation du debugger
à la place des messagebox est plus que recommandé.
J'en remets une couche sur les messagebox : dans les événements "en cours" ça peut fausser le comportement.
Le debugger aussi dans certains de ces cas d'ailleurs...
Tu peux faire une petite fonction de "trace pour développement/debug" qui écrit dans un fichier log ou dans une table.
Hors ligne
erasorz a écrit:
Tu peux faire une petite fonction de "trace pour développement/debug" qui écrit dans un fichier log ou dans une table.
Ou on peut aussi utiliser OutputDebugString() comme expliqué ici et là
Hors ligne
Dans ce type de problème il est préférable de contrôler la zone de saisie temporaire l'aide de la fonction getText() et d'utiliser setText() en lieu et place des setItem()
Dernière modification par Dadone (29-11-2013 14:08:36)
Hors ligne
Salut,
Dadone a écrit:
Dans ce type de problème il est préférable de contrôler la zone de saisie temporaire l'aide de la fonction getText() et d'utiliser setText() en lieu et place des setItem()
Le gettext est inutile dans la mesure ou l'on se trouve dans l'evt itemChanged et que l'un des paramètres est la donnée saisie par l'utilisateur. (DATA) Inutile de faire appel à une fonction alors que l'info est déjà disponible.
Et un setText dans un evt itemchanged est vraiment déconseillé car celui ci écraserait la donnée en cours de saisie.
Maintenant si tu veux dire que dans d'autre evt que l'itemchanged, il est préférable d'utiliser des setText que des setItem c'est parce que dans le code certaines instructions ne sont déclenchés que sur des evt liés à la saisie utlisateur. Si ce code avait été mis dans des fonctions et que ces fonctions avait été appelées juste avant de faire le setitem et dans l'evt itemchanged afin de valider les données que l'on désire accepter, le setitem ou le settext était équivalent.
Cdt
Yanis
Hors ligne
Yanis a écrit:
Salut,
Dans ce type de problème il est préférable de contrôler la zone de saisie temporaire l'aide de la fonction getText() et d'utiliser setText() en lieu et place des setItem()
Le gettext est inutile dans la mesure ou l'on se trouve dans l'evt itemChanged et que l'un des paramètres est la donnée saisie par l'utilisateur. (DATA) Inutile de faire appel à une fonction alors que l'info est déjà disponible.
Et un setText dans un evt itemchanged est vraiment déconseillé car celui ci écraserait la donnée en cours de saisie.
Maintenant si tu veux dire que dans d'autre evt que l'itemchanged, il est préférable d'utiliser des setText que des setItem c'est parce que dans le code certaines instructions ne sont déclenchés que sur des evt liés à la saisie utlisateur. Si ce code avait été mis dans des fonctions et que ces fonctions avait été appelées juste avant de faire le setitem et dans l'evt itemchanged afin de valider les données que l'on désire accepter, le setitem ou le settext était équivalent.
Cdt
Yanis
S'il y a la routine événementielle itemError() déclenchée alors la routine événementielle itemChanged() n'est pas déclenchée.
Ce que je veux dire, c'est qu'il convient de contrôler la zone de saisie temporaire, voir ce qu'elle contient car, in fine, c'est cette zone qui va être à l'origine du déclenchement des autres routines événementielles.
De plus le setText() et getText() fonctionnent même si la datawindow est en query mode ce qui n'est pas le cas pour le geItem() et le setItem()
Donc ce sont des fonctions plus générales.
Après on peut très bien contrôler ce que contient la zone tampon de saisie dans editchanged() par exemple....
Dernière modification par Dadone (29-11-2013 17:21:28)
Hors ligne