Le forum (ô combien francophone) des utilisateurs de Powerbuilder.
Bonjour,
J'ai besoin de copier une datawindow de type crosstab vers une autre.
Ma datawindow d'arrivée n'a pas de style définit, est ce que cela pourrait gêner?
J'ai essayer de modifier le staticmode avant de faire un rowscopy, mais mon rowscopy me retourne toujours -1 y'a til une subtilité pour utiliser le rowscopy avec un crosstab??
D'avance merci de votre réponse
Dernière modification par djeckelle (04-09-2008 09:04:47)
Hors ligne
salut,
il me semble que les fonctions rowscopy et sharedata ne fonctionnent pas sur un crosstab...
Hors ligne
des pistes :
* toutes les controles (en particulier textes) identiques
* méthode avec GetFullState, SetFullState
voir ici : newgroups
Hors ligne
Merci erasorz ca fonctionne.
Hors ligne
djeckelle a écrit:
Merci erasorz ca fonctionne.
à la bonne heure, quelle méthode fonctionne :
* toutes les controles (en particulier textes) identiques
ou
* méthode avec GetFullState, SetFullState
?
Hors ligne
C'est la méthode avec getfullstate et setfullstate.
Tout d'abord je met le staticmode = Yes sur ma datawindow source et ensuite j'applique le code suivant
blob lblb_data // Buffer integer li_retour // On associe le dataobject à la datawindow destination adw_dest.dataobject = adw_source.dataobject adw_dest.settransobject(sqlca) // On stocke dans un buffer // - les spécifications des objets de la DataWindow source, // - les données tampons li_retour = adw_source.getfullstate(lblb_data) if li_retour <> -1 then //On applique le buffer à la datawindow de destination li_retour = adw_dest.SetFullState(lblb_data) end if
Je ne sais pas si c'est propre et correct mais cela focntionne et même bien.
Hors ligne
En fait il me reste un petit problème
Le crosstab que je veux copier contient dans un trailer de group une compute représentant un total avec l'expression suivante : sum(valeur for group 2)
Une fois ma copie réalisée la première colonne est renseignée avec son total (Correct), mais les colonnes suivantes reprennent le même total.
Avez vous une autre brillante idée???
Hors ligne
salut
GroupCalc ?
Hors ligne
J'apelle adw_dest.groupcalc juste après le morceau de code que j'ai noté dans mon précédent message, tu penses que cela peut poser problème ?
Hors ligne
Bonjour,
Fais-tu un "sort" après le groupcalc sur ta datawindow?
Hors ligne
Non , car je n'ai pas de tri mis en place.
J'ai testé en le mettant en place mais cela ne change rien.
Hors ligne
J'ai réalisé un autre test, si je rajoute parès mon setfullstate le code ci-dessou, j'ai bien mes totaux, par contre je perd la mise en forme, tout ce qui est caché s'affiche.
ls_values = adw_source.Describe("DataWindow.Crosstab.Values") ls_values = "DataWindow.Crosstab.Values='" + ls_values +"'" adw_dest.Modify(ls_values)
Hors ligne
djeckelle a écrit:
Non , car je n'ai pas de tri mis en place.
J'ai testé en le mettant en place mais cela ne change rien.
Je suppose que tu as mis ton tri avant le groupcalc lors de ton test?
Hors ligne
Non je suis allée consulter l'aide et j'ai mis le tri après pourquoi , ce n'est pas bon ??
Hors ligne
djeckelle a écrit:
Non je suis allée consulter l'aide et j'ai mis le tri après pourquoi , ce n'est pas bon ??
Aide PB a écrit:
GroupCalc does not sort the data before it recalculates the breaks. Therefore, unless you populated the DataWindow in a sorted order, call the Sort method to sort the data before you call GroupCalc.
Donc, il faut mettre ton "sort" avant le Groupcalc
Hors ligne
J'ai essayé en mettant le sort avant mon groupcalc, ca me donne le même résultat.
Pour info je me suis fiée à ceci :
Sorting and groups To sort a DataWindow object with groups, call GroupCalc after you call Sort.
Sinon, mon problème est lié au fait que dans la datwindow copie l'expression de la compute est identique pour toute soit : sum(valeur for group 2)
Alors qu'il me faudrait sum(valeur_1 for group 2), sum(valeur_2 for group 2), sum(valeur_3 for group 2), ....
J'ai donc écris une boucle qui me parcours les objets afin de regarder pour les objets de type compute leur expression, maintenant il faut que j'arrive à modifier cette expression
Hors ligne
et en copiant uniquement les données ? cela ne va pas ?
Hors ligne
Non
Ce qui se passe c'est que pour les compute créés dynamiquement par le crosstab si à l'intérieur de l'expression de ces dernières il y a le nom d'une autre colonne dynamique l'expression n'est pas mise à jour. De ce fait je me retrouve avec la même valeur pour toutes. Celle de la colonne initiale.
Pour rappel le rowscopy et le sharedata ne fonctionnement pas. J'ai essayé de de copier de data à data ça ne fonctionne pas du tout. Par contre hors mis ce soucis de compute dans mon trailer de group, les méthodes getfullstate et setfullstate fonctionnent.
Mais je suis sur une piste et dès que j'ai plus d'infos je l'indiquerai.
En tous cas merci pour votre aide à tous
Hors ligne
Bonjour,
Enfin ça y est tout fonctionne..
Pour finir, j'ai crée ma propre méthode rowscopy pour les crosstab dans laquelle je modifie dynamiquement les expressions des computes créees dynamiquement.
Pour ceux que ça intéresse voici ma méthode...attention j'ai un peu alléger le code au début car vous êtes des grands et vous savez qu'il faut tester les retours de fonction.
On peut certainement améliorer le tout, mais je l'ai testé et appliqué sur une 10n de crosstab différents..ça fonctionne du tonnerre.
blob lblb_data // Buffer integer li_retour // code retour de fonction integer li_cpt // compteur integer li_nb_obj=0 // nb d'objets integer li_len_string_obj // Longeur de la chaine d'objets integer li_pos_deb =1 // Position de début dans la chaine integer li_len_obj_courant // longeur de chaine de l'objet integer li_nb_dim // Nombre de dimension d'un structure integer li_len // Longueur de la chaine ls_nom_compute integer li_indice // stocke dans la boucle l'indice dans la structure as_infos_crosstab à lire pour modifier l'expression de la compute à modifier string ls_name // nom d'objets string ls_type string ls_list_objet // Liste d'objets string ls_sep = '~t' // Séprateur dans la chaine entre objets string ls_expression // expression des computes string ls_visible // Propriété visible de la compute string ls_nom_compute // stocke dans la boucle le nom de la compute à modifier string ls_joker = "XXXX" // Chaine de caractère à remplacer dans l'expression de la compute à modifier string ls_new_nom // Nouveau nom de colonne dans l'expression de la compute à modifier string ls_retour // Chaine de retour de fonctions string ls_modify // Chaine de modify boolean lb_fin = false // Booléen utilisé pour la fin de traitement de la boucle. boolean lb_is_child = false // Indique si la compute lu dans la boucle descend de la compute stockée. // - On stocke dans un buffer // - les spécifications des objets de la DataWindow source, // - les données tampons // - et le statut des flags li_retour = adw_source.getfullstate(lblb_data) // - On applique le buffer à la datawindow de destination li_retour = adw_dest.resetupdate() li_retour = adw_dest.SetFullState(lblb_data) // - On passe le crosstab en mode statique afin de manipuler les données des colonnes. ls_retour = adw_dest.Modify("DataWindow.Crosstab.StaticMode=Yes") // Valorise une chaine avec la liste des objets de la datawindow , en suite on parcours les objets de cette chaine ls_list_objet = adw_dest.Describe("datawindow.objects") // On Valorise une chaine avec la liste des objets de la datawindow pour ensuite la parcourir ls_list_objet = adw_dest.Describe("datawindow.objects") if ls_list_objet <> "?" or ls_list_objet <> "!" then // On calcul la longueur de la chaîne li_len_string_obj = len(ls_list_objet) // Compte le nombre de séparateurs li_nb_obj = Pos(ls_list_objet,ls_sep,1) if li_nb_obj >= 1 Then // On parcours la liste d'objet DO WHILE not lb_fin // On incrémente le compteur d'objet li_nb_obj ++ // On redetermine la position li_nb_obj = Pos(ls_list_objet,ls_sep,1) if li_nb_obj = 0 then lb_fin = true li_nb_obj = li_len_string_obj+1 end if // - On récupère le nom de l'objet et son type (datawindow,column, text, compute (for Computed Field), ...) ls_name = Mid(ls_list_objet, li_pos_deb, (li_nb_obj - li_pos_deb)) ls_type = adw_dest.describe(ls_name+".type") // Dans le cas d'une compute on va lire dans la structure si il existe des infos. // Si OUI , c'est qu'il faut mettre à jour l'expression pour les colonnes créés dynamiquement par le crosstab if ls_type = "compute" then li_len = len(ls_nom_compute) lb_is_child = ((li_len > 0) and (ls_nom_compute = left(ls_name, li_len))) // Si le nom de la compute lu est <> de celui stocké , ou si la compute n'est //pas une fille de la compute stockée on récupère ses infos if (ls_nom_compute <> ls_name) and lb_is_child = false then li_nb_dim = upperbound(ast_infos_crosstab) if li_nb_dim >0 then for li_cpt=1 to li_nb_dim // On regarde si la compute en cours de lecture se trouve dans la structure if not isnull(ast_infos_crosstab[li_cpt].nom_compute) and ast_infos_crosstab[li_cpt].nom_compute = ls_name then li_indice = li_cpt // stocke l'indice dans la structure as_infos_crosstab ls_nom_compute = ls_name // stocke le nom de la compute à modifier end if next end if else // Si la variable ls_nom_compute est renseignée c'est que l'on est en cours de modification des colonnes dynamiques if ls_nom_compute <> "" then ls_expression = ast_infos_crosstab[li_indice].valeur ls_new_nom = ast_infos_crosstab[li_indice].nom_colonne +right(ls_name, len(ls_name) - li_len) ls_expression = f_remplacer_chaine(ls_expression, ls_joker, ls_new_nom,false) // On applique le modify sur la compute avec la nouvelle expression ls_retour = adw_dest.Modify(ls_name +".Expression='"+ls_expression+"'") if ls_retour <> '' then f_isa_error(-1, "Problème de modification de l'expression :"+ ls_retour, "nvo_export_data.uof_rowscopy_crosstab", 16) end if end if end if /*(ls_nom_compute <> ls_name) and lb_is_child = false*/ else /*ls_type <> "compute"*/ li_indice = 0 ls_nom_compute = "" end if /*ls_type = "compute"*/ // On supprime l'objet courant de la liste des objets à traiter li_len_obj_courant = len(ls_name) ls_list_objet = Right(ls_list_objet, (li_len_string_obj - li_len_obj_courant - 1)) // On re-calcul la longueur de la chaîne li_len_string_obj = len(ls_list_objet) loop /*lb_fin*/ end if /*li_nb_obj >= 1*/ end if/*ls_list_objet <> "?" or ls_list_objet <> "!" */
Hors ligne
Hors ligne