03 novembre 2006

Accélérateur de traitement ...

Avec son nom tout à fait anodin, la propriété "..AffichageActif" peut accélérer de façon considérables des traitements. En effet, vous pouvez l'observer avec l'analyseur de performances, les accès à l'interface sont coûteux temps. Par exemple un parcours de données avec des "TableAjoute" dans une table mémoire (champ d'affichage) sera plus long qu'un même parcours chargeant une variable tableau (fonction "TableauAjoute"). Là peut intervenir avantageusement la propriété, en inhibant provisoirement l'affichage. Exemple :

NomFenêtre..AffichageActif = Faux
TraitementXYZ()
NomFenêtre..AffichageActif = Vrai

Simple, mais redoutable d'efficacité dans bien des cas de figure !

02 novembre 2006

Etat imprimé à tout faire (zone répétée, variable tableau...)

Par défaut l'assistant de création des états permet de sélectionner des données dans les fichiers de l'analyse, une requête, un champ table...

Il existe une méthode d'impression "passe partout" car elle permet d'imprimer tout aussi facilement tout et n'importe quoi. L'idée de ce billet m'est venue en voyant le forum, pour l'impression des données d'une zone répétée.

Il suffit dans l'assistant de création d'état d'indiquer "Je programme la lecture de ma source de données", puis de créer dans l'état des champs avec les types et masques désirés. C'est le code de l'état et du bloc corps que se chargeront du parcours des données, la programmation est minime :

// code d'ouverture de l'état
// Déclaration d'une globale pour parcourir les répétitions
// ou pourquoi pas les éléments d'une variable tableau...
gnIndice est un entier = 1


// Code de lecture des données de l'état
// Termine l'impression si toutes les répétitions ont été vues
SI gnIndice > ZoneRépétéeOccurrence(FEN_FenetreAppelante.ZR_ZoneRépétée1) ALORS
RENVOYER Faux
SINON
RENVOYER Vrai
FIN


// Code avant impression du bloc corps
// Affectation des champs de l'état avec les attributs
// de la zone qui permettent d'avoir les valeurs
RUB_RUBRIQUE1 = FEN_FenetreAppelant.ZR_ZoneRépétée1.ATT_Attribut1[gnIndice]
RUB_RUBRIQUE2 = FEN_FenetreAppelant.ZR_ZoneRépétée1.ATT_Attribut2[gnIndice]
RUB_RUBRIQUE3 = FEN_FenetreAppelant.ZR_ZoneRépétée1.ATT_Attribut3[gnIndice]
...
// Incrémentation du compteur pour passer à la prochaine répétition.
gnIndice++


Cette méthode peut être étendue à tout ce qui peut se parcourir, dans l'exemple on lit les répétitions d'une zone répétée, mais il peut s'agit d'un tableau, d'une zone mémoire, un fichier texte...

Représentation binaire d'une valeur.

A toute fin utile, voici un traitement proposé en réponse sur le forum pour obtenir la représentation binaire d'une valeur. La fonction de conversion inverse est donnée également.

FONCTION VersBinaire(nValeurDecimal)

sBinaire est une chaîne = ""
nb est un entier = nValeurDecimal

TANTQUE nb > 0
SI modulo(nb,2) ALORS
sBinaire = "1" + sBinaire
SINON
sBinaire = "0" + sBinaire
FIN
nb = nb/2
FIN
RENVOYER sBinaire


Et la récupération d'une valeur exprimée en décimal, à partir de sa représentation binaire :

FONCTION DepuisBinaire(schaineBinaire)

sBinaire est une chaîne = schaineBinaire
i est un entier
j est un entier
nDecimal est un entier
nCalcul est un entier

POUR i = Taille (sBinaire) A 1 PAS -1
nCalcul = 2*Val (sBinaire[[i A i]])
SI nCalcul ALORS
nDecimal += Puissance (nCalcul,j)
FIN
j++
FIN

RENVOYER nDecimal

25 octobre 2006

Comment suis-je devenu définitivement accro des outils PC SOFT (partie 1) ?

J'ai découvert le savoir faire PC SOFT en 1994 avec le trio Hyper Screen, Hyper File et Hyper Screen. Travaillant sur la réalisation d'un tableau de bord(1) pour une chaîne de grande distribution, fraîchement diplômé de l'université de Grenoble, je n'avais jamais fait autre chose que des programmes noirs, avec des interfaces en mode texte. Et là, je faisais des programmes en couleurs, gérant la souris, le défilement de données avec des ascenseurs, l'ouverture de fenêtres les unes par-dessus les autres ... le tout depuis un QBasic sous DOS 6.2 et sa compilation en ligne de commande. Le principe(2) était des plus simple, les 3 produits PC SOFT ajoutaient en quelque sorte des commandes au QBasic, commandes pour gérer l'interface, les données et les éditions. Le résultat était sidérant, avec très peu de commandes le programme était d'une efficacité redoutable, aussi conviviale qu'une application sous Windows 3.1 de l'époque, les problèmes de pilotes en moins !

Sorti de la tristesse des interfaces texte du DOS grâce à Hyper Screen, je me suis tout naturellement mis à la programmation sous Windows. J'ai compulsé de nombreuses heures le Petzold, et, je ne pouvais pas choisir mes outils à cette époque, j'ai fait mes premières fenêtres sous Visual C++ 1.5. Avec la première mouture des MFC (Microsof Foundation Classes), je pensais que la gestion de l'interface et des données serait aussi simple qu'avec Hyper Screen et Hyper File sous DOS. C'était une erreur, je me suis retrouvé avec des compilations infernales et interminables, des classes dans tous les sens, loin très loin de la simplicité de mes précédents développements. Heureusement, mon employeur a changé son fusil d'épaule avec l'arrivée de WINDEV 1.5, et depuis, avec des contextes professionnels différents, je travaille avec les outils PC SOFT. Ca fait donc plus de 12 ans !

Avec WINDEV 1.5 j'ai pu faire mes premières applications Windows en quelques clics, comme on peut le faire aujourd'hui. Le principe est en effet resté le même, on dessine la fenêtre en y plaçant les champs et boutons. On clic sur Go pour tester, sur l'engrenage pour créer l'exécutable à diffuser. J'ai ainsi enchaîné mes créations avec la version 1.5, puis les versions 2, 4 et enfin 5.5 qui a permis le passage en 32 bits. Passage douloureux pour bon nombre de mes collègues qui devaient se soucier de la portée de leurs pointeurs, de la taille de leurs variables entières (...), aisé pour moi qui devait uniquement cocher un sélecteur à la création de l'exécutable (juste les appels des API à adapter). PC SOFT avait tout prévu, comme sous Hyper Screen, et Hyper File qui restait le même avec déjà son système de modification automatique des fichiers de données.

La suite au prochain épisode ...


(1) Tableau de bord : vous comprenez mon billet relatif au tableau de bord des versions 11, j'ai fréquemment travaillé de tout temps sur la présentation des données, et l'aperçu du tableau de bord de suivi des projets est de très bonne augure pour WINDEV 11 !

(2) Cette technique de programmation reste disponible en version 10, elle est illustrée pas des exemples du dossier \Langages Externes\. En C, C#, Basic, Cobol, Fortran on ajoute des "includes" qui donnent accès à Hyper File, Wlangage et aux éléments d'une bibliothèque (.WDL).

20 octobre 2006

Section critique à la bonne place, avec le bon nom...

Dans un programme utilisant plusieurs thread (messagerie instantanée avec Socket, traitements batch...), il peut arriver après un certain temps d'utilisation un blocage (pas de réponse...), ou une disparition pure et simple de la liste des processus, ou un message du mécanisme de sécurité WLangage :

Une erreur système inattendue est survenue.
Module : WD100VM.DLL
Erreur système : Access violation (GPF)
EIP = 12345678


C'est une difficulté sérieuse, car il n'y a en général aucune reproduction systématique, et le traitement donné dans la pile de l'erreur change d'une exécution à l'autre. La piste de recherche à privilégier dans pareil cas, se nomme "section critique". En effet, dès que plusieurs threads s'exécutent en parallèle, ils vont nécessairement à un moment ou à un autre accéder à des éléments partagés. Typiquement, une variable globale du projet, un membre de classe utilisé dans une méthode exécutée par un thread secondaire, et une autre partie de la classe sollicitée dans le thread principal ... les combinaisons sont infinies.

Il faut donc en tout premier lieu en cas d'instabilité vérifier que tous les éléments (variables, membres...) qui sont utilisés par deux thread distincts sont dans une section critique. Sans cela, l'erreur ou le blocage "aléatoire" est quasiment garanti à un moment ou à un autre dans le déroulement de l'application, et le plus souvent après un important nombre d'heures d'utilisation.

A titre d'exemple, si une variable globale du projet est affectée dans un thread secondaire, le code devra être de la forme suivante :

Et bien sûr, la consultation de cette variable dans le thread principal devra se faire avec la même section critique (attention à ne pas faire une faute de frappe dans le nom de la section) :

Ce billet est motivé par plusieurs instabilités aléatoires résolues en ajoutant les bonnes sections critiques. La dernière en date, hier, provenait d'une faute de frappe avec un nom de section critique erroné lors de l'affectation d'un membre !

17 octobre 2006

Demander de l'aide au Framework DotNet ...

Dans le meilleur des mondes, le développeur aurait dans son environnement de développement toutes les fonctions possibles et imaginables créées depuis l'origine de la micro-informatique. Le temps passé à "réinventer la roue" serait enfin réduit à un minimum acceptable. Bien évidemment, ce meilleur des mondes n'est qu'utopie, et c'est tant mieux car le quotidien du développeur deviendrait bien monotone s'il n'était plus nécessaire de se creuser la tête de temps à autre !

Dans la pratique donc, il n'est donc pas rare d'avoir une fonction manquante, nécessitant dans le pire des cas un recodage. Mais c'est un cas extrême avec WINDEV car deux Framework sont à la disposition du développeur.

On pense immédiatement au Framework PC SOFT inclus avec toutes les applications. Il contient à lui seul des centaines de fonctions, des propriétés, l'accès moteur Hyper File, aux bases de données via OLE DB ...

Mais il ne faut pas omettre le Framework .NET directement accessible également. Il apporte de nombreuses possibilités supplémentaires.

Une illustration, obtenir du système un identifiant unique, plus communément appelé GUID (cf. ci-contre). La fonction "iDonneIdentifiant" du WLangage ne convient pas si l'on désire un identifiant unique au niveau du poste, elle ne convient que pour une instance de l'application.

La classe GUID de MSCORLIB inclus en standard dans .NET donne l'information. Il devient alors très facile d'avoir l'information en quelques clics. Le menu "Atelier" donne la possibilité d'ajouter dans le projet les classes de MSCORLIB. Il suffit ensuite de déclarer un objet "GUID" pour obtenir l'information attendue.

L'éditeur de code propose une complétion automatique pour les classes .NET intégrées, cela facile leur utilisation.

Notez qu'en utilisant le Framework .NET dans votre application sa présence sur l'installation cliente sera indispensable. Il faut donc vérifier avant tout le déploiement du Framework .NET sur les postes cibles. Normalement il est fait du moment que Windows update est actif.

13 octobre 2006

Synthèse de l'information, par Google et WINDEV 11 !

C'est chose faite, la version 11 de WINDEV est annoncée. En même temps Google propose une nouvelle version de Blogger. Moi qui adore les découvertes, je suis comblé !

Je suis régulièrement amené ces derniers temps à travailler sur la présentation des données dans des applications existantes. Les tableaux statistiques d'époque ou autre ne conviennent plus à l'utilisateur final, qui veut en un clin d'oeil avoir accès à toute l'information. C'est par exemple une des clés du succès des portails Web qui savent proposer un accueil regroupant les éléments dont a besoin l'Internaute.

Cette "tendance" ressort des nouveautés, puisque Google, et WINDEV 11 propose une notion de "tableau de bord" (dashboard en anglais dans le texte). L'interface du futur Windows Vista est également orientée vers une présentation réellement pensée pour l'utilisateur, et non plus pour le "bidouilleur", ou le connaisseur.

Gageons qu'avec de telles sources d'inspiration, les applications vont prendre un sacré "coup de jeune" en terme d'interface, et d'ergonomie. Alors synthèse de l'information dans nous outils de travail, mais également dans nos productions pour rendre l'outil informatique plus accessible en pensant toujours à ce dont à réellement besoin l'utilisateur final !

12 octobre 2006

On en apprend tous les jours ...

Le développement est un domaine si vaste, qu'il ne se passe pas une journée sans faire de découverte. Ma nouveauté du jour, est la fonction "ChaineRécupère" ! J'ai de tout temps utilisé la fonction "Transfert" qui n'est plus nécessaire maintenant. J'étais passé à côté de cette fonction, je ne sais pas dire dans quelle version de WINDEV elle est apparue.

Un fil du forum décrit l'aspect technique de cette commande.

Moralité, n'oubliez pas de relire régulièrement les documentations diverses, on ne sait jamais tout. Et puis il vient un stade ou l'on en apprend tous les jours, mais on en oublie également.

11 octobre 2006

Poser la bonne question !

Le dialogue instauré entre une application et ses utilisateurs est primordiale. Même avec des modes opératoires parfaitement définis, si l'application propose un choix ambigu l'utilisateur risque une fausse manipulation. Il aura de plus un ressenti négatif envers l'application, la trouvant difficile à utiliser.

Il paraît donc évident que toutes les applications devraient avoir des dialogues peaufinés. Cependant la réalité est différente, car historiquement le développeur disposait pour solliciter l'utilisateur de la fameuse "MessageBox" Windows, accessible en Wlangage au travers des fonctions "OuiNon", "Confirmez" avec les traditionnels boutons Oui, Non, Annuler. Difficile de proposer un dialogue efficace à partir de ce jeu d'instructions, sans passer un temps important dans la création de fenêtres spécifiques.

Pour trouver un juste équilibre entre des messages conviviaux à la réponse facile, sans rallonge de planning, le Wlangage propose une fonction "Dialogue", dotée d'un assistant de mise en œuvre, que je recommande de rendre obligatoire dans toutes vos règles ou chartes de programmation !

En effet, cette fonction permet de trouver le juste équilibre pour que le développeur en un minimum de temps puisse créer une interface de dialogue agréable, et surtout complète.

Voici une illustration, avec une action courante, l'envoi d'un email. Dans le cas ou l'utilisateur final ne renseigne pas le sujet de son message, on va l'en informer. La méthode originale "OuiNon" pouvait donner le type de message ci-contre. Oui, il est un peu caricatural, mais je vous assure l'avoir trouvé dans des applications.

L'utilisation de la fonction "Dialogue" permet d'éviter pareil "désagrément", car elle va permettre au développeur de bien poser la question, tout en proposant des boutons de réponses en texte clair. Notez que l'internationalisation est prise en charge par la fonction "Dialogue". Cette vue de l'assistant se passe quasiment de commentaire. Au centre le message, à droite on gère la présence des boutons, en bas leurs caractéristiques, à gauche l'icone système à afficher...



L'assistant va plus loin, le code de traitement du choix de l'utilisateur est immédiatement généré. Il ne reste plus qu'à insérer l'appel de vos procédures.

Un principe similaire pour un dialogue de saisie est proposé grâce à la fonction "Saisie". Ci-dessous, son illustration extraite de l'aide de WINDEV.



Astuce, n'oubliez pas les minuteries. Il est rare de bloquer une application sur un dialogue, il peut être utile de forcer sa validation sans réponse de l'utilisateur après un certain laps de temps. C'est la fonction "DélaiAvantFermeture" qui appelée avant "Dialogue" vous permet d'ajouter une minuterie sur le bouton qui valide le dialogue.

10 octobre 2006

Piloter la sauvegarde d'une base de données Hyper File Client/Serveur

Voici un code prêt à l'emploi qui m'a donné du fil à retordre, car l'aide en ligne de la commande était erronée ! En effet, il y avait une coquille sur le paramètre permettant de donner le mot de passe. Le bon paramètre est /MDP_DB et non pas /MDP_BD.

Vous pouvez copier directement le code sur le fil correspondant dans le forum

09 octobre 2006

Hyper File, Hyper File Client/Serveur, MYSQL, Oracle, SQL SERVER...

Une demande très courante des développeurs, et de pouvoir changer ou alterner la base de données utilisée par l'application. Utiliser une base Hyper File en mode partage (dit "classique"), ou en mode Client/Serveur suivant le site, ou une base MYSQL...

La solution est très simple, mais de part notre naturel à toujours chercher compliqué, les méthodes employées sont souvent les moins efficaces. Pourtant, avec seulement deux commandes, le W-Langage permet de facilement jongler d'une base de données à l'autre, sans intervenir sur la description des tables dans l'analyse. En effet, le type de base de données indiqué dans l'analyse est indicatif, il est utilisé uniquement par défaut sans mention contraire dans vos traitements. Ainsi dans votre code vous pouvez à tout moment appeler :
- "HOuvreConnexion" : elle permet d'ouvrir une connexion vers une base quelconque, du moment que vous avez une accès natif, ou un provider OLE DB.
- "HChangeConnexion" : elle permet d'associer une ou plusieurs tables de l'analyse, à une connexion qui vient d'être ouverte.
Ainsi une application simplement en redéfinissant la connexion peut changer la base utilisée. Un extrait de code est proposé dans une FAQ PC SOFT.

Attention, il s'agit là du principe de connexion. Bien entendu, le simple faire de changer de base peut ne pas suffire, car chaque base a ses propres spécificités d'utilisation. Si la base Hyper File est en mode Client/Serveur, il faudra privilégier les requêtes pour en tirer les meilleures performances. Mais cela dans un but d'optimisation. Dans tous les cas ou le volume de données traité reste raisonnable, il n'est pas indispensable d'avoir un travail d'optimisation intensif, il est ainsi possible de jongler facilement d'une base à une autre juste avec les commandes "HOuvreConnexion"et "HChangeConnexion".

Ce principe de connexion peut également être utilisé pour effectuer un transfert de données lorqu'il s'agit de bases de données différentes. La notion d'alias vient en renfort, et va permettre d'avoir un unique fichier de l'analyse, accessible en deux exemplaires dans deux connexions différentes. Le traitement peut alors être de la forme suivante :
- "HOuvreConnexion" pour vous connecter à une base quelconque,
- "HAlias" pour avoir une copie du fichier,
- "HChangeConnexion" pour que l'alias travail sur la base sur laquelle la
connexion a été ouverte,
- "POUR TOUT" pour parcourir les enregistrements du fichier source,
- "HCopieEnreg" et "HAjoute" pour copier les enregistrements.
Il est même envisageable de traiter une analyse complète, et plaçant le tout
dans parcours de la liste des fichiers (fonction "HListeFichier").
Il existe également des outils permettant d'effectuer des transferts de données.

06 octobre 2006

Echanger des sources et techniques avec Google ?

L'actualité Google est toujours chargée ces dernières années, elle concerne aujourd'hui tous les développeurs adeptes du partage de sources, et qui ne souhaitent plus réinventer en permanence la roue !

Un nouveau portail "codesearch" a donc vu le jour, et permet d'effectuer des recherches dans les codes sources recensés par Google. Et en matière de recensement, Google sait y faire !

05 octobre 2006

Limiter les ressources sollicitées par les impressions.

Je l'ai évoqué dans un précédent billet, s'il y a bien un domaine dans lequel il faut s'appliquer à ne pas trop solliciter le système, c'est bien celui de l'impression. En effet, si pour l'utilisateur le fait d'imprimer une action anodine, pour le système ce n'est pas rien, il va abondamment solliciter les pilotes de périphériques, les ressources graphiques...

Voici quelques astuces qui vous permettront je l'espère d'augmenter la réussite de vos impressions, essentiellement sur les configurations les plus faiblement dotées (hard et soft).

1. réinitialiser le mécanisme d'impression avant chaque nouvelle impression, avec un appel de la fonction "iRAZ".

2. éviter les images volumineuses en fond de page par exemple en utilisant une image enregistrée pour le Web.

3. sélectionner dans la confi- guration des états, l'option d'impres- sion à chaque page.


4. ralentir l'impression avec la fonction "Multitache" dans le code après impression du bas de page. L'attente doit varier en fonction de la configuration, elle peut être mémorisée dans la base de registres. Un menu "Configuration" de l'application pourra permettre son réglage d'un poste à un autre.

03 octobre 2006

Créer une fenêtre, à partir d'une application existante

Il peut arriver de trouver une fenêtre dans une application existante, avec une interface novatrice ou non, mais en tout cas interessante. Pour réaliser la même dans votre application, une première alternative consiste à recréer champs par champs les éléments de la fenêtre qui aide votre inspiration (notez que je ne parle jamais de copie...).

Mais il y a bien mieux, dans l'assistant de création d'une nouvelle fenêtre. Le volet "Import" vous liste les applications lancées, et vous permet d'en choisir une. A la validation, vous obtiendrez sous WINDEV une fenêtre dont vous pourrez coder les traitements, reprenant tout ou partie de l'interface de l'application existante.

Mise en forme RTF programmée

Voici une méthode que j'utilise couramment pour mettre en forme un texte RTF. Elle permet de créer un "modèle" en RTF, puis de l'utiliser dans un traitement pour une mise en base, ou un affichage.

Première étape, sous Wordpad, préparer le texte avec la mise en forme. Dans le texte, placer des %1, %2 en lieu et place des données effectives, en effectuant toute la mise en forme désirée.

Seconde étape, récupérer à l'aide du bloc note le code RTF avec sa mise en forme, afin de le placer dans une constante du projet. Dans le cas ou la mise en forme doit évoluer régulièrement, il peut être avantageux de récupérer la mise en forme au lancement de l'application, avec la fonction "fChargeTexte".

La technique est en place, pour obtenir l'information avec sa mise en forme dans l'application, il suffira d'affecter un champ RTF, un libellé RTF, ou une rubrique de fichier avec la fonction "ChaineConstruit". Exemple :
LIB_RTF = ChaineConstruit(RTF_RAPPORT, RéseauUtilisateur(), DateVersChaine(DateSys()), sRapport)

Ce texte mise en forme peut également compléter un texte existant, en utilisant la fonction "RTFInsére".

02 octobre 2006

Les possibilités d'un service Web ... sans Web service

L'utilisation d'un Web service peut être commode dans bien des situations pour interroger depuis une application un système distant qui va vous retourner une information : une clé pour l'installation de l'application, l'état d'un processus distant ...

Vous pouvez avec WINDEV créer un Web service, qui sera configuré sur le serveur Web avec l'extension standard SOAP. Cela reviendra à accéder à une bibliothèque (.WDL) regroupant vos traitements, en "traversant" le serveur Web. Vous pouvez obtenir le détail de ce principe, et de sa configuration, dans l'aide de WINDEV, le schéma de principe ci-contre en est issu. Le site "Soapuser.com" montre les principes de communication qui régissent les services Web. Vous pourrez constater que cela n'est pas simple, pour finalement peu de chose : récupérer le résultat d'un traitement exécuté sur un serveur Web.

Le but de ce billet, est de présenter une alternative à la mise en place d'un Web Service, donnant le même résultat, mais évitant la configuration de l'extension SOAP du serveur Web, et le déploiement des modules WINDEV spécifiques (WD100SIIS.DLL, WD100SAPA.DLL ou WD100SAPA2.DLL). Cette alternative peut être mise en œuvre, à partir du moment ou vous disposez d'une application WEBDEV déployée. Cette application, en un minimum de programmation peut devenir un "Web service". Le principe est le suivant :

Côté site WEBDEV, le code du projet sera piloté via sa ligne de commande. Exemple :

ValeurReçueEnParamètre est une chaine
ValeurReçueEnParamètre = PageParamètre("AFAIRE")

SELON ValeurReçueEnParamètre
CAS : "XYZ"
// On a reçu la tâche XYZ à faire
// comme retourner une clé d'installation
// On appelle une procédure qui retourne le résultat
ChaineAffiche(FonctionXYZ())
// On termine le site la session est terminée
FinProgramme()

AUTRES CAS :
// Aucune action spécifique à faire
// lancement normal du site sur sa page
PageAffiche(<1ière>)
FIN

Côté WINDEV, le code n'est pas plus complexe pour interroger le "Web service" grâce à la fonction "HTTPRequete". Voici un exemple :

HTTPRequete("http://serveur/WD100AWP/WD100AWP.EXE/CONNECT/MONSITE?AFAIRE=XYZ")
Info(HTTPDonneRésultat())

La fonction "HTTPDonneRésultat" va retourner l'information renvoyée par la fonction "FonctionXYZ" du site WEBDEV, par l'intermédiaire de la fonction WLangage "ChaineAffiche". En utilisant différentes valeurs pour le paramètre "AFAIRE" il est possible d'utiliser un même site WEBDEV pour effectuer toutes sortes d'actions, en quelque sorte donc de sous-traiter des traitements. Mais appelé sans paramètre, le site WEBDEV garde sa vocation première.

Voilà comment en 5 fonctions WLangage ajouter des fonctionnalité délocalisées à une application WINDEV, en limitant les étapes de configuration. Il est toujours préférable d'utiliser ce que l'on a déjà, plutôt que d'ajouter une couche de technologie supplémentaire.

Configurations de projet

Une possibilité de WINDEV peu connue des développeurs, les "configurations de projet". Il s'agit pourtant de la possibilité de préparer à partir d'un unique projet, plusieurs exécutables avec des contenus différenciés. Les configurations de projet permettent également la création de composants (.WDK), de bibliothèques (.WDL), de Web Service ou d'assemblage .NET.

La mise en pratique des configurations de projet est capitale, dès qu'un projet va être diffusé à plusieurs sites ayant des spécificités. Si une partie du projet est commune à tous les sites, mais que certaines fenêtres et états auront des particularités, ou ne servent que sur un site donné, les configurations de projet évitent de créer les exécutables les uns à la suite des autres.
C'est à la création des configurations que le contenu de chaque exécutable est déterminé en fonction des éléments déjà présents dans le projet. Ensuite le menu "Atelier ... Génération multiple" permet en une seule opération de recréer tous les exécutables. J'ai déjà vu des développeurs crées un exécutable en cochant certains éléments du projet à inclure, puis créer un deuxième exécutable avec d'autres éléments, puis créer un troisième exécutable avec encore de nouveaux éléments pour un autre site ...

Les configurations n'étant pas limitées aux exécutables, elles permettent d'aller bien plus loin en générant par exemple :
- l'exécutable de l'application,
- un composant avec des fenêtres internes qui permettront d'intégrer des parties de l'application dans un autre projet,
- un Web service regroupant des procédures de l'application pour les exploiter via des requêtes http...

Une fois les configurations décrites avec tous leurs éléments, elles sont transparentes pour la suite du développement. Il faut simplement lors de l'ajout d'un nouvel élément (état, classe, fenêtre...) préciser la configuration dans laquelle il doit être placé.

Si un traitement ne doit être exécuté que dans le cas d'une configuration précise, il est possible d'utiliser la commande "ProjetInfo" avec le paramètre "piConfiguration". Il est dommage sur cet aspect que le "code cible conditionnel" ne propose pas les configurations, et qu'il soit nécessaire d'utiliser un traditionnel SELON ProjetInfo(iConfiguration) ...

28 septembre 2006

Filigrane / image en fond d'un état

J'ai vu de nombreux développeurs, et encore un fil de discussion récent sur le forum, batailler pour ajouter dans le fond d'un état une image. Typiquement, une mention "duplicata" en diagonale dans le fond d'un état. Le piège consiste à partir sur la fonctionnalité de "formulaire" que propose l'éditeur d'état, elle est très spécifique. Il faut utiliser la solution "Image de fond" donnée dans la description de l'état (cf image du billet). Cette solution consiste à appeler dans le code avant impression du bloc de haut de page, la commande suivante :
iImprimeImage("Image.jpg", 0, 0, iLargeurPage(), iHauteurPage())

Il n'y a rien d'autre à faire !

Astuce : pensez à optimiser la taille de cette image, car elle sera envoyée au pilote de l'imprimante. Et s'il y a bien un domaine dans lequel il faut éviter d'être trop gourmand en ressources, c'est bien celui de l'impression.

Quiz - connaissez-vous la fonction "HStatCalcule" ?

Il s'agit probablement d'une des fonctions WLangage les plus méconnue du moteur Hyper File, et pourtant elle est primordiale ! Dernier exemple en date, une requête récupère 350 enregistrements, dans une table en comportant 400 000. Les 350 enregistrements sont rapidement récupérés (fonction "ConstruitTableFichier" pour leur visualisation), pourtant la requête ne rend pas la main et la table reste bloquée avec le sablier. Renseignement pris sur l'application et son activité, il s'avère que d'importants mouvements ont été faits sur ce fichier.

Solution dans pareil cas : appeler la fonction "HStatCalcule", pour obtenir un chargement immédiat et complet des données de la requête.

Voici la description de la fonction donnée dans l'aide :

Ces statistiques sont utilisées lors de la pose d'un filtre, la création d'une requête ou encore la création d'une vue sur le fichier. Le moteur Hyper File analyse la condition de sélection et s'appuie ensuite sur ces statistiques pour déterminer les rubriques les plus discriminantes qui permettront d'optimiser les parcours des fichiers.
Les statistiques permettent d'avoir des informations sur le contenu du fichier au moment de leur calcul. Aussi, plus il y a de modifications du fichier après ce calcul et moins ces statistiques sont fidèles au contenu du fichier. Plus le fichier contient d'enregistrements et moins la modification d'un enregistrement a d'impact sur le reflet du fichier que les statistiques renvoient.

Un autre point important sur le sujet "performances", concerne la densité des index. Un fichier de stockage peut être utilisé pour de l'insertion permanente de données, mais peut avoir peu de consultations. A l'inverse, un fichier peut être consulté en permanence, tout en étant que rarement complété. Et bien en fonction de l'usage du fichier, il peut être bon d'ajuster le "taux de densité" de l'index, afin de favoriser les insertions, ou les consultations. Le taux de densité est modifiable lors de la réindexation des fichiers (WDOptimiseur, ou fonction "HRéindexe").

22 septembre 2006

Exécutables WINDEV et Framework

Un billet de remerciement pour le support technique PC SOFT, qui a publié de l'information sur la méthode de téléchargement du Framework par les exécutables. La documentation ne va pas aussi loin, et la compréhension d'un mécanisme de ce type permet une bien meilleure utilisation.

En complément, il est bon de préciser que la sélection d'un Framework commun lors de la création d'un exécutable est une possibilité, mais pas une obligation pour l'exécutable. Je reformule, si vous créez un exécutable en demandant l'utilisation d'un Framework commun, cet exécutable utilisera bien le Framework commun mais à la condition qu'il ne trouve pas un Framework dans son propre répertoire.

21 septembre 2006

Bogues et Philosophie

La philosophie a-t-elle sa place dans le développement, notamment en ce qui concerne la tolérance aux bogues ?

Et bien comme tout sujet philosophique, tout est question de point de vue.

Intervenant sur de nombreux projets dans des domaines très disparates, je suis régulièrement sollicité pour la recherche de bogues récalcitrants, vous l'aviez constaté dans certains de mes billets. Techniques et outils de débogage permettent toujours de parvenir à une solution, quelqu'en soit l'origine. Mais à quel prix ? Faut-il peu importe le coût aller jusqu'à la correction systématique, oui diront les puristes, pas si sûr diront ceux qui n'ont pas peur de philosopher(*) !

C'est en tout cas mon avis, à quoi bon perdre des heures à chercher la petite bête, cela ne fait que freiner l'avancée des projets. Je pense qu'il ne faut pas hésiter parfois à "laisser tomber" un traitement récalcitrant, en préférant le recoder, ou refaire une IHM, on y est souvent gagnant. Il en est de même pour la configuration des PC, avec la soixantaine de processus qui cohabitent, en cas de conflit il est bien plus rapide de remonter un point de restauration, même si cela n'est pas bon pour l'autosatisfaction... Les versions de Windows qui s'enchaînent vont dans ce sens, il est préférable d'avoir aujourd'hui un Windows XP, plutôt qu'un Windows 98 sans bogue, il sera préférable dans quelques années d'avoir un Windows Vista, plutôt qu'un Windows XP entièrement stabilité.

(*) ndlr : je parle ici d'une philosophie très bon marché, plus inspirée des réalités économiques, que par une réelle pensée. Je n'ai pas la prétention d'être un philosophe !

13 septembre 2006

Ma variable date change-t-elle toute seule de valeur !!!

Le W-Langage dispose d'un type "date" qui permet de manipuler très facilement les dates, chose fréquente dans un programme. Par exemple, il permet de facilement connaître la date 7 jours en arrière, sans avoir de calcul à faire pour connaître le mois, ou l'année. Exemple :

DateMoins7 est une Date = DateSys()
DateMoins7..Jour -= 7

Info
(DateMoins7)


Si les calculs sont aisés avec ce type, il faut être concentré lors de son affectation, car il peut provoquer un changement inopiné de valeur, tant que son principe n'a pas été bien assimilé. Par exemple, on tente d'affecter le 31 janvier 2006 à une variable date avec ce code :

MaDate est une Date
MaDate..Jour = 31

MaDate..Mois = 1

MaDate..Année = 2006

Info
(MaDate)


Contre toute attente, la date ne sera pas le 31/1/2006, mais le 30/1/2006. La date a changé toute seule !

Voici l'explication, qu'il faut donc garder dans un coin de tête pour bien profiter des avantages de ce type.

L'affectation de MaDate avec ..Jour = 31 ne fait pas d'affecter le jour. Il y a une affectation automatique du mois et de l'année, avec le mois en cours, et l'année en cours. Ainsi l'affectation de MaDate avec ..Jour = 31, revient à affecter la variable avec le 31/9/2006. Mais il n'y a que 30 jours en septembre, et le type date corrige automatiquement l'affectation. On a donc à ce moment là le 30/9/2006 dans la variable MaDate. L'affectation suivante ..Mois = 1 ne fait que remplacer dans la date le mois de septembre, par le mois de janvier. On a donc le 30 janvier 2006 dans la date, et non pas le 31 comme l'on pouvait s'y attendre.

J'espère que cette explication sera utile à quelques développeurs !

12 septembre 2006

Lutter contre les mystères du développement...

Au premier abord l'informatique n'est constituée que de zéros et de uns, combinés par une logique implacable. Il n'en est rien, bien heureusement pour tous les Développeurs qui trouveraient le temps bien long sans le piment apporté par bogues et effets de bords pouvant survenir dans les applications !

Et oui, ce qui est obligatoirement vrai un jour, peut finalement ne pas l'être le lendemain pour une raison qu'il sera difficile de trouver, et qui provoquera un report de planning. Quel développeur n'a pas pesté sur un code qui marchait très bien, et qui ne plus fonctionne sans avoir été modifié ...

L'arme absolue en la matière n'existe pas, mais il est possible dans des applications sensibles d'adopter une programmation défensive. Elle consiste à compléter les traitements de tests supplémentaires, vérifiant ce qui normalement n'est pas à vérifier, car n'arrive jamais. Ces tests sont les assertions.

En W-Langage, la fonction "dbgAssertion()"vous permettra de mettre en place ces tests supplémentaires. Les assertions seront actives durant l'exécution en mode test sur le poste de développement. Il sera ainsi possible de détecter une éventuelle anomalie, insoupçonnée lors de la conception. Typiquement, les tests seront placés dans tous les traitements qui vont recevoir des paramètres, afin de vérifier leur valeur.

Voici une méthode de programmation permettant d'activer les assertions dans l'application en production. Cela permet d'effectuer des tests complémentaires, une fois l'application compilée, et diffusée. Il suffit d'ajouter une ligne de code unique dans le projet, et de lancer l'exécutable avec une ligne de commande :

// Initialisation du projet, activation des assertions
// si la ligne de commande contient ASSERT
dbgActiveAssertion(Position(LigneCommande(), "ASSERT", 1, sansCasse))

La mise en place d'une programmation défensive a un coût en temps réel lors de l'écriture du code. En revanche elle permet un gain de temps significatif dans les phases de mises au point.

08 septembre 2006

Ne pas oublier les FAA !

On reste bien dans le domaine WINDEV cette fois-ci, il ne s'agit pas de "Federal Aviation Administration", mais de "Fonctionnalités Automatiques des Applications" !
En effet, les applications WINDEV peuvent être enrichies sans effort de développement de fonctionnalités automatiques :
- mémorisation de la taille et de la position des fenêtres,
- sélection des colonnes à visualiser dans les champs tables,
- activer les animations des fenêtres, le GFI,
- obtenir un graphique, un total à partir d'une colonne de table,
- retrouver l'historique des modifications apportées à un champ relié à la base Hyper File,
- mémorisation de la valeur d'un champ...


Une documentation complète destinée aux utilisateurs est éditée par PC SOFT. Je vous encourage à la consulter de temps en temps, afin de ne pas passer à côté d'une possibilité intégrée aux applications.

N'oubliez donc pas ces fonctionnalités, elles ne coûtent pas de temps de développement, et donnent un plus fonctionnel indéniable aux applications.

05 septembre 2006

Abonnement France Telecom, fin d'une époque !

Une fois n'est pas coutume, le billet de rentrée est sans rapport avec le Développement WINDEV, mais concerne le fournisseur d'accès Free ! Comme à son habitude, Free se maintient à la une de l'actualité des FAI en proposant à ses abonnés non dégroupés la possibilité de s'affranchir de l'abonnement mensuel France Telecom (lire le communiqué).

Il est bien évidence que cette nouvelle offre baptisée "Freebox only" s'intègre à une stratégie commerciale de long terme. Mais cela au prix de marges faibles voir négatives dans l'immédiat, de part les tarifs France Telecom imposés aux fournisseurs d'accès.

Le groupe Iliad a choisi de prendre en considération sa clientèle actuelle et future, plutôt que d'engranger des bénéfices à court terme en réduisant les coûts comme d'autres FAI l'on fait par le passé.

Application au développement : une petite fonctionnalité surprise, sans supplément dans une version, peut être un sacré plus pour la satisfaction des utilisateurs surtout s'il s'agit d'une FAA ;-)