OVH Cloud OVH Cloud

[WDxx] Pb de recursivité.

5 réponses
Avatar
deje
Bonjour à tous.

J'ai un problème à vous soumettre, concernant le traitement la récursivité
en Hyper File.
Là, je bloque.

Hypothèse de départ:
La table primaire contient les éléments repérés par un champ (type S ou C)
qui indique qu'ils sont simples ou composés.
(Tous les éléments simples contenus dans les composés sont des éléments de
la même table.)

a) La liaison est de type 1 à plusieurs ID lié à ID_Détail dans la table
sous-jacente. (chaque id_détail correspond donc à un composant ou un
composé).
la table primaire contient le champ ID (clé unique numérique auto)
b) La table sous-jacente contient les éléments contenus dans les composés.
la table sous-jacente (tabledetail) contient donc les champs ID_Num (Clé
unique auto) et ID_Detail (clé avec doublons numérique liée à ID de la table
primaire).
Jusque là, rien de plus classique. On obtient de cette façon la possibilité
de créer une arborescence, de composés et de composants.
Une composition peut contenir des composants et / ou des composés. Il n'y
a pas de limite de niveau d'imbrication. (en réalité, cela n'excède pas une
dizaine de niveaux, mais une limite est fixée pour éviter les références
circulaires afin de na pas saturer la pile système). Je passe les détails
sur le reste des champs, qui correspondent aux caractéristiques des
éléments.

Problème à résoudre à l'aide d'une fonction récursive.

Stocker dans une 3eme table (TableCible, sur un seul niveau, tous les
composants Simples contenus dans les compositions des différents niveaux,.
C'est ce qu'on peut appeler une mise à plat de la composition de départ.

J'ai réalisé cette programmation en VB, a l'aide de DAO, en la traitant par
récursivité directe, ça fonctionne très bien et très vite.
Par contre, à l'aide de HF, je ne peux pas obtenir le résultat voulu. La
fonction réentrante bloque après le retour du 1er rappel et ne continue pas
le parcours sur la suite des éléments. Le retour au contexte précédant ne
permet pas de continuer le parcours. Pourtant, il pointe sur le bon
enregistrement.
L'algorithme incriminé est du type : (j'ai simplifié)
___________________________
MiseAPlat(ID)
vPosition est une chaine

HRecherchePremier(TtableDetail,ID)
Hlit()
vPosition=HSauveposition()
Boucle
Si HEndehors() = vrai sortir
Si vType = "S" alors // vType est récupéré dans la table
primaire en partant du ID correspondant au ID_Detail en cours.
Stocke(TableDetail.ID_Detail, TableCible) // stockage du
composant dans la table cible.
sinon // vType = "C"
MiseAPlat(ID_Detail) // réentrance.
HRetourPosition(vPosition)
Fin
HLitsuivant(TableDetail)
Fin
Fin
_____________________________________
En HF, la même utilisation de la récursivité, en traçant uniquement
l'arbre de la structure arborescente, ça fonctionne parfaitement.

D'après vous, où est l'erreur ?

Par avance merci, mais ne perdez pas trop votre temps si vous en manquez.
J'espère que ce fil apportera à d'autres un bon sujet de réflexion !
D.JUPIN

Email : papi83NoSpam@free.fr
(supprimer NoSpam)

5 réponses

Avatar
deje
Erreur ! vPosition est un entier , mais ça ne change rien au problème.

DJUPIN
Avatar
Maax°\(51\)°
Salut,

Essaie en mettant

HRetourPosition(vPosition,hRPConserve)

Dixit de la doc :
hRPConserve La position n'est pas libérée (d'autres HRetourPosition
pourront être réalisés sur cette position)



Ton pb vient peut etre de la

@+
Maax°(51)°

"deje" a écrit dans le message de news:
436c7e57$0$21229$
Erreur ! vPosition est un entier , mais ça ne change rien au problème.

DJUPIN




Avatar
patrice
"deje" a écrit dans le message de
news:436c58ea$0$21036$
MiseAPlat(ID)
vPosition est une chaine

HRecherchePremier(TtableDetail,ID)
Hlit()
vPosition=HSauveposition()
Boucle
Si HEndehors() = vrai sortir
Si vType = "S" alors // vType est récupéré dans la table
primaire en partant du ID correspondant au ID_Detail en cours.
Stocke(TableDetail.ID_Detail, TableCible) // stockage du
composant dans la table cible.
sinon // vType = "C"
MiseAPlat(ID_Detail) // réentrance.
HRetourPosition(vPosition)
Fin
HLitsuivant(TableDetail)
Fin
Fin



et si au lien de hsauve/hretour ne pas essayez plutot de sauver le n°
d'enregistrement, puis de repositionner dessus par un hlit() et de remettre
la clé par hchangecle() ?
Avatar
deje
Merci pour votre réponse, elle m'a permis de comprendre le pourquoi du
problème.
En réalité, on peut libérer le contexte, mais il doit l'être à la sortie de
la fonction réentrante, et non pas après le retour de celle-ci.
La fonction ainsi modifiée a un comportement parfaitement stable et remplit
bien ce pourquoi elle a été prévue.
Il n'en reste pas moins que l'aide est un peu pauvre, surtout en matière
d'exemples concrets. Cette notion de contexte est particulièrement
importante, et n'est pas (à mon avis) suffisamment documentée.
Sincères remerciements pour votre aide qui m'a fait gagner un temps
précieux.
Cordialement
D. JUPIN
Avatar
deje
Bonsoir,

Merci pour votre réponse, effectivement, on peut utiliser votre proposition,
mais j'ai trouvé la méthode qui fonctionne bien avec la sauvegarde du
contexte, qui est à mon avis la plus appropriée, quand à l'utilisation du
filtre comme on peut le voir dans le code que je joins et qui peut servir à
ceux qui se posent la même question.


--------------------------------
Voici la fonction (simplifiée) :

MiseAPlat(ID)
// l'ID est la clé de la composition à mettre à plat.
vPosition est une chaîne
// sauvegarde du contexte
vPosition=HSauveposition(TableDetail)
HActiveFiltre(TableDetail)
HFiltre(TableDetail,"ID",ID)
HLitPremier(TtableDetail,"ID")
Boucle
Si HEndehors() = vrai sortir
Si vType = "S" alors // vType est récupéré dans la table
primaire en partant
// du ID correspondant au
ID_Detail en cours.
Stocke(TableDetail.ID_Detail, TableCible) // stockage du
composant dans la table cible.
sinon // vType = "C"
MiseAPlat(ID_Detail) // réentrance.
Fin
HLitsuivant(TableDetail)
Fin
Fin
HRetourPosition(vPos,hRPFiltre)
-------------------------------
Merci encore.
Salutations.