25 avril 2007

Comment stopper un sablier récalcitrant ?

Pour faire patienter un utilisateur, l'utilisation d'un sablier est parfaitement adaptée. Mais dans la "vie" d'une application, un traitement simple au départ s'enrichie au fil du temps, fait appel à des composants, dialogues avec d'autres applications ... bref au final, il y a quelque part un Sablier(Vrai) qui persiste et ne veut plus s'enlever même avec un Sablier(Faux) dans le traitement.

Voici une méthode de contournement permettant de s'assurer de la disparition définitive d'un sablier laissé par un traitement.

Il faut créer une procédure globale "StopSablier", qui contiendra uniquement un appel de Sablier(Faux). Les automatismes de procédure feront le reste, comme le montre la copie d'écran du billet. Pour résumer, avec un seul appel de la procédure dans le code, on va appeler 3 fois Sablier(Faux), on est ainsi certain de reprendre le curseur de souris standard !

Pas forcément élégant, mais radicalement efficace !

20 avril 2007

Définir l'instruction suivante pour déboguer 10 fois plus vite !

Pendant longtemps le passage au Débogueur d'un code permettait :
- de suivre l'exécution en pas à pas (F7),
- de repérer le traitement à corriger,
- faire la correction,
- relancer un test pour s'assurer du résultat en ayant donc à refaire tout le processus permettant d'arriver au traitement...

Mais maintenant il y a le bouton que je surnomme le "bouton magique du Débogueur", qui permet de définir l'instruction suivante, tout en débogant. Il facilite en effet considérablement la mise au point et permet :
- de suivre l'exécution en pas à pas (F7),
- de repérer le traitement à corriger,
- faire la correction, et immédiatement rexécuter le code juste avant cette modification !!! Il n'est plus nécessaire de relancer le test et donc de refaire tout le processus permettant d'arriver au traitement.

Il est même possible de changer une fenêtre sous l'éditeur, et de réexécuter son ouverture. Mais là les cas d'usage sont moins fréquents.

16 avril 2007

Migrer une analyse vers une autre base de données...

Les forums contiennent souvent des sujets de la forme "comment migrer mon analyse" en Oracle, en SQL SERVER, MYSQL...

J'avais évoqué ce sujet dans un précédent billet, il n'y a aucune migration à faire au niveau des descriptions de fichiers pour utiliser une base de données ou une autre ! Si dans l'analyse un fichier est décrit en Oracle, sa description peut être appliquée en Hyper File, SQL SERVER ou tout autre base pour laquelle on dispose d'un provider OLE DB ou d'un accès natif.

La clé du mécanisme : les fonctions "HOuvreConnexion" et "HChangeConnexion".

Peu importe le type indiqué dans l'analyse, à tout moment le programme peut :
- appeler "HOuvreConnexion" pour ouvrir une connexion vers une base de données,
- puis appeler "HChangeConnexion" pour associer les tables de l'analyse, à cette nouvelle connexion.

C'est donc un mécanisme à garder dans un coin de tête, bien plus rapide que de se lancer dans des modifications de l'analyse, générations ...

14 avril 2007

Jauge en lieu et place du sablier lors de l'exécution d'une requête, la "soluce" !?

Les utilisateurs ne supportent pas les écrans figés avec un sablier, pourtant imposés lorsqu'une requête importante doit être exécutée.

Afin d'afficher une jauge durant le traitement d'une requête, il faut bien récupérer en premier lieu le nombre d'enregistrements à traiter avec la fonction "HNbEnr", et cette dernière fige l'application avec le sablier tant que toute la requête n'est pas exécutée dans sa totalité.

Et bien cela n'est plus vrai, après consultation des dernières nouveautés !!!

La fonction "HNbEnr" a été dotée d'une option "hNonBloquant". Elle permet de connaître immédiatement après l'appel de la requête, le nombre d'enregistrements déjà récupérés. Il est donc possible de débuter le traitement de la requête par son parcours, tout en affichant une jauge certes approximative, mais une jauge. Au fur et à mesure du parcours, si la propriété "..ExécutionTerminée" retourne faux, il est possible de réajuster la jauge avec le nombre d'enregistrements récupérés en rappelant "HNbEnr".

Tous ceux qui aiment observer les utilisateurs de nos applications, savent déjà que le traitement sera jugé plus rapide, du moment qu'une progression est visible !

13 avril 2007

Extraire sur disque des fichiers contenus dans une bibliothèque ?

J'ai longtemps pensé que cela n'était pas possible, et pourtant ... astuce découverte sur le forum WIN DEV, elle mérite d'être connue j'espère pouvoir la relayer par ce billet !

Je remercie son auteur que je cite (presque) directement :

- Faire un fichier Hyper File avec une rubrique mémo binaire,
- Ajouter les fichiers que l'on veut pouvoir extraire dans le mémo binaire,
- Inclure ce fichier (.fic, .ndx, .mmo) dans l'exécutable,
- dans le code indiquer que pour ce fichier il faut le rechercher dans la bibliothèque :
HChangeLocalisation(Fichier, hWDL)

Et voila.

Il suffit de rechercher dans le fichier Hyper File l'enregistrement qui contient le fichier que l'on souhaite extraire, puis de l'extraire avec :
HExtraitMémo(Fichier,MemoFichier,"C:\chemin...\FichierDestination")

Message d'origine.

Ajout de descriptions de tables MYSQL dans une analyse provoque une erreur MSVCRT.DLL ou WDHF

Rien de pire qu'une action que l'on utilise couramment, et qui sur un poste ne daigne pas s'exécuter. J'ai rencontré ce cas avec l'importation d'une table MYSQL dans une analyse. Après le listage des tables de la base MYSQL, un des messages suivants était affiché :

Une erreur système inattendue est survenue.
Si cet incident se produit de manière systématique
Module MSVCRT.DLL...
Ou :
Erreur interne à la DLL WDHF
L'origine de la panne ? Une version de LIBMYSQL.DLL qui ne convenait pas à WINDEV.
Le problème a donc disparu en installant un MYSQL et en récupérant sa LIBMYSQL.DLL standard. Précédemment il s'agissait d'un MYSQL installé avec par EasyPHP.

Pourquoi la taille d'un fichier Hyper File n'est pas réduite après un lot de suppressions ?

L'appel en série de la fonction "HSupprime()" ne provoque pas la diminution de la taille du fichier. Ceci est valable pour le fichier de données (.FIC) et pour son mémo (.MMO).

Déroutant au premier abord, mais normal en creusant un peu. En effet, pour le système de fichiers (FAT32, NTFS...) l'allocation d'un espace ou sa restitution est coûteuse en temps. Il n'y a qu'à voir la différence de temps entre un copier/coller par l'explorateur, et un couper/coller du même volume. De ce fait en cas de suppression, la taille initiale est conservée, il y a simplement un "marquage" des enregistrements laissés libres par les suppressions. Les ajouts ultérieurs viendront réutiliser ces espaces vides.

Si après une suppression importante on souhaite récupérer l'espace disque correspondant, il est possible d'exécuter la fonction "HRéindexe" avec compression : là tout l'espace est restitué.

A noter que par un parcours séquentiel du fichier sur les numéros d'enregistrements, on peut passer sur les enregistrement marqués à réutiliser (cf. fonction "HEtat").

A noter d'autre part que ce mécanisme met clairement en évidence le fait qu'il ne faut jamais baser un traitement, encore moins une liaison, sur un numéro d'enregistrement puisqu'il n'est pas fixe.