22 décembre 2006

Fonctions WLangage dans le code SQL, mais également procédures stockées...

L'appel d'une fonction du WLangage dans une requête SQL est permis, mais bien évidement il est possible d'appeler une procédure stockée sur le serveur avec la même méthode.

La méthode est on ne peut plus simple :
- dans l'analyse, créer une collection de procédures, puis une fonction par le clic droit dans le volet,
- dans un traitement, appeler la fonction "HMiseAJourCollection" qui permet de copier la collection de procédures, sur le serveur.

A ce stade, il est possible d'insérer l'appel des procédures de la collection, dans les requetes SQL lancées. Exemple avec le même modèle de traitement que dans le précédent billet :

sNomFichierTXT est une chaîne = "c:\temp\commande.txt"
sListeCommande est une chaîne
sCodeSQL est une chaîne
sdReq est une Source de Données

sCodeSQL = [
SELECT ProcServeur(DateCommande) as DateCommandeformatée,
NumCommande,
TotalHT
FROM COMMANDE
]

HExécuteRequêteSQL(sdReq, sCodeSQL)

POUR TOUT sdReq
sListeCommande += [RC]+HRécupèreEnregistrement(sdReq,TAB)
FIN

fSauveTexte(sNomFichierTXT, sListeCommande)
LanceAppliAssociée(sNomFichierTXT)

La procédure "ProcServeur" aura un code WLangage qui pourra traiter la date reçue en paramètre, pour la formater différemment par exemple, ou pour la modifier en fonction de données, requêtes de la base.

Attention, dans la version en cours de WINDEV 11 je n'ai pu appeler la procédure que par la fonction "HExecuteRequeteSQL". Sauf mauvaise manipulation de ma part, l'éditeur de requêtes n'a pas encore l'air adapté à l'appel des procédures stockées.

20 décembre 2006

Fonctions Wlangage dans les requêtes Hyper File avec l'opérateur "WL." (WINDEV 11)

Le moteur Hyper File Client/Serveur propose les procédures stockées, et de ce fait permet l'appel de fonctions du Wlangage, directement dans le code SQL des requêtes !

J'ai fait quelques tests de procédures stockées, et au passage j'ai utilisé cette possibilité. Cela va simplifier bien des traitements nécessitant le formatage du résultat d'une requête, en vue d'une exportation par exemple.

Un cas typique, je dois générer un fichier texte contenant des dates / numéros / montants de commandes. La date doit être lisible, et non pas au format "AAAAMMJJ" utilisé pour le stockage et l'affectation des champs ou colonnes de type date des interfaces.

Le résultat peut être obtenu immédiatement dans la requête, ce qui évite un traitement des données lors du parcours qui suit la requête.

Voici un exemple utilisant cette possibilité (il s'agit du code de l'image de ce billet) :

sNomFichierTXT est une chaîne = "c:\temp\commande.txt"
sListeCommande est une chaîne
sCodeSQL est une chaîne
sdReq est une Source de Données

sCodeSQL = [
SELECT WL.DateVersChaine(DateCommande) as DateCommandeformatée,
NumCommande,
TotalHT
FROM COMMANDE
]

HExécuteRequêteSQL(sdReq, sCodeSQL)

POUR TOUT sdReq
sListeCommande += [RC]+HRécupèreEnregistrement(sdReq,TAB)
FIN

fSauveTexte(sNomFichierTXT, sListeCommande)
LanceAppliAssociée(sNomFichierTXT)
A noter qu'il est possible de donner un formatage spécifique à la date avec le code SQL suivant :
sCodeSQL = [
SELECT WL.DateVersChaine(DateCommande,'JJJ JJ MMM AAAA') as DateCommandeformatée,
NumCommande,
TotalHT
FROM COMMANDE
]
Le fichier généré aura les dates dans un format "Ven. 28 Jan. 2000" par exemple.

Ndlr : la requête est volontairement simpliste pour l'illustration, elle permet dans un cas réel une sélection de données. Ce qui est très intéressant, c'est le code d'exportation qui est simplifié à l'extrême, et qui dit code simple, dit code plus rapide avec un risque d'erreur de programmation moindre !

19 décembre 2006

Nouveau site WINDEV : Ed4u

Apparition d'un nouveau site de ressources WINDEV : Ed4u. Peu d'informations dans l'immédiat, le site basé sur un CMS vient d'être publié ces derniers jours c'est donc un peu tôt. Les auteurs semblent cependant très motivés, je leur souhaite de réussir dans leur projet !

15 décembre 2006

Exécuter une action lors du tri d'une colonne de table

Il est fréquent de devoir effectuer une action lorsque l'utilisateur trie les données d'une table. Une capture d'événement était requise jusqu'à la version 10, ce sujet a été fréquement abordé sur le forum. Le code nécessaire se trouve ci-dessous.

Il est cependant rendu obsolète, puisque WINDEV 11 permet d'ajouter aux colonnes un code "à chaque tri" !







//1. Code d'initialisation de la table :
Evenement("TRISPECIAL","TABLE1", 1529)

//2. Procédure TRISPECIAL
Procédure TRISPECIAL()
// _eve.wParam contient le numéro de la colonne
Trace("On a cliqué sur l'entête de la colonne n° "+_eve.wParam )
SI _eve.wParam = 2 ALORS
//On veut que la procédure TRISPECIAL permet d'obtenir un tri sur
//la colonne COL2 puis sur la colonne COL1:

// Annuler le tri automatique
_eve.retour = 0
tabletri("COL2"+TAB+"COL1")
FIN
Ndlr : ce code a pour origine un message du support.

Concaténation optionnelle avec WINDEV 11

Combien de bogues ont été générés par un caractère en trop en début ou fin de chaîne ? Ou un "\" manquant dans un chemin d'accès, ou un "/" dans une URL ?

Le cas de figure est très fréquent, on doit fournir une liste construire dans une itération, avec un séparateur bien déterminé. Le code à la forme suivante :

POUR TOUT Client AVEC CodePostal="26110"
sListeClient += Client.Nom+", "
FIN

Et il faut ensuite supprimer le ", " en trop en fin de chaîne s'il y a eu au moins un client. Ou alors faire une condition dans la boucle pour gérer le séparateur ... Bref plusieurs méthodes que l'on panache, ce qui augmente encore le risque d'erreur.

Du coup la fonctionnalité "concaténation optionnelle" avait attiré mon attention dans la brochure, je l'ai mise en ouvre et immédiatement adoptée !
Voici un exemple (j'en proposerai un plus parlant prochainement en situation) :
POUR TOUT Client AVEC CodePostal="26110"
sListeClient += [", "] + Client.Nom
FIN

Composant, partage par le GDS

Essai suivant sur la version 11 de WINDEV, l’intégration des composants dans le GDS.

Je ne pense pas qu'il soit nécessaire de rappeler l'intérêt des composants, salutaires dans les projets pour partager des fonctionnalités entre les différents modules, et surtout pour sécuriser les accès au système d'information.

De la même manière, le GDS est également devenu totalement incontournable pour gérer les modifications des projets, et leur partage entre les développeurs.

Mais la gestion des composants n’étant pas intégrée au GDS en version 10, des gymnastiques étaient souvent nécessaires pour assurer la mise à jour des composants d’un projet, et il ne fallait pas non plus oublier de les transmettre d’un développeur à l’autre, ou d’un site à un autre suivant le cas. Ayant plusieurs fois mentionné ces difficultés à PC SOFT, j’ai prioritairement regardé les possibilités du GDS en matière de gestion des composants. Nouvelle bonne surprise, puisque le GDS a inclus le nécessaire.

La création d’un composant tout d’abord permet dans son assistant de placer le composant dans l’arborescence du GDS, en plus du centre de réutiliabilité (ce dernier n’était pas facilement partageable entre sites distants comme l’est le GDS).

Ensuite l’intégration d’un composant dans le projet propose également la récupération d’un composant, depuis le GDS. La mise en place des ressources partagées va être facilitée. Par contre je ne crois pas avoir vu d’option permettant d’inclure les composants utilitaires fournis par PC SOFT dans le GDS. Il me semble que l’installation de WINDEV pourrait proposer d’ajouter ses composants dans la base GDS, la réutilisation sera encore accrue. Peut être ma première suggestion pour WINDEV 11 !

Le plus bel effet, sans compétence infographique, c'est WINDEV 11

Malgré la "suractivité" qu’entraîne la période de fin d'année, je débute la découverte de WINDEV 11 installé il y a quelques minutes sur mon portable. Je manque cruellement de temps ces jours-ci, mais je ne peux pas résister à quelques essais !

Le premier lancement est une surprise visuelle, l'interface est profondément améliorée en terme d'esthétisme : effets de transparence, animation des boutons, halos, alors que mon poste est équipé de Windows XP SP2 et non pas de Vista !

Comme je suis d'un naturel envieux, je me suis en priorité demandé s'il serait aisé de reproduire ces effets dans des modules existants.

Pour test, j'ai utilisé un programme permettant aux enfants de réviser leur vocabulaire, en répondant aux interrogations de l'agent Microsoft !

Et bien plus que jamais, le savoir faire PC SOFT est bien présent dans cette version, puisque avec mes piètres compétences graphiques, sans programmation, "Appliquer un gabarit" et quelques clics m'ont permis d'obtenir une interface "Vista" telle que la propose WINDEV 11, toujours sur mon système XP !

14 décembre 2006

IE7 et le volet "Quick tab" ou "Aperçu mosaique"

La nouvelle version du navigateur Internet Explorer propose une fonctionnalité bien intéressante, avec l'ouverture des sites dans des volets. Cette possibilité n'a rien de révolutionnaire, Firefox la propose depuis longtemps, et la navigation par des volets dans une application est chose commune. Par contre, dès qu'au moins deux volets sont ouverts, un volet "Quick tab", ou "Aperçu mosaïque" est ajouté. Là c'est une révolution dans la présentation des données pour l'utilisateur, en un coup d'œil il repère le volet sur lequel il souhaite retourner. Et à tout moment le raccourci Ctrl+Q permet de revenir à la mosaïque.

Au quotidien, cette méthode de présentation peut faire gagner un temps précieux en Alt+tab, "non c'est pas celui là", Alt+tab, "non c'est pas celui là" ...

Pour les applications, cette possibilité sera peut être proposée par WINDEV pour les champs onglets ou boite à outils ! C'est en tout cas une suggestion que je vais m'empresser de faire à PC SOFT !

La copie d'écran ci-dessus montre IE7 en position de recherche d'informations WINDEV. Mais j'en ai également un ouvert avec des volets remplis de cadeaux, Noël oblige !

Un bémol tout de même dans la fonctionnalité, elle est gourmande en mémoire. 100 Mo de RAM sont rapidement nécessaires pour ouvrir plusieurs volets.

05 décembre 2006

Fonctionnalités d'exportation (RTF, XLS, RTF ...) depuis l'aperçu pour les impressions programmées

L'aperçu des états imprimés créés avec l'éditeur d'états propose par défaut des sorties dans différents formats : RTF pour Word, XLS pour EXCEL, PDF, XML, ou envoi par email.

Cette même possibilité n'est pas disponible pour les impressions programmées par les fonctions "iImprime", "iImprimeMot", "iImprimeZone", "iImprimeImage"... alors qu'elle est bien utile !

Il existe un moyen de combiner ces deux "méthodes" d'impression pour avoir une impression programmée, imprimée au travers d'un état. Ainsi l'impression programmée bénéficie des possibilités d'exportation dans l'aperçu.

Le moyen pour y parvenir est très facile à mettre en œuvre, il suffit de :
- créer un état ne parcourant aucune donnée, sans aucune champ,
- placer le code de l'impression programmée dans traitement de fermeture de l'état.
Le lancement de cet état "spécial" avec la commande "iImprimeEtat" permettra d'avoir un aperçu contenant une impression programmée, et les possibilités d'exportation.

04 décembre 2006

Pacte écologique / Etre un bon citoyen sans faire de politque...

Je ne profite d'aucune ressource de façon abusive (chômage, RMI, allocations...). Tous mes revenus sont déclarés, et j'estime mérités, car je ne profite pas de l'argent d'autres contribuables.

C'est ma façon d'être un "bon citoyen".

Je ne fais pas de politique : gauche ou droite au pouvoir ne change rien à mon quotidien. L'un comme l'autre au travers de leurs représentants n'ont qu'un objectif, la présidence en 2007, le reste n'a que peu d'importance. Même armé de très bonnes intentions le meilleur des candidats ne pourra pas mettre les fainéants au travail, soigner les malades imaginaires ou mettre au pas ceux qui n'ont aucune règle.

Cela ne m'empêche pas d'être optimiste pour l'avenir, car je ne suis pas le seul à rester animé des saines valeurs héritées du travail des générations précédentes. Aussi, j'ai signé le "Pacte écologique", qui j'en suis sûr rencontrera un vif succès, et permettra de montrer que finalement, tout le monde ne se fout pas de tout.

Vous pouvez signer le "Pacte écologique", et peut être plus encore, ajouter quelques gestes quotidiens supplémentaires en faveur de l'environnement. Par exemple si vous faites plus de 20 minutes de bouchon le matin, demandez-vous si le vélo n'est pas plus rapide au final (tout en permettant au passage de profiter pleinement des friandises de noël sans crainte pour votre ligne).

28 novembre 2006

Inhiber une action standard sur un événement (clavier, souris...)

Windows apporte pour tous les champs des comportements standard pour lesquels aucune programation n'est requise, et c'est tant mieux par ce que je ne programmerai pas tout ça tous les jours !

Mais comme il est toujours bon d'en vouloir plus, on peut dans certain cas ne pas vouloir du comportement standard sur une action bien précise.

Par exemple, on pourrait décider qu'un champ ascenseur ne doit pas réagir à la roulette de la souris. Il suffit pour y parvenir d'ajouter le traitement optionnel "roulette souris", puis de faire renvoyer la valeur "0" à l'événement Windows correspondant (cf. montage écran).

En effet, le traitement optionnel est appelé lorsque Windows fait l'envoi de l'événement au champ, et avant même que Windows n'ait effectué son action standard. De ce fait on peut très bien exécuter un code avant l'action standard de Windows, et aller jusqu'à l'inhiber comme dans ces exemples.

Cela est également valable avec la fonction "Evénement" du WLangage qui fonctionne suivant le même principe.

27 novembre 2006

Imprimer directement depuis un aperçu...

La fenêtre d'aperçu propose lors de l'impression de choisir le nombre de pages à imprimer, ainsi que le nombre de copies. D'un point de vue ergonomique, cela peut ne pas convenir à certains usages, voici la méthode pour ne pas avoir de confirmation et imprimer directement :

Aperçu personnalisé :
Il faut tout d'abord copier dans le répertoire du projet la fenêtre de l'aperçu, c'est une fenêtre WINDEV dans le répertoire des exemples. Ouvrir ensuite cette fenêtre dans le projet, afin de l'enregistrer dans les éléments du projet. Par le menu "Projet / Description du projet" et le volet "Style", il faut donner cette fenêtre comme fenêtre d'aperçu. A ce stade, il est possible de personnaliser la fenêtre utilisée lors de l'aperçu depuis l'application.

Modification de l'aperçu :
Ouvrir la description du bouton "Imprimer", et simplement changer son nom en "ImprimerTout". Au prochaine aperçu, ce bouton lancera directement l'impression !

23 novembre 2006

Big Brother dans les applications ...

Dans un site en exploitation avec des données en perpétuelle mouvements, il n'est pas rare de rencontrer deux utilisateurs se disputant la propriété ... d'une erreur de manipulation.

- C'est toi il y a une semaine qui m'a dit de rentrer la nouvelle adresse.
- Oui mais ensuite je l'ai changée à nouveau, tu n'aurais pas du l'écraser !
- Non je ne l'ai pas changée à nouveau, c'est toi qui a oublié de la changer ...

Au final le conflit est stoppé en se tournant vers l'informaticien en charge du programme :
- [en coeur] : on vient te voir car l'application a encore perdu une adresse.

Ca sent le vécu pour beaucoup j'en suis certain. Un remède très efficace existe, c'est la journalisation. Cerise sur le gâteau, son activation se fait par une case à cocher dans la description des fichiers de l'analyse, aucune programmation n'est requise. La journalisation des écritures est suffisante pour régler tout litige tel que décrit ci-dessus.

Lorsque la journalisation est active, le menu contextuel des champs reliés aux rubriques de fichiers dispose d'une option "Historique..." qui permet de connaître toutes les valeurs successivement prises par la rubrique avec :
- la date de l'heure de modification,
- la valeur,
- le poste depuis lequel le changement a été fait,
- le login de l'utilisateur qui a fait le changement.

Toutes ces informations peuvent également être proposées par une interface spécifique de l'application, avec la fonction "HHistoriqueModification" qui retourne, entre autre, toutes ces informations sur les modifications.

Plus de doute sur qui a fait quoi !

Autre intérêt, la journalisation permet après une restauration de données de rajouter à la sauvegarde les dernières modifications.

Deux recommandations pour l'utilisation de la journalisation :
- utiliser dans le programme la fonction "HPoste" pour renseigner le journal précisément sur l'auteur des changements,
- placer les journaux sur un autre disque que celui contenant les données, avec la fonction "HChangeRepJNL".

22 novembre 2006

Mémorisation de la position des colonnes de table inopérante ?

Option à ne pas oublier dans la description des tables : mémoriser la position des colonnes. Elle permet sans ajouter de code, de proposer à l'utilisateur final de toujours retrouver les colonnes comme il les a lui-même positionnées.

Seulement il peut arriver que cette mémorisation soit inefficace sur une table donnée, sans raison apparente. Il y a bien sûr une explication : la propriété "..MenuContextuel". En effet, l'affectation de la propriété "..MenuContextuel" d'une table, inhibe la restauration de ses paramètres mémorisés. Ceci dans le but de ne pas avoir de colonne invisible, qui ne pourrait pas être restaurée. Mais encore faut-il le savoir, je n'ai pas trouvé l'information dans la documentation. Je l'ai obtenue du support après avoir cherché un long moment pourquoi dans une même fenêtre une première table avait ses colonnes bien remises en place, mais pas une seconde.

Peut-être qu'une prochaine version de WINDEV pourra afficher des informations aux développeurs pour les informer lors de l'utilisation d'une propriété de ce type des effets engendrés sur d'autres fonctions.

17 novembre 2006

Fichier en cours d'utilisation ... mais par qui ?

Un fichier de données reste parfois ouvert, alors que l'on est persuadé qu'il n'est plus utilisé, et que tous les programmes l'utilisant sont arrêtés...

Fichier en cours d'utilisation sur un autre poste ...
Le fichier est utilisé par un autre processus ...

Un utilitaire pouvant se substituer au gestionnaire de tâches est très commode, car il permet de connaître les processus qui utilisent un fichier. Il s'agit de Process Explorer, à toujours garder dans ses outils de travail. Anecdote, l'éditeur d'origine est Sysinternal, mais il semble qu'il y ait eu récemment une absorption de Microsoft. En effet, l'adresse http://www.sysinternals.com est directement redirigée sur un site Microsoft !

Bref, le menu "Find / Find handle or DLL" permet de donner le chemin d'accès au fichier de données en cours d'utilisation ... qui ne devrait pas l'être. La recherche vous donne ensuite la liste de tous les processus utilisant ce fichier.

Au passage, deux "pièges" pouvant aboutit à laisser un fichier de données ouvert ...
- fichier Hyper File, appeler la fonction "HFerme", mais oublier les "HAnnuleDéclaration" sur les requêtes exécutées sur ce même fichier,
- fichier externe : appeler "fCrée" et "fOuvre", et ne faire qu'un seul "fFerme". Pour éviter tout risque d'erreur, préférer "fOuvre" seule, mais avec le paramètre "foCréation".

Une image (celle du site Microsoft) de l'utilitaire complet, tel qu'il apparaît si vous le substituez au gestionnaire de tâches :

15 novembre 2006

Importer un fichier texte dans un fichier Hyper File en formatant des dates

L'importation d'un fichier texte dans un fichier Hyper File est facilitée par la commande "HImporteTexte". Dans le cas favorable, l'importation est donc extrêmement simple grâce à cette fonction. Bien évidemment, suivant l'origine des données à importer, on se trouve en dehors du "cas favorable", il suffit par exemple qu'une date n'ait pas le format "AAAAMMJJ" attendu.

Dans ce cas, il faut avoir recours à une bonne vieille moulinette, facilitée par l'instruction POUR TOUT.

L'exemple ci-dessous utilise une demande du forum, ce sujet revenant assez régulièrement d'ou l'idée de ce billet. Il faut souligner qu'il s'applique aux dates, mais également à tout ce qui peut nécessiter une conversion avant la mise en base.

Soit un fichier texte à importer avec le contenu suivant (une tabulation sépare les colonnes, un retour chariot sépare les lignes ) :

15/03/2002 abc imo 560,33
19/04/2003 klo hap 561,00
12/06/2001 dol pme 7840,00

Si la date dans le fichier texte avait été codée sous la forme "20020315" la fonction "HImporteTexte" aurait fait l'affaire. Mais avec ce codage de date, il faut mouliner (une fois de plus ?). Voici un exemple de code pouvant être utilisé :
sEnregistrementsAImporter est une chaîne
sNouvelEnreg est une chaîne
sDateNonformatée est une chaîne

sEnregistrementsAImporter = fChargeTexte("C:\MonFichier.txt")

POUR TOUTE CHAINE sNouvelEnreg DE sEnregistrementsAImporter SEPAREE PAR RC

sDateNonformatée = ExtraitChaîne(sNouvelEnreg, 1, TAB)
Fichier.Date = ChaîneVersDate(sDateNonformatée, "JJ/MM/AAAA")
Fichier.Personne = ExtraitChaîne(sNouvelEnreg, 2, TAB)
Fichier.Libellé = ExtraitChaîne(sNouvelEnreg, 3, TAB)
Fichier.Montant = ExtraitChaîne(sNouvelEnreg, 4, TAB)

HAjoute(Fichier)
FIN

Une bonne évolution de la fonction "HImporteTexte", serait de pouvoir donner dans les délimiteurs un format de date comme le prend la fonction "ChaîneVersDate". Le champ d'action de "HImporteTexte" serait grandement étendu. J'en ai fait la suggestion au support.

14 novembre 2006

Une option de menu contextuel en gras

Une astuce permet de passer une unique option d'un menu contextuel, ayant le look XP, en gras.

Il suffit d'intervenir sur le libellé, et de l'encadrer avec les balises HTML de mise en gras, l'image ci-contre met en évidence ce procédé.

Cela permet par exemple de mettre en évidence l'option la plus couramment utilisée, un "petit plus" dans une interface !

10 novembre 2006

Bêta Blogger avant WINDEV 11, pour une leçon d'ergonomie !

En attendant de pouvoir m'initier aux nouveautés de WINDEV 11, je découvre la bêta version des Blogs façon Google. Un sacré chamboulement puisqu'en terme de fonctionnalités, visibles tout autour de ce billet, il est maintenant possible :
- d'ajouter des flux RSS,
- de regrouper les billets par sujets,
- d'avoir une arborescence des archives ...

Mais surtout, et là chapeau, surtout il est possible d'obtenir tout cela sans aucune programmation Web, dans un environnement totalement dynamique. Un simple glisser/déplacer d'un élémement dans la page permet de disposer les différentes zones du blog. Un modèle d'ergonomie.

J'encourage tous ceux qui le peuvent à prendre quelques minutes pour créer un blog de test, juste pour découvrir la simplicité avec laquelle toutes les possibilités du blog sont proposées. Les développeurs se sont réellement creusés pour parvenir à un tel résultat, c'est un très bel exemple de respect de l'utlisateur.

Stockage des images, optimisation de l'espace en changeant le format...

Une rubrique mémo image est généralement affectée par une commande de la forme Fichier.RubriqueImage = ChampImage, ou "EcranVersFichier".

Cette affectation copie fidèlement l'image contenue dans le champ, au format BMP.

En fonction du contenu de l'image, un enregistrement en JPEG est souvent suffisant en qualité, et permet de diviser la taille de l'image par un facture important. Il suffit pour cela d'affecter la rubrique avec un appel de la fonction "dSauveimageJPEG" :

Fichier.RubriqueImage = dSauveImageJPEG(ChampImage, enMémoire)


Petite astuce bien utile s'il faut gagner un peu de place, surtout si l'application doit à un moment donné transférer ces images.

09 novembre 2006

Présentation par défaut de l'interface d'une application déployée

L'utilisateur final d'une application peut configurer la présentation de son application :
- position et taille des fenêtres,
- largeur des colonnes des tables,
- mémorisation de valeurs pour les champs...

Comme il est courant pour tout le monde de changer d'avis, il est souhaitable de lui proposer une option de l'application permettant de revenir à l'état initial pour toutes les informations mémorisées. Il peut s'agit d'un menu "Paramètres / Rétablir l'affichage par défaut". Cette option devra simplement faire la suppression dans la base de registres de la clé retournée par la fonction "ProjetInfo(piRegistre)".

Pour aller plus loin sur ce mécanisme, il est également possible de remplacer la sauvegarde faite dans la base de registres, par une sauvegarde dans un fichier XML. Cette possibilité est donnée par la fonction "InitParamètre". L'avantage est alors de pouvoir facilement "transporter" les paramètres sauvegardés d'un poste à un autre. Il est même envisageable de conserver le fichier XML dans un fichier de la base de données, afin de le restituer automatiquement au lancement de l'application en fonction de l'utilisateur qui se connecte !

08 novembre 2006

Loupe de recherche des colonnes des tables

Voici une "checklist" à appliquer lorsque la loupe d'une colonne de table fichier n'apparaît pas lors de l'exécution.

- la coche "Avec recherche (loupe)" doit être active dans la description de la colonne, tout comme la coche "Triable" (volet "Général"),

- la rubrique du fichier associé à la colonne (volet "Liaison") doit être une clé dans le fichier (unique ou doublon peut importe),

- le remplissage de la table doit se faire sans programmation. Il s'agit du sélecteur "Parcours automatique" dans la description de la table (volet "Contenu"),

- l'option "Ascenseur proportionnel" doit également être cochée toujours dans la description de la table (volet "Détail").

Toutes ces conditions doivent être réunies dans le cas d'une table directement reliée à un fichier. Si la table est reliée à une requête, la nécessité de clé dans le fichier de données disparaît.

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.