Ce guide vous aide à résoudre les problèmes courants rencontrés lors de l'utilisation de l'application WinDev Production Table TL21.
- Problèmes de Saisie
- Problèmes de Verrouillage
- Problèmes de Synchronisation
- Problèmes de Performance
- Erreurs Courantes
Symptômes :
- User B saisit du texte
- User A enregistre une modification
- User B perd sa saisie
Causes possibles :
gbSaisieEnCoursn'est pas défini correctement- Les procédures
MemoriserPositionSaisie()etRestaurationPositionSaisie()ne sont pas appelées - Le callback HSurveille n'est pas correctement implémenté
Solutions :
// Dans l'événement "Entrée dans COL_xxx"
VerrouillerLignePourSaisie() // Cette procédure définit gbSaisieEnCours = Vrai
// Dans l'événement "Sortie de COL_xxx"
gbSaisieEnCours = Faux
PROCÉDURE HSurveille_Callback(NomFichier, Action)
SI gbModificationParMoiMeme = Vrai ALORS RETOUR
SI gbSaisieEnCours = Vrai ALORS
MemoriserPositionSaisie()
TableAffiche(TABLE_Prod_TL21, taRéExécuteRequete)
RestaurationPositionSaisie()
RETOUR
FIN
gbActualisationEnAttente = Vrai
FIN
// Ajouter des logs pour déboguer
Trace("gbSaisieEnCours = " + gbSaisieEnCours)
Trace("gnColonneEnCoursDeSaisie = " + gnColonneEnCoursDeSaisie)
Trace("gsContenuCelluleEnCours = " + gsContenuCelluleEnCours)
Symptômes :
- Le contenu est restauré
- Mais le curseur est à la fin du texte
Cause :
- Limitation technique de WinDev : pas de fonction pour restaurer la position exacte du curseur
Solution :
- Accepter cette limitation
- Le curseur sera toujours placé à la fin du texte après restauration
Symptômes :
- Message d'avertissement affiché
- Impossible d'éditer la ligne
- Aucun utilisateur n'est réellement en train d'éditer
Causes possibles :
- Verrou HFSQL non libéré
- Champ
Modifie_parnon réinitialisé - Crash de l'application sans libération du verrou
Solutions :
// Exécuter ce code pour libérer tous les verrous
POUR TOUT Prod_TL21
SI Prod_TL21.Modifie_par <> "" ALORS
Prod_TL21.Modifie_par = ""
HModifie(Prod_TL21)
FIN
FIN
ToastAffiche("✅ Tous les verrous ont été libérés", toastCourt, cvBas, chCentre)
// Ajouter un champ DateHeureVerrou dans la table
// Libérer automatiquement les verrous de plus de 30 minutes
POUR TOUT Prod_TL21
SI Prod_TL21.Modifie_par <> "" ALORS
nMinutesEcoulees est un entier = DateHeureDifférence(Prod_TL21.DateHeureVerrou, DateHeureSys())
SI nMinutesEcoulees > 30 ALORS
Prod_TL21.Modifie_par = ""
HModifie(Prod_TL21)
FIN
FIN
FIN
// Dans VerrouillerLignePourSaisie(), forcer le déverrouillage
SI Prod_TL21.Modifie_par <> "" ET Prod_TL21.Modifie_par <> gsUtilisateurActuel ALORS
// Demander confirmation
SI OuiNon("La ligne est verrouillée par " + Prod_TL21.Modifie_par + ". Forcer le déverrouillage ?") = Oui ALORS
Prod_TL21.Modifie_par = ""
HModifie(Prod_TL21)
// Continuer le verrouillage
SINON
gbSaisieEnCours = Faux
RETOUR
FIN
FIN
Symptômes :
- Erreur lors de l'appel à
HDébloqueNumEnr() - Verrou HFSQL non libéré
Causes possibles :
- Mauvais paramètre passé à
HDébloqueNumEnr() - Enregistrement déjà débloqué
- Connexion HFSQL perdue
Solutions :
// Correct
HDébloqueNumEnr(Prod_TL21, hNumEnrEnCours)
// Incorrect
HDébloqueNumEnr(Prod_TL21, nID) // ❌ Ne pas utiliser l'ID
SI HBloqueNumEnr(Prod_TL21, hNumEnrEnCours) = Vrai ALORS
// Enregistrement verrouillé, on peut le débloquer
HDébloqueNumEnr(Prod_TL21, hNumEnrEnCours)
FIN
Symptômes :
- User A enregistre une modification
- User B ne voit pas les changements
Causes possibles :
- HSurveille non activé
- Callback non défini
- Base de données non en mode Client/Server
Solutions :
// Dans l'événement "Initialisation" de la fenêtre
HSurveille(Prod_TL21, HSurveille_Callback, hFichierModifié)
PROCÉDURE HSurveille_Callback(NomFichier, Action)
Trace("HSurveille déclenché : " + NomFichier + " - " + Action)
// ... reste du code
FIN
// HSurveille fonctionne uniquement en mode Client/Server
// Vérifier la connexion
SI HConnexion("MaConnexion", "utilisateur", "motdepasse", "serveur:4900", "MaBase") = Faux ALORS
Erreur("Impossible de se connecter à HFSQL Client/Server")
FIN
Symptômes :
- HSurveille se déclenche en boucle
- Performance dégradée
- Application qui freeze
Cause :
gbModificationParMoiMemen'est pas utilisé correctement
Solution :
// TOUJOURS encapsuler les modifications
gbModificationParMoiMeme = Vrai
HModifie(Prod_TL21)
gbModificationParMoiMeme = Faux
// Dans le callback
PROCÉDURE HSurveille_Callback(NomFichier, Action)
SI gbModificationParMoiMeme = Vrai ALORS
RETOUR // ✅ Ignorer ses propres modifications
FIN
// ... reste du code
FIN
Symptômes :
TableAffiche()prend plusieurs secondes- Interface qui freeze
Causes possibles :
- Trop d'enregistrements
- Requête non optimisée
- Pas d'index sur les champs
Solutions :
// Dans l'analyse, ajouter des index sur :
// - IDProd_TL21 (clé primaire)
// - Ordre
// - Modifie_par
// Filtrer par date
HFiltre(Prod_TL21, "Date >= '" + DateSys() - 30 + "'")
TableAffiche(TABLE_Prod_TL21, taRéExécuteRequete)
// Au lieu de rafraîchir toute la table
TableAffiche(TABLE_Prod_TL21, taRéExécuteRequete)
// Rafraîchir uniquement la ligne modifiée
TableAfficheLigne(TABLE_Prod_TL21, nNumLigne)
Symptômes :
- Toasts qui s'accumulent
- Interface encombrée
Solution :
// Limiter les toasts dans HSurveille_Callback
SI gbSaisieEnCours = Vrai ALORS
// Pas de toast pendant la saisie
RETOUR
FIN
// Afficher un toast seulement toutes les 5 modifications
SI gnNombreModifications MODULO 5 = 0 ALORS
ToastAffiche("📝 " + gnNombreModifications + " modifications détectées", toastCourt, cvBas, chCentre)
FIN
Solution : Déclarer la variable dans le code de déclaration de la fenêtre :
gbModificationParMoiMeme est un booléen = Faux
Cause : L'ID de l'enregistrement n'existe plus dans la base.
Solution :
SI HLitRecherchePremier(Prod_TL21, IDProd_TL21, nID) = Faux ALORS
ToastAffiche("⚠️ Enregistrement supprimé par un autre utilisateur", toastCourt, cvBas, chCentre)
TableAffiche(TABLE_Prod_TL21, taRéExécuteRequete)
RETOUR
FIN
Cause : L'enregistrement est déjà verrouillé par un autre utilisateur.
Solution :
SI HBloqueNumEnr(Prod_TL21, hNumEnrEnCours) = Faux ALORS
ToastAffiche("⚠️ Ligne déjà verrouillée", toastCourt, cvBas, chCentre)
gbSaisieEnCours = Faux
RETOUR
FIN
Cause : Aucune colonne n'est sélectionnée.
Solution :
gnColonneEnCoursDeSaisie = TableSelectOccurrence(TABLE_Prod_TL21, tscColonne)
SI gnColonneEnCoursDeSaisie = 0 ALORS
// Pas de colonne sélectionnée, abandonner
RETOUR
FIN
// Dans chaque procédure, ajouter des traces
PROCÉDURE VerrouillerLignePourSaisie()
Trace("=== VerrouillerLignePourSaisie ===")
Trace("gbSaisieEnCours = " + gbSaisieEnCours)
Trace("nIDActuel = " + nIDActuel)
// ... reste du code
FIN
Avant de tester en multi-utilisateurs, vérifier que tout fonctionne en mono-utilisateur :
- Ouvrir la fenêtre
- Entrer dans une cellule
- Modifier le contenu
- Sortir de la cellule
- Vérifier que l'enregistrement est sauvegardé
- Ouvrir 2 instances de l'application (2 ordinateurs ou 2 sessions)
- User A entre dans une cellule de la ligne 1
- User B entre dans une cellule de la ligne 2
- User B commence à saisir
- User A sort de sa ligne (enregistrement)
- Vérifier que User B reste dans sa cellule avec sa saisie
Si vous ne trouvez pas de solution à votre problème :
- Consultez la documentation
- Vérifiez le CHANGELOG
- Ouvrez une issue
Dernière mise à jour : 2025-01-04