Précisions sur les variables Source de données
Bonjour,
Dans ce message je veux partager avec vous des précisions sur l'utilisation d'une variable source de données, en particulier en ce qui concerne la "portée" et le nom logique pour une source de données.
Dans deux messages, vmolines présente un problème important sur les Sources de données:
http://www.developpez.net/forums/d82...n/#post4905408
Citation:
Envoyé par
vmolines
Parmi les choses anormales en Windev, c'est la gestion des sources données.
Déclarée en tant que variable locale pour recevoir le résultat d'une requête, si on déclare une source de données locale de même nom dans un autre traitement, les deux sources de données sont en conflit.
[...]
Pour résumer, vous croyez manipuler une variable sdRequete qui contient un jeu d'enregistrement. Que nenni, vous manipulez en fait une chaine globale "sdRequete". D'ailleurs je crois qu'utiliser "sdRequete" en paramètre de hExecuteRequeteSQL ne pose pas de problème à Windev :D.
http://www.developpez.net/forums/d82...n/#post4905850
Citation:
Envoyé par
vmolines
extrait de l'aide :
Citation:
Une source de données déclarée en globale est globale à tous les traitements du projet qui utilisent le contexte HyperFileSQL correspondant à celui où la source de données a été déclarée
Ceci indique implicitement qu'une source de données peut être locale. Or ce n'est pas le cas.
et quand bien même l'aide indiquerait que les sources de données sont globales (sic), il est plus qu'ennuyeux que le compilateur nous laisse joyeusement croire qu'on manipule une variable locale.
Dans l'aide en ligne de mon WD12 il est dit:
Citation:
Une source de données est globale à tous les traitements du projet.
Dans l'aide en ligne sur le web il est dit:
Citation:
Une source de données déclarée en globale est globale à tous les traitements du projet qui utilisent le contexte HyperFileSQL correspondant à celui où la source de données a été déclarée.
De par mon expérience je crois qu'il faut distinguer:
_ • d'une part, la variable de type source de données,
_ • d'autre part, le jeu de données correspondant à cette variable dans le contexte HyperFile.
Un jeu de données est global à tous les traitements qui utilisent le contexte HyperFileSQL correspondant à celui où la source de données a été déclarée.
Mais la "durée de vie" du jeu de données est directement liée à la portée dans laquelle la variable de type source de données est déclarée.
En fait, le contexte HyperFile est nécessairement global. Sitôt qu'on déclare une source de données, elle devient disponible et visible dans le contexte HyperFile, donc globalement.
En dehors de la portée où la variable source de données est déclarée, l'accès à cette source de données se fait seulement au moyen d'un nom logique (une chaîne de caractères).
Le problème relaté par vmolines est que le nom logique attribué à la source de données est identique au nom de la variable de type source de données.
Mais, ce qui n'est pas dit dans l'aide en ligne, c'est qu'il est possible de spécifier le nom logique. Ainsi, en spécifiant le nom logique de la source de données, on peut espérer éviter des "collisions" entre des sources de données qu'on aurait voulu limiter à une portée locale.
Dans l'exemple didactique ci-dessous, je "génère" un nom logique unique en concaténant une chaîne d'horodatage obtenue par la fonction HeureSys().
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| src est une Source de Données
sNomUnique est une chaîne
SQL est une chaîne = "SELECT * FROM CLIENT"
// générer un "nom logique" unique pour la source de données
sNomUnique = src + HeureSys()
// spécifier le "nom logique" de la source de données
src = sNomUnique
SI HExécuteRequêteSQL(src, hRequêteDéfaut, SQL) ALORS
// on peut accéder à la source de donnée via la variable
Info("Source -> Nb enr. = " + HNbEnr(src))
// on peut accéder à la source de donnée via le nom logique
Info("Nom unique -> Nb enr. = " + HNbEnr(sNomUnique))
SINON
Erreur()
FIN |
Et voici comment, en pratique, je l'utilise de façon abrégée dans mes procédures.
Code:
1 2 3 4 5 6 7 8 9 10 11
| src est une Source de Données
SQL est une chaîne = "SELECT * FROM CLIENT"
// spécifier un "nom logique" unique pour la source de données
src += HeureSys()
SI HExécuteRequêteSQL(src, hRequêteDéfaut, SQL) ALORS
...
SINON
...
FIN |
Remarque:
A la place de HeureSys(), il est sans doute préférable d'utiliser la fonction DonneIdentifiant() qui retourne un nombre entier différent à chaque appel, de façon à pouvoir générer une identifiant unique.
Pour les plus gourmands (les veinards qui ont WD15 ;)), il y a aussi la possibilité d'utiliser comme identifiant unique un GUID brut calculé par DonneGUID(guidBrut).
P.S. Merci à une personne de PC Soft qui m'a informé de la possibilité de nommer une variable source de données.
_
Sources de données, alias (HAlias) et changement de répertoire (HChangeRep)
Très intéressant...
J'ajoute ma petite contribution, concernant des problèmes qui peuvent survenir lors de l'utilisation d'alias sur une source de donnée.
En effet, le fait d'"exécuter" avec "HExécuteRequêteSQL" une source de donnée pour en faire un "jeu de données" fait perdre à la source de donnée initiale le changement de répertoire effectué avec HChangeRep().
Il n'est pas possible d'utiliser la même variable source de donnée pour décrire un fichier et pour parcourir ce même fichier.
Code:
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
|
//Le répertoire de base des fichiers de l'analyse (Contexte hyperfile du projet) est "C:\Base"
//(CLIENT..Répertoire renvoie "C:\Base")
sdClientAlias est une Source de Données = "sdClient"+DonneGUID(guidBrut)
HAlias(CLIENT,sdClientAlias)
HChangeNom(sdClientAlias,CLIENT..NomPhysique)
HChangeRep(sdClientAlias,"C:\BaseAlias")
sReq est une chaîne
sReq = "SELECT "+RC
sReq += sdClientAlias+".Nom "+RC
sReq += "FROM "+RC
sReq += sdClientAlias+RC
//Info(sdClientAlias..Répertoire+" "+sdClientAlias..NomPhysique+" "+sdClientAlias..Nom)
//Affiche C:\BaseAlias CLIENT sdClient812116e59ddf4d708312df9eef7c97d0
SI PAS HExécuteRequêteSQL(sdClientAlias,hRequêteDéfaut,sReq) ALORS
Erreur(HErreurInfo(hErrComplet))
RENVOYER Faux
FIN
Info(sdClientAlias..Répertoire+" "+sdClientAlias..NomPhysique)
//Affiche C:\MonProjet\Exe sdClient812116e59ddf4d708312df9eef7c97d0 sdClient812116e59ddf4d708312df9eef7c97d0!!! |
Pour que cela fonctionne, il faut créer une source de données supplémentaire, avec un nom ET un identifiant différent, et qui contiendra le "jeu de données" issu de la requête :
Code:
1 2 3 4 5 6 7 8 9 10 11
|
sdReq est une Source de Données = "sdReqClient"+DonneGUID(guidBrut)
SI PAS HExécuteRequêteSQL(sdReq,hRequêteDéfaut,sReq) ALORS
Erreur(HErreurInfo(hErrComplet))
RENVOYER Faux
FIN
//On lit le fichier "C:\BaseAlias\CLIENT.FIC"
HLitPremier(sdReq)
Info(sdReq.Nom) |
La source de donnée "sdReq" est identifiée -et accessible- de manière unique par la chaine "sdReqClient"+DonneGUID(guidBrut) dans l'espace de sa portée, déterminé -comme toute variable- par l'endroit de sa déclaration.
Elle contient et permet de parcourir un jeu de données issu de la requête sur le fichier "C:\BaseAlias\CLIENT.FIC".
La source de donnée "sdClientAlias" est identifiée -et accessible- de manière unique par la chaine "sdClient"+DonneGUID(guidBrut) dans l'espace global du contexte hyperfile de sa déclaration.
Elle représente le fichier de nom logique "sdClientAlias", de nom physique "CLIENT" et se trouvant dans le répertoire "C:\BaseAlias".
Il est important de noter qu'une source de donnée de type "jeu de données" et une source de donnée de type "description de fichier" n'ont donc pas la même portée.
Tant que je suis sur les alias et les changements de répertoire, j'en profite pour ajouter que l'utilisation de HChangeRep("*") (avec l'étoile), change
aussi le répertoire des alias de fichiers, ce qui n'est pas vraiment explicite dans l'aide de PC-Soft.
Bonne prog :ccool: