30 juillet 2007

Synthèse pour aller plus vite !

Voyant apparaître sur les forums des demandes de conseils pour optimiser les accès aux données, j'ai regroupé ici les principaux éléments de réponse, et méthodes à employer. L'optimisation des accès est primordiale, surtout lorsqu'ils sont faits au travers d'Internet qui n'offre pas les débits d'un réseau local.

Privilégier les sélections par des requêtes :
Il est préférable d'effectuer les sélections de données au travers de requêtes. En effet, par opposition à des accès enregistrement par enregistrement, elles vont permettre de "ramener" sur le poste client les données sélectionnées, par "paquets" réseau bien remplis. Des lectures enregistrement par enregistrement vont au contraire générer du trafic avec à chaque fois peu de données. De plus la lecture d'un enregistrement impose de récupérer toutes ces rubriques, alors que la sélection d'une requête peut être affinée en ne prenant que les rubriques utiles à un moment donné. Ceci est d'autant plus vrai si la connexion se fait par Internet.

Optimisation des requêtes :
Le menu "Requête / Optimiser la requête" accessible en édition d'une requête doit finaliser la phase de création d'une interrogation. Il permet d'ajouter si besoin les clés dont la requête aura besoin pour un maximum de rapidité.

Statistiques des index à jour :
Les clés dans le fichier sont importantes, à condition que les statistiques des index soient régulièrement mis à jour (surtout après des ajouts en grand nombre).

Rester raisonnable :
La facilité avec laquelle on programme et accède aux données, le tout généralement dans l'urgence, provoque parfois une négligence de l'évaluation de ce que l'on demande. Chaque enregistrement à une taille bien précise, chaque interrogation va ramener un ensemble d'enregistrements, donc un volume précis. Il faut tenir compte, surtout en accès via Internet, de ce volume, afin d'évaluer avec le débit minimal si l'application ne demande pas trop par rapport à ce qu'elle peut recevoir.

Client/Serveur :
Privilégier un accès aux données au travers du moteur Hyper File Client/Serveur, il va permettre de soulager grandement le travail de chaque poste client, et donc de gagner en performances. Les procédures stockées vont offrir également des gains. Typiquement, un long calcul statistiques pourra être fait en "différé" de l'application, permettant à un utilisateur d'avoir un résultat immédiat en remplacement d'une attente.
Son mécanisme de "Log" pourra également permettre un suivi très fin des interrogations en vue de rechercher notamment des abus d'une station, ou d'un traitement.

Analyseur de performances :
Lorsque l'on a encore des attentes, il faut exécuter l'analyseur de performances qui va permettre de les localiser très précisément. Une fois que l'on sait où passe le temps, il devient possible de voir comment l'influencer (dans un programme uniquement à mon grand regret).
Cas particulier pour l'attente du matin, il faut garder dans un coin de tête le possible trouble que peut engendrer la restauration du système.

Ce billet n'a rien d'exhaustif le sujet étant si vaste, je tenterai de le compléter régulièrement. Mais pas trop vite tout de même, car il est temps pour moi de prendre quelques jours de repos en cette période estivale !

Sur le même sujet :
Accélérer le lancement des applications.
Accélérer les traitements d'importation de données

18 juillet 2007

Attente au matin lors de la mise à jour d'un fichier ...

Description surprenante d'un utilisateur final :

Tous les matins le premier enregistrement d'une commande prend du temps, les suivants sont immédiats !?

Surprenante, car c'est plutôt au fur et à mesure que l'on "charge" la machine tout au long de la journée qu'elle ralentit, plutôt qu'à son démarrage. Et pourtant, cela peut se produire avec les postes XP configurés par défaut et utilisant une base Hyper File.

Le fautif : la restauration du système de Windows car elle pense que les fichiers NDX (index Hyper File) sont des fichiers systèmes à sauvegarder. De ce fait, après chaque démarrage du poste, si une modification est demandée sur un fichier Hyper File ("HModifie", "HAjoute", "HSupprime"...), une sauvegarde du fichier est faite et peut donc être coûteuse en temps suivant sa taille. Plus généralement, sont concernées toutes les actions qui provoquent une modification de l'index. En revanche la simple consultation n'a pas d'incidence sur la restauration du système.

La solution consiste à indiquer au mécanisme de restauration du système qu'il doit ignorer les fichiers d'index de votre application. Pour cela une clé de registre est mise à disposition par Microsoft. Il suffit donc d'aller insérer une valeur dans cette clé avec la fonction "RegistreEcrit".

La clé de registre est la suivante : HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\BackupRestore\FilesNotToBackup
Il faut insérer une valeur texte dont le nom est une chaîne quelconque, par exemple le nom de votre application, et la donnée le chemin à exclure.

La copie d'écran ci-contre donne une illustration, et ce lien donne une page de détail sur un site Microsoft.

16 juillet 2007

Echec de visualisation des pages d'une aide CHM

Surprise après le déploiement d'une application déployée sur un serveur (aucun fichier sur les postes des utilisateurs à part un raccourci) : les aides au format CHM présentaient une erreur de "Navigation vers la page Web annulée".

Renseignement pris auprès du support, rien de plus normal avec un Windows XP à jour : ce n'est pas autorisé !!! Sécurité Microsoft oblige, les .CHM doivent être en local pour une visualisation directe. Il est cependant possible de passer outre cette "sécurité", en suivant les recommandations de cet article :
http://support.microsoft.com/default.aspx?scid=kb;fr;902225

11 juillet 2007

Mon état est devenu fou, il ne voit pas mon paramètre !

"Tranche de vie", avec un long moment perdu à ne pas réussir à passer un paramètre à un état. Malgré un iImprimeEtat(NomEtat, Paramètre), j'avais systématiquement le message "on attendait 1 paramètres, on en a reçu 0".

Après de longues minutes à chercher, j'ai finalement trouvé mon erreur dans la description de l'état, ou par mégarde les bornes "min" et "max" étaient cochées je ne sais plus pour quelle raison. Le bon code d'appel de l'état avec des bornes et un paramètre aurait du être iImprimeEtat(NomEtat, ValeurBorneMin, ValeurBorneMax, Paramètre).

J'espère que ce billet pourra dépanner quelqu'un, un jour, ce qui me permettra de me sentir moins seul sur pareil bêtise !

10 juillet 2007

Identifier les emails entrants qui sont des réponses aux précédents emails sortants

Il est de plus en plus fréquent de devoir implémenter un suivi des emails dans les systèmes d'information, par exemple pour qu'une réponse soit directement dirigée vers le bon collaborateur.

L'exemple WD Suivi Email de la LST 68 donne le principe de base, en utilisant la variable Email.Référence. Mais j'ai eu besoin d'aller plus loin pour le cas ou l'on souhaite récupérer directement l'identifiant du dernier message que l'on a envoyé. En effet, le champ Email.Référence empile les identifiants des différents messages, il peut donc être utilise de faire un parcours en sens inverse de son contenu pour trouver l'identifiant du dernier message envoyé. D'autre part dans la structure des emails on peut trouver directement l'identifiant du dernier message, dans une section "In-Reply-To".

Voici donc deux fonctions permettant de parvenir au résultat attendu, n'hésitez pas à les réutiliser si elles répondent à vos attentes !

FONCTION ChercheRéférence(_SourceEmail)

// Recherche dans le code source d'un email reçu en paramètre
// s'il s'agit d'une réponse à un message envoyé précédemment
// On recherche d'abord la balise In-Reply-To, puis dans les
// références (en partant de la fin)
// MESSAGEID_DOMAINE est une constante du projet contenant
// le domaine donné lors de l'envoi des messages (partie droite du @)

sReference est une chaîne
sListeRéférence est une chaîne

sReference = :InReplyTo(_SourceEmail)

SI Position(sReference, MESSAGEID_DOMAINE, 1, SansCasse) ALORS
// Une référence a été trouvée, elle est renvoyée.
RENVOYER sReference
SINON
// Pas de "InReplyTo" dans ce message, on va regarder les références de l'email en partant de la fin.
SI Email.Référence <> "" ALORS
// On supprime les espaces entre les références pour les parcourir
sListeRéférence = Remplace(Email.Référence, " ", "")
POUR TOUT CHAINE sReference DE sListeRéférence SEPAREE PAR "><" DEPUISFIN
// On teste si la référence en cours nous appartient
// Si oui, on a retoure car c'est la plus récente et donc celle que l'on veut.
SI Position(sReference, MESSAGEID_DOMAINE, 1, SansCasse) ALORS
RENVOYER SansEspace(Remplace(Remplace(sReference, ">", ""), "<", ""))
FIN
FIN
// Pas de référence trouvée si on arrive jusque là
RENVOYER ""
SINON
// Par de référence non plus (nouveau message ou réception d'un Webmail qui ne les fait pas suivre)
RENVOYER ""
FIN
FIN


FONCTION InReplyTo(_SourceEmail)

// Retourne le In-Reply-To d'un email dont on reçoit
// le source complet en paramètre (par exemple Email.Source)
// Le In-Reply-To trouvé correspond à l'identifiant d'un email
// envoyé précédemment

sInReplyToBalise est une chaîne = RC+"In-REPLY-TO:"
sInReplyTo est une chaîne
nPosInReplyTo est un entier

nPosInReplyTo = Position(_SourceEmail, sInReplyToBalise, 1, SansCasse)

SI nPosInReplyTo > 0 ALORS
sInReplyTo = ExtraitChaîne(_SourceEmail[[(nPosInReplyTo+Taille(sInReplyToBalise)+1) A ]], 1, RC)
RENVOYER SansEspace(Remplace(Remplace(sInReplyTo, ">", ""), "<", ""))
SINON
// L'info n'est pas trouvée
RENVOYER ""
FIN


Si vous faites un copier/coller du code dans votre éditeur, utilisez ensuite le menu "Code ... Réindentation automatique" afin d'avoir le code correctement affiché.

09 juillet 2007

Pourquoi le code de modification d'un champ s'exécute à l'ouverture d'une fenêtre ?

Dans l'ordre normal des choses, l'ouverture d'une fenêtre provoque l'enchaînement des traitements suivants :
- code de déclaration des globales de la fenêtres,
- code d'initialisation successives des différents champs,
- et enfin le code d'initialisation de la fenêtre.

Alors qu'elle peut être l'option qui provoque l'exécution du code de modification d'un des champs, avant le code d'initialisation de la fenêtre ?

C'est l'option "Mémoriser la valeur" du détail de la description des champs. En effet, j'ai bataillé un moment pour trouver pourquoi j'avais un onglet dont le code était appelé de la sorte. C'est comme tout, une fois qu'on le sait, cela devient simple et évident. En effet, comme le système restaure un choix de l'utilisateur de l'application, il exécute également le code qui avait été provoqué par ce choix.

03 juillet 2007

Installation MSI ou CAB ? Localisation Framework ?

Les combinaisons d'installations d'une application WINDEV MOBILE sur un périphérique mobile sont nombreuses, il n'est pas évident de s'y retrouver au départ :
- Utiliser le Framework PC SOFT non renommé,
- Utiliser un jeu de DLL renommées,
- Utiliser un Framework commun renommé.
Le tout à combiner avec le type d'installation retenue : via un fichier MSI ou un fichier .CAB.

Pour faire un bon choix, il faut avoir les réponses aux questions suivantes qui vont dépendre du domaine d'activité, du matériel (...) :
- l'installation sera-t-elle faite sur un mobile directement, sans connexion à un PC ?
- le mobile dispose-t-il d'un espace de stockage important (carte mémoire additionnelle) ?
- plusieurs applications devront-elle être installées ?

Avec ces réponses, il est facile de s'orienter vers le choix le plus adapté, sachant qu'il s'agit de toute façon de compromis :

- installation sur mobile sans connexion à un PC ?
Dans ce cas il faut générer une installation en .CAB qui sera copiée sur le mobile (et automatiquement supprimée après exécution). Dans le cas contraire, un MSI sera préférable car exécuté au travers d'un installeur Microsoft avec lequel l'utilisateur est généralement familiarisé.

- le mobile dispose d'espace avec une carte additionnelle ?
Dans ce cas il est préférable d'utiliser un jeu de DLL renommées, unique pour l'application. De cette manière un .CAB unique sera créé facilitant l'installation. Dans le cas contraire, il faut limiter l'espace occupé en ayant un unique Framework sur le mobile. Si une seule application doit être installée, on garde un jeu de DLL renommées, unique pour l'application. Par contre s'il faut installer plusieurs applications, on retient le choix :
-- utiliser le Framework PC SOFT non renommé pour placer le Framework directement dans le mobile,
-- ou utiliser un Framework commun renommé pour placer le Framework directement sur une carte mémoire.
Dans ces deux cas, 2 fichiers .CAB sont générés : un pour l'application, l'autre pour le Framework.

J'espère que ce résumé pourra donner quelques orientations...

02 juillet 2007

"Mobilité" en nouveau sujet

Quelques jours passés en Suisse le mois dernier, de nouveaux matériels répondants maintenant à des attentes réelles des utilisateurs, et une bonne promo à "1 euro de plus" comme PC SOFT en a le secret, ont eu raison de moi : me voilà tout fraîchement équipé d'un Smartphone (QTEK) HTC S710.

L'occasion donc d'ajouter une nouvelle catégorie dans le Blog : la mobilité ! J'espère prochainement vous faire partager mes premières astuces et conseils, mais il va falloir que je découvre auparavant ce "nouveau monde" ou l'ergonomie doit être sans cesse la priorité du Développeur !

Il ne faut pas se fier aux idées reçues, ces petits concentrés de technologies ne sont plus des gadgets !

Ndlr : ne vous méprenez pas en ce qui concerne la Suisse, j'ai simplement pu y observer une utilisation bien plus fréquente de ce type d'équipement qu'en France. Rien à voir avec ce qui pourrait fâcher un douanier !