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 :

perte de la source de données dans une procédure récursive [WD17]


Sujet :

WinDev

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé Avatar de droliprane
    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Mai 2005
    Messages
    710
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Vendée (Pays de la Loire)

    Informations professionnelles :
    Activité : Architecte de système d'information
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2005
    Messages : 710
    Par défaut perte de la source de données dans une procédure récursive
    Bonjour, pour une fois je vous soumets un problème hyper simple à expliquer, j'ai une procédure de calcul de cout d'une gamme de fabrication.

    Cette gamme de fabrication est concue comme un arbre orienté, donc avec des noeuds qui pointent vers des suivants, tout ça dans un table sql server qui s'appelle gam.

    Donc je parcours mon "arbre" de fabrication en partant du sommet (la dernière opération d'une gamme pointe vers une opération fictive 0) et je distribue de manière récursive ma procédure sur les différents fils de mon noeud courant.

    Jusqu'ici que du classique.

    Donc ça fonctionne bien tant que je descends dans l'arbre, ça plante au premier retour de procédure dans le TANT QUE, au HLitSuivant(Rs). L'erreur est la suivante :

    Vous avez appelé la fonction HLitSuivant.
    Fichier <Rs> inconnu dans l'analyse, ou requête ou vue non initialisée.
    Comme s'il avait perdu ma source de données au cours des différents appels récursifs.

    Voici la procédure si vous voyez qqchose qui vous choque, pourtant le récursif j'ai plutôt l'habitude, mais c'est une première sos windev :

    Code : 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
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    PROCEDURE CoutFabrication(LOCAL aid est un entier, LOCAL op est un entier)
     
    Rs est une Source de Données
    Rs2 est une Source de Données
    Sql est une chaîne
     
    cout_op est un numérique
    cadence_op est un numérique
    nom_atelier est une chaîne
    taux_atelier est un  numérique
     
    cout_enfants est un numérique
    cout_fab est un numérique
    cout_composants est un numérique
    cout_apres_op est un numérique
     
    // ON VA CHERCHER L'ATELIER DE L'OP, LE COUT ...
    Sql = "SELECT * FROM gam, atl WHERE gam_article = " + aid + " AND gam_op = " + op + " AND gam_atelier = atl_id"
    SI PAS HExécuteRequêteSQL(Rs,Cnx,hRequêteDéfaut ,Sql) ALORS
    	Erreur("Erreur d'initialisation de la requête"+RC+HErreurInfo()+ RC + RC + Sql)
    	RENVOYER -1
    FIN
    SI HLitPremier(Rs) ALORS
    	cout_op = Rs.gam_cout
    	cadence_op = Rs.gam_cadence
    	nom_atelier = Rs.atl_nom
    	taux_atelier = Rs.atl_taux
    FIN
     
     
     
    // on prend la gamme de l'article est on descend l'arbre progressivement jusqu'aux feuilles (op initiales)
    Sql = "SELECT * FROM gam, atl WHERE gam_article = " + aid + " AND gam_op_suivante = " + op + " AND gam_atelier = atl_id"
    SI PAS HExécuteRequêteSQL(Rs,Cnx,hRequêteDéfaut ,Sql) ALORS
    	Erreur("Erreur d'initialisation de la requête"+RC+HErreurInfo()+ RC + RC + Sql)
    	RENVOYER -1
    FIN
    cout_enfants = 0	
    HLitPremier(Rs)
    TANTQUE PAS HEnDehors(Rs)
     
    		cout_enfants = cout_enfants + CoutFabrication(aid, Rs.gam_op)
    		HLitSuivant(Rs)
     
    FIN
     
     
    SI op <> 0 ALORS
     
    	// DANS TOUS LES CAS ON CALCULE LE COUT DE FABRICATION, LE COUT EN COMPOSANTS
    	// CALCUL DU COUT DE FABRICATION
     
    	SI nom_atelier = "STRAITANCE" ALORS
    		cout_fab = cout_op
    	SINON
    		cout_fab = taux_atelier / cadence_op	
    	FIN
     
    	Info(cout_fab)
     
    	// COUT DES COMPOSANTS
    	Sql = "SELECT * FROM nmcl, art WHERE nmcl_article = " + aid + " AND nmcl_op = " + op + " AND nmcl_fourniture = art_id"
    	SI PAS HExécuteRequêteSQL(Rs2,Cnx,hRequêteDéfaut ,Sql) ALORS
    		Erreur("Erreur d'initialisation de la requête"+RC+HErreurInfo()+ RC + RC + Sql)
    		RENVOYER -1
    	FIN
    	HLitPremier(Rs)
    	TANTQUE PAS HEnDehors(Rs2)
    		cout_composants = cout_composants + Rs2.art_prix_revient
    		HLitSuivant(Rs2)
    	FIN
     
    	cout_apres_op = cout_enfants + cout_fab + cout_composants
     
    	Sql = "UPDATE gam SET gam_cout_avant_op = " + cout_enfants + ", gam_cout_apres_op = " + cout_apres_op + " WHERE gam_article = " + aid + " AND gam_op = " + op
    	SI PAS HExécuteRequêteSQL(Rs2,Cnx,hRequêteDéfaut ,Sql) ALORS
    		Erreur("Erreur d'initialisation de la requête"+RC+HErreurInfo()+ RC + RC + Sql)
    		RENVOYER -1
    	FIN
     
     
    FIN
     
    RENVOYER cout_apres_op
    Comme d'habitude je vous remercie par avance car je suis certain que la solution va fuser !!!

    Merci

  2. #2
    Expert confirmé
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 470
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable Données

    Informations forums :
    Inscription : Janvier 2009
    Messages : 5 470
    Par défaut
    Bonjour,
    Il faut peut-être utiliser un contexte HyperFile indépendant dans la procédure.

    Tatayo.

    P.S. Il ne manque pas des hAnnuleDéclaration dans le code ?

  3. #3
    Membre éclairé Avatar de droliprane
    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Mai 2005
    Messages
    710
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Vendée (Pays de la Loire)

    Informations professionnelles :
    Activité : Architecte de système d'information
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2005
    Messages : 710
    Par défaut
    merci de ta réponse.

    je ne bosse pas sur hyperfile mais en direct sur SqlServer

    et concernant l'instruction hAnnuleDeclaration, tu pense que je devrais annuler quoi ? Normalement les objets "Sources de Données" doivent s'empiler et se dépiler au fur et à mesure des appels récursifs, donc je ne vois pas pourquoi il perdrait le pointeur sur la source de données....

    J'ose espérer que windev ne contraint pas à avoir des noms de variables de différents pour chaque instance d'un objet ?

  4. #4
    Membre chevronné
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2009
    Messages
    179
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2009
    Messages : 179
    Par défaut
    Bonsoir,

    Les sources de données ne peuvent pas s'empiler dans windev :

    Une source de données possède un nom interne qui est égal par défaut au nom de la variable. Pour un même contexte de fichier, il ne peut exister qu'une seule source de données avec le même nom. Si vous utilisez des variables de type source de données dans une boucle, un code récursif ou une classe, il est donc nécessaire de modifier le nom interne de la source de données pour assurer son unicité.
    3 ème point dans les remarque

    On peut s'en sortir avec des HSauvePosition et HRetourPosition, mais ça implique d'exécuter une nouvelle fois la requête au retour dans la fonction ...

    (Personnellement je n'aime pas les appels récursif SQL, surtout sur un serveur distant, la procédure peut vite prendre un temps fou en fonction de la connexion. J'essaie toujours si possible de récupérer l'ensemble des données en 1 minimum de requête et en gérant le tout en mémoire)

  5. #5
    Membre éclairé Avatar de droliprane
    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Mai 2005
    Messages
    710
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Vendée (Pays de la Loire)

    Informations professionnelles :
    Activité : Architecte de système d'information
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2005
    Messages : 710
    Par défaut
    Mince alors j'aurais jamais imaginé ça.
    Du coup comment je procède pour créer l'objet source de données avec un nom interne différent à chaque fois ? Je peux utiliser ma variable op pour le nommer de manière distincte mais comment se fait cette déclaration ?

    Je pourrais aussi transformer ma procédure pour fonctionner en itératif mais ça suppose une gestion un peu lourde avec des tableaux et je raisonne plus facilement en récursif.

  6. #6
    Membre chevronné
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mars 2009
    Messages
    179
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2009
    Messages : 179
    Par défaut
    En cherchant dans le forum j'ai trouvé ces sujets :

    Procédure récursive avec requête
    et
    Précisions sur les variables Source de données

    cela devrait résoudre votre problème en théorie.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [CR XI] modifier la source de données d'une procédure stockée vers une commande
    Par battl14 dans le forum SAP Crystal Reports
    Réponses: 4
    Dernier message: 18/05/2011, 14h28
  2. Recuperation des données dans une source de données
    Par randriamanana dans le forum ASP.NET
    Réponses: 2
    Dernier message: 13/07/2009, 16h45
  3. Réponses: 3
    Dernier message: 25/03/2008, 13h04
  4. Saisie de données dans une procédure stockée
    Par Hastaroth dans le forum MS SQL Server
    Réponses: 4
    Dernier message: 25/10/2004, 09h54
  5. Vérification du type de données dans une procédure stockée
    Par biroule dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 16/09/2004, 11h20

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