PC SOFT

FOROS PROFESIONALES
WINDEVWEBDEV y WINDEV Mobile

Inicio → WINDEV 2025 → Mauvais résultat d'une requete
Mauvais résultat d'une requete
Iniciado por Jean Turcotte, 02,nov. 2019 03:18 - 17 respuestas
Miembro registrado
1.395 mensajes
Publicado el 02,noviembre 2019 - 03:18
Bonjour, j'utilise une requête pour filtrer le contenu d'une Combo sur les 'Marque et Modèle'. A chaque entrée en saisie dans la combo, j'exécute la requête.
Voici ma requete;



Et voici mon code;
nNbrRésultat est un entier
ModeModif(Vrai)
ValeurCombo est une chaîne = MoiMême..Valeur
SI HExécuteRequête(REQ_RechercheInventaire, hRequêteDéfaut, ValeurCombo) = Vrai ALORS
nNbrRésultat = HNbEnr(REQ_RechercheInventaire)
SI HLitPremier(REQ_RechercheInventaire) ALORS
COMBO_Équipement.SupprimeTout()
NombreEnr est un entier = HNbEnr(REQ_RechercheInventaire)
SI NombreEnr <> 0 ALORS
POUR TOUT REQ_RechercheInventaire

Ça fonctionne très bien quand le résultat de la requête trouve des valeurs correspondantes dans la base de données.
Le soucis a lieu quand la requête ne trouve aucun résultat, la variable nNbrRésultat me donne tout de même le nombre 1 comme résultat et la combo affiche toujours la première ligne de donnée de la BD.

Ou est mon erreur?
Merci !

--
Jean Turcotte
WX 24
Android 8.0 sur Galaxy S8
Laptop Lenovo I7 12GB Ram
Miembro registrado
1.395 mensajes
Publicado el 02,noviembre 2019 - 03:32
Voici une capture d'écran démontrant le mauvais fonctionnement;





--
Jean Turcotte
WX 24
Android 8.0 sur Galaxy S8
Laptop Lenovo I7 12GB Ram
Miembro registrado
4.361 mensajes
Publicado el 02,noviembre 2019 - 09:33
C'est un classique, lorsque tu fait une recherche sur une chaîne( via une requête, ou les fonction HlitRecherche (même avec hIdentique,)) Windev te renvoie la valeur la plus proche. Avant d'appliquer le traitement, il faut vérifier que tu as bien la valeur recherchée.
Par ailleurs, pour un tel traitement (recherche d'une seule valeur,) pourquoi passer par une requête (gourmande en temps d'accès,) pourquoi ne pas passer par les fonctions HLitRecherche, quitte au besoin à indexer la table concernée sur ModèleMarque ?

--
Il y a peut être plus simple, mais, ça tourne
Miembro registrado
2.682 mensajes
Publicado el 03,noviembre 2019 - 10:28
Bonjour,

Il faudrait le code complet car je vois déjà que tu vérifies au moins 2 fois le nombre d'enregistrements de la requête.

--
Cordialement,

Philippe SAINT-BERTIN
Miembro registrado
2.321 mensajes
Publicado el 03,noviembre 2019 - 14:05
Bonjour,

Voici un exemple fourni par l'Aide en ligne :
// Initialise la requête
SI HExécuteRequête(REQ_MaRequête) = Faux ALORS
Erreur("Erreur d'initialisation de la requête" + RC + HErreurInfo())
SINON
// Lecture du premier enregistrement de la requête
HLitPremier(REQ_MaRequête)
TANTQUE PAS HEnDehors()
// Traitement sur l'enregistrement de la requête
...
// lecture de l'enregistrement suivant
HLitSuivant()
FIN
FIN
HAnnuleDéclaration(REQ_MaRequête)

C'est rustique mais cela fonctionne !

Une variante possible :
// Initialise la requête
SI HExécuteRequête(REQ_MaRequête) = Faux ALORS
Erreur("Erreur d'initialisation de la requête" + RC + HErreurInfo())
SINON
// Lecture du premier enregistrement de la requête
POUR TOUT REQ_MaRequête
// Traitement sur l'enregistrement de la requête
...
FIN
FIN
HAnnuleDéclaration(REQ_MaRequête)


Donc, pour ton besoin, HNbEnr() est inutile.
On peut encore beaucoup simplifier en liant la combo à la requête et en rafraichissant la combo.
Extrait de l'Aide en ligne :
https://doc.pcsoft.fr/fr-FR/?1013203&name=Requete_et_Table_Fichier
Pour forcer la ré-exécution de la requête, il suffit d'utiliser la fonction TableAffiche (ou ListeAffiche pour un champ Liste ou Combo) avec la constante taRéExécuteRequête.



--
Bon dev,
Jean-Pierre
Mensaje modificado, 03,noviembre 2019 - 14:16
Publicado el 04,noviembre 2019 - 10:51
Voroltinquo a émis l'idée suivante :
C'est un classique, lorsque tu fait une recherche sur une chaîne( via une
requête, ou les fonction HlitRecherche (même avec hIdentique,)) Windev te
renvoie la valeur la plus proche. Avant d'appliquer le traitement, il faut
vérifier que tu as bien la valeur recherchée.
Par ailleurs, pour un tel traitement (recherche d'une seule valeur,) pourquoi
passer par une requête (gourmande en temps d'accès,) pourquoi ne pas passer
par les fonctions HLitRecherche, quitte au besoin à indexer la table
concernée sur ModèleMarque ?


bonjour,

1 - il fait une recherche de type contient (LIKE '%..%') et non une
recherche unique
2 - la gourmandise du temps d'accès n'est vrai que si et seulement s'il
utilise HFSQL classic, en HFSQL C/S les fonctions sont transformées en
requêtes (il en va de même avec tout autre SGBD => MySQL, MSSQL,
Oracle, etc.)
3 - cf. 1

mais tout ceci n'explique pas pourquoi une requête de type contient
renvoi un enreg avec une donnée non correspondante quand il n'y a pas
de données trouvées

--
Cordialement JeAn-PhI
Publicado el 04,noviembre 2019 - 10:52
Jean TURCOTTE vient de nous annoncer :
Bonjour, j'utilise une requête pour filtrer le contenu d'une Combo sur les
'Marque et Modèle'. A chaque entrée en saisie dans la combo, j'exécute la
requête.
Voici ma requete;



Et voici mon code;
nNbrRésultat est un entier
ModeModif(Vrai)
ValeurCombo est une chaîne = MoiMême..Valeur
SI HExécuteRequête(REQ_RechercheInventaire, hRequêteDéfaut, ValeurCombo) =
Vrai ALORS
nNbrRésultat = HNbEnr(REQ_RechercheInventaire)
SI HLitPremier(REQ_RechercheInventaire) ALORS
COMBO_Équipement.SupprimeTout()
NombreEnr est un entier = HNbEnr(REQ_RechercheInventaire)
SI NombreEnr <> 0 ALORS
POUR TOUT REQ_RechercheInventaire

Ça fonctionne très bien quand le résultat de la requête trouve des valeurs
correspondantes dans la base de données. Le soucis a lieu quand la requête ne
trouve aucun résultat, la variable nNbrRésultat me donne tout de même le
nombre 1 comme résultat et la combo affiche toujours la première ligne de
donnée de la BD.

Ou est mon erreur?
Merci !


bonjour,

pouvez-vous essayer ceci :

ValeurCombo est une chaîne = MoiMême..Valeur
HExécuteRequête(REQ_RechercheInventaire, hRequêteDéfaut, ValeurCombo)
HLitPremier(REQ_RechercheInventaire)
SI PAS HEndehors(REQ_RechercheInventaire) ALORS
.....
FIN

--
Cordialement JeAn-PhI
Publicado el 04,noviembre 2019 - 11:06
La première question que je me poserais: que contient ValeurCombo envoyé en paramètre ?? (plus précisément, que retourne MoiMême..Valeur ??)
Publicado el 04,noviembre 2019 - 17:19
Lionel a formulé la demande :
La première question que je me poserais: que contient ValeurCombo envoyé en
paramètre ?? (plus précisément, que retourne MoiMême..Valeur ??)


pas faux mais je dirais que c'est une combo avec saisie donc la valeur
saisie, j'utilise toujours ..ValeurAffichée comme cela pas de pb

--
Cordialement JeAn-PhI
Miembro registrado
1.395 mensajes
Publicado el 04,noviembre 2019 - 22:04
JeAn-PhI a écrit :
Lionel a formulé la demande :
La première question que je me poserais: que contient ValeurCombo envoyé en
paramètre ?? (plus précisément, que retourne MoiMême..Valeur ??)


pas faux mais je dirais que c'est une combo avec saisie donc la valeur
saisie, j'utilise toujours ..ValeurAffichée comme cela pas de pb

--
Cordialement JeAn-PhI

C'est un bon raisonnement.Voroltinquo a écrit :
C'est un classique, lorsque tu fait une recherche sur une chaîne( via une requête, ou les fonction HlitRecherche (même avec hIdentique,)) Windev te renvoie la valeur la plus proche. Avant d'appliquer le traitement, il faut vérifier que tu as bien la valeur recherchée.
Par ailleurs, pour un tel traitement (recherche d'une seule valeur,) pourquoi passer par une requête (gourmande en temps d'accès,) pourquoi ne pas passer par les fonctions HLitRecherche, quitte au besoin à indexer la table concernée sur ModèleMarque ?

--
Il y a peut être plus simple, mais, ça tourne

Si je comprend bien, utiliser la fonction HlitRecherche () avec un Hfiltre (contient...) suivi d'une boucle HlitSuivant serait plus efficace que la fonction HexécuteRequete() utilisé dans mon code?

--
Jean Turcotte
WX 24
Android 8.0 sur Galaxy S8
Laptop Lenovo I7 12GB Ram
Miembro registrado
1.395 mensajes
Publicado el 04,noviembre 2019 - 23:20
Alors voici mon code corrigé;
ValeurCombo est une chaîne = COMBO_ComplétéPar..ValeurAffichée
sCléParcours est une chaîne = HFiltreContient(CONTACT_PERSONNEL, PrénomNomEmployé, ValeurCombo)
COMBO_ComplétéPar.SupprimeTout()
HLitPremier(CONTACT_PERSONNEL,sCléParcours)
TANTQUE PAS HEnDehors(CONTACT_PERSONNEL)
SI HTrouve ALORS
COMBO_ComplétéPar.Ajoute(CONTACT_PERSONNEL.PrénomNomEmployé)
COMBO_ComplétéPar.Ouvre()
HLitSuivant(CONTACT_PERSONNEL)
FIN
FIN
HDésactiveFiltre(CONTACT_PERSONNEL)

Grace à vous, mon code est maintenant fonctionnel, et en plus simplifié.
Merci ! :)

--
Jean Turcotte
WX 24
Android 8.0 sur Galaxy S8
Laptop Lenovo I7 12GB Ram
Miembro registrado
2.682 mensajes
Publicado el 05,noviembre 2019 - 08:52
Bonjour,

Perso je serai resté sur une requête avec une liaison sur sur la requête et un ListeAffiche().

Si tu veux utiliser cette méthode, je t"engage à utiliser les POUR TOUT. Syntaxe plus simple et plus lisible que HlitPremier.

--
Cordialement,

Philippe SAINT-BERTIN
Miembro registrado
499 mensajes
Publicado el 05,noviembre 2019 - 08:53
Comme proposé par Jean-Pierre dans son message, vous pouvez encore simplifier ce code. C'est mathématique : moins de lignes de code, moins de bugs ! :)

ValeurCombo est une chaîne = COMBO_ComplétéPar..ValeurAffichée
sCléParcours est une chaîne = HFiltreContient(CONTACT_PERSONNEL, PrénomNomEmployé, ValeurCombo)
COMBO_ComplétéPar.SupprimeTout()
SI HLitPremier(CONTACT_PERSONNEL,sCléParcours) ALORS
POUR TOUT CONTACT_PERSONNEL
COMBO_ComplétéPar.Ajoute(CONTACT_PERSONNEL.PrénomNomEmployé)
FIN
COMBO_ComplétéPar.Ouvre()
FIN
HDésactiveFiltre(CONTACT_PERSONNEL)


Comme ça, pas de risque d'oublier le HlitSuivant() (et de déclencher de boucle infinie). :)
Publicado el 05,noviembre 2019 - 10:51
Ok, donc ton problème à la base venait de MoiMême..Valeur à la place de MoiMême..ValeurAffichée
Je rejoins ce qui est dit plus haut, je resterais sur une requête plutôt qu'un HFiltre / HLit...
(mais je peux pas te dire pourquoi sinon le modérateur laisse pas passer, comme pour HEnregistre :p)
Miembro registrado
1.395 mensajes
Publicado el 05,noviembre 2019 - 13:44
Merci pour vos conseils mais en définitive, qu'es-ce qui prend moins de ressources, Un HexecuteRequete ou un HlitRecherche ?

--
Jean Turcotte
WX 24
Android 8.0 sur Galaxy S8
Laptop Lenovo I7 12GB Ram
Miembro registrado
1.640 mensajes
Publicado el 05,noviembre 2019 - 14:43
Hello,

Je pense qu'une requête SQL avec SELECT sur uniquement les rubriques qui t’intéressent sera plus rapide.
hlitPremier ou HlitrecherchePremier revient a faire un SELECT * FROM ...

Tu va charger donc en mémoire moins de données donc, forcément, gain de temps.
Miembro registrado
2.682 mensajes
Publicado el 05,noviembre 2019 - 15:30
En fait une requête ne fait qu'un seul accès réseau et renvoie un jeu de résultat qui sera parcouru en mémoire. La lecture fait un accès réseau à chaque lecture.

Il est donc théoriquement plus intéressant d'utiliser une requête plutôt qu'un parcours avec lecture directe du fichier.

Je dirai qu'aujourd'hui et sauf cas particulier, les réseaux sont tellement rapides et le poids de ton enregistrement est tellement faible que ça n'a pas vraiment d'importance.

--
Cordialement,

Philippe SAINT-BERTIN
Miembro registrado
1.395 mensajes
Publicado el 05,noviembre 2019 - 16:33
Merci ! j'utiliserai donc des requêtes;)...

--
Jean Turcotte
WX 24
Android 8.0 sur Galaxy S8
Laptop Lenovo I7 12GB Ram