mercredi 29 décembre 2010

Pagination alternée avec Microsoft Word 2007

Comment faire pour avoir un super document super top classe avec des numérotations différentes en fonction, par exemple, que l'on soit dans la table des matières et dans le reste du document avec Word 2007 ? Le principe qui permet cela se base sur les sections. La stratégie consiste à définir des sections différentes en fonction de la numérotation à utiliser. C'est bien beau de parler de sections et compagnie mais comment le faire en pratique ?

Le contexte :

Le document sur lequel nous travaillerons se compose de cette manière :
  • 1 page de garde
  • 1 page blanche
  • La table des matières
  • 1 page blanche
  • Le contenu du document 
Nous aimerions avoir une numérotation en chiffres romains sur la table des matières et une numérotation en chiffres arabes dans le document. Evidemment, la page de garde et les pages blanches ne doivent pas être numérotée et la première page du contenu du document doit commencer la numérotation (commencer à 1)

La solution :
Afin de différencier les zones de numérotations, il est nécessaire de définir des sections. Dans notre cas, il est nécessaire d'avoir 4 sections. Nous allons en mettre 5 afin d'avoir une section propre à la page de garde :
  1. Page de garde : pas de numérotation
  2. Première page blanche : pas de numérotation
  3. Table des matières : numérotation en chiffre romain
  4. Page blanche : pas de numérotation
  5. Contenu : numérotation en chiffres arabes.
La mise en place de sections se fait via l'onglet "Page Layout" en cliquant sur le bouton "breaks"(sauts en français). L'image ci dessous indique la positions du boutons "Breaks"(cliquer sur l'image pour agrandir)


 Les pages étant déja définies, nous plaçons des sauts de sections de type "Next Page" car la numérotation travaille par page. On place donc nos 5 sauts de sections aux endroits adéquats. Maintenant, nous pouvons définir nos différentes numérotations.

En double cliquant sur le dessus d'une page (ou en dessous), le mode footer/header de Word s'affiche. Ce mode permet d'éditer les entêtes et les pieds de pages. Pour quitter ce mode il suffit de double cliquer sur le milieu d'une page.

Si vos sauts de sections sont bien définis, vous devriez voir les 5 sections et la dernière sections (le contenu du document) sera marquée comme étant la 5ieme. Sur la capture ci-dessous, il est noté au niveau de l'entête : "Header - Section 5" ce qui indique bien que le contenu du document se trouve dans la 5ieme section.

Il vous suffit, alors, de vous déplacer de sections en sections pour rajouter la numérotation de page via le bouton "Page Number" de l'onglet "Header & Footer Tools" :
Les options proposées permettent de rajouter la numérotation a différents endroits de la page. Il permet également de définir le format de la numérotation (Format Page Numbers) et de supprimer la numérotation (Remove Page Number).

La numérotation recommence à 1 dans chacune des sections. Si il est nécessaire de ne pas réinitialiser le compteur de pages, il vous suffit de le spécifier dans les options du format de la numérotation  (Format Page Numbers)

Par défaut, la numérotation utilise les chiffres usuels (chiffres arabes). Pour changer le type de numérotation, il est également nécessaire de passer par les options du format de la numérotation  (Format Page Numbers)



Et hop un document top classe avec une numérotation correcte !

Les sections ne servent pas uniquement à définir une numérotation différentes. Elles permettent de définir des zones ou la mise en page est différente, par exemple, lorsque l'on souhaite avoir une page dans son document qui est horizontale(landscape) au lieu de verticale. Les autres versions de Word se basent sur le même principe même si les accès à ces options sont différents. Pour plus d'informations, chercher le mot clé "section" dans l'aide de Microsoft Word.

mercredi 22 décembre 2010

Assurer l'unicité d'un process

Certaines applications nécessitent qu'une seule instance à la fois soit exécutée sur une machine. Il existe sans doute d'autres stratégies pour réaliser cette unicité, mais une méthode assez simple consiste à utiliser un Mutex (Mutual Exclusion).

La classe Mutex du .NET framework se trouve dans le namespace System.Threading. Ce namespace contient d'autres composants tel que des sémaphores ou des moniteurs.

La technique consiste tenter de créer un mutex et d'essayer d'avoir le mutex. Si on arrive pas à l'avoir c'est qu'il est pris par un autre processus. Le mutex étant nommé, c'est qu'une autre instance de l'application est en train de s’exécuter.

La première exécution va créer le mutex et l'acquérir. Lorsque l'application se termine, elle relâche le mutex. Si on démarre simultanément plusieurs applications, la première obtiendra le mutex, les autres seront bloqués pendant 1000 ms lors de l'appel à la fonction WaitOne qui retournera faux car la première instance aura le mutex. Une fois l'application terminée, le mutex est relâché et une autre instance de l'application peut récupérer le mutex et s'exécuter.

Initialisation statique en C# (constructeur statique)

Une variable statique peut-être initialisée de la même manière qu'une variable de classe directement lors de sa déclaration. L'instanciation de la variable se fera alors automatiquement :


Cependant, il est parfois nécessaire de réaliser une instantiation plus complexe qui n'est pas possible en une seule commande. Il existe en C# l'équivalent du bloc static Java : Le constructeur statique.

La constructeur statique se déclare comme un constructeur sauf qu'il a le mot clé static qui le précède. Dedans, vous pouvez y instancier ou modifier tout ce qui est statique.

Ci dessous, un exemple de programme appelant ces 2 variables statiques avec le résultat de l'exécution du programme pour montrer que ca marche !



mardi 31 août 2010

Scripts SQL contenant un caractère & (amper and)

Afin de disposer de variables dans les scripts SQL, SQL*PLUS(Client en ligne de commande permettant de se connecter à une base de donnée Oracle) permet de définir des variables préfixées du caractère '&'. Lorsque l'utilisateur exécute la requete, sql*plus lui demande la valeur à utiliser afin de remplacer cette variable. Ceci permet d'avoir une partie dynamique dans une requête et ainsi d'éviter de devoir retaper plusieurs fois des requetes qui diffèrent d'un filtre ou d'un paramètre.

Mais où est le problème alors ? Le problème va venir le jour où un script contiendra un & dans une chaîne de caractères. Votre SQL*Plus va vous demander par quelle valeur faut-il remplacer la variable et le fait de ne rien mettre va juste vous effacer ce qu'il y a après le caractère &. Ce problème apparait également avec TOAD pour Oracle.

La commande "SET DEFINE OFF;" permet de désactiver ces demandes de remplacements de variables lors de l'exécution de script. Cette commande marche aussi bien avec TOAD et SQL*Plus. Il est à noter qu'avec TOAD, il est également possible de faire un clic droit dans l'éditeur et déselectionner l'option proposant de demander les valeurs des variables (marche uniquement pour l'exécution d'une requete)

Voila, un petit post utile en cas de soucis avec le caractère & !



Références

lundi 21 juin 2010

Agrégation de strings

Comment avoir dans son result set un groupement de string qui serait agrégé et séparé par des virgules? Nous allons prendre comme cas d'utilisation la table des pays du schéma HR fournit par Oracle (HR.COUNTRIES). Nous voulons avoir pour chaque lettre de l'alphabet la liste des pays séparé par des virgules correspondant à cette lettre.

Il existe diverses solutions en Oracle pour arriver à cette fin. La plus récente (Oracle 11.2g) consiste à utiliser la fonction LISTAGG et de réaliser un group by. La requete suivante donne le résultat attendu :
La clause WITHIN GROUP(...) permet de réaliser un tri au sein de l'agrégation et ainsi avoir les pays triés par ligne du result set.

Pour les malchanceux(comme moi) qui n'ont pas la chance d'utiliser Oracle 11.2g, quelles sont les solutions à notre disposition pour réaliser la tâche demandée ? Après quelques recherches sur le Web, j'ai pu trouver la fonction wm_concat du package wmsys. La requete utilisant cette fonction est la suivante :
Cependant, cette solution n'est pas géniale. Premièrement, le result set n'est pas trié par ligne et la clause WITHIN GROUP n'est pas applicable sur cette fonction. La solution serait alors d'utiliser un PARTITION BY dans le select et d'ensuite filtrer pour n'avoir que les résultats qui contiennent l'ensemble des pays :

Le second problème lié à cette solution vient de sa non-documentation. En effet, cette fonction est undocumented et vous ne pourrez donc pas bénéficier du support d'Oracle en cas de problème avec cette fonction. De plus, la version exacte de la solution est assez lourde.

Quelles sont les solutions si on utilise une version d'Oracle un peu moins récente et qu'on ne veut pas utiliser une fonction non documentée ? Il existe sans doute plusieurs solutions à ce problème, les unes les plus originales et farfelues que les autres. Celle que j'ai dernièrement utilisée est la suivante :
 Cette solution utilise tout d'abord la fonction d'agrégation RANK pour mettre un ranking sur les noms de pays portant la même première lettre. Ensuite, nous utilisons les clauses connect by et la fonction sys_connect_by_path pour agréger les pays qui porte la même première lettre et de réaliser le tri a au sein de chaque résultat.

Enfin, il est bien évidemment possible de réaliser sa propre fonction qui permet de réaliser cette agrégation de strings. Plusieurs sites présentent leurs implémentations(voir sources)

Sources :

mardi 15 juin 2010

Enum Java-like en C#

Si vous avez l'habitude de programmer en Java et que vous passez dans le monde de Microsoft avec le C#, vous vous êtes peut-être déja demandé pourquoi les Enums C# sont aussi primitif que les enums en C. En effet, contrairement à Java(à partir de la version 5), il n'est pas possible d'ajouter des propriétés sur les Enums C#. Serait-ce une fonctionnalité propre et uniquement valable pour les développeurs Java ?

En effectuant plusieurs recherches sur internet, j'ai trouvé une solution qui permet de simuler le fonctionnement des enum java sur le .NET framework en C#.

La solution que je vais vous présenter consiste à utiliser les attributs sur les valeurs de l'énumération et d'utiliser la reflection pour récupérer les valeurs des attributs.

L'exemple le plus fréquent en Java est l'énumération des planètes du système solaire sur lesquelles il est possible de récupérer des informations complémentaires tel que le diamètre ou le poids de la planète, par exemple.

Alors en pratique comment faire ?

Premièrement, il est nécessaire de définir les attributs à utiliser, par exemple l'attribut MassAttribute:
L'attribut hérite de la classe Attribute, on lui définit un constructeur prenant un paramètre de type double et une propriété Mass avec un getteur qui retourne la valeur de la masse. Une fois définie, il est possible d'ajouter les attributs sur les valeurs de l'enum :
Maintenant que notre énumération de planètes est décorée de ses attributs, il est possible de récupérer les valeurs stockées dans ces attributs via la réflection. La méthode GetCustomAttributes de la classe FieldInfo permet de récupérer les attributs de la classe. Cette méthode prend en paramètre le type de l'attribut ainsi qu'un booléen qui détermine si il faut aller chercher les attributs dans les classes héritées ou non(Il existe également une signature de cette méthode qui ne prend pas le type de l'attribut mais cette dernière retourne, évidemment, tous les attributs liés au Type). Si vous avez défini que votre attribut Mass est unique pour chaque élement de l'énum, il suffit de récupérer l'élement d'index 0 de la liste des attributs retourné par la fonction. Ce qui donne :
Enfin, pour avoir le meme comportement que les enums Java, il est nécessaire de pouvoir récuperer la valeur de l'attribut en appelant une méthode directement sur l'objet de l'énumération. Pour ce faire nous allons définir une classe static avec des méthode pour étendre l'énum. Nous allons donc utiliser le fait que le C# permet d'étendre des classes en leur rajoutant de nouvelles méthodes avec les Extension methods(http://msdn.microsoft.com/en-us/library/bb383977.aspx) :
Ainsi, il est donc possible de faire appel à la méthode GetMass sur une valeur de l'énumération Planets que nous avons précédemment créé et d'avoir un fonctionnement similaire aux enums Java meme si la mise en oeuvre de ce système est beaucoup plus lourde que ce qui est mis à disposition des développeurs Java.
Une fois de plus, le langage C# de Microsoft se montre sans limite...

mercredi 9 juin 2010

Des couleurs dans la console

Le  blanc sur fond noir c'est parfois un peu lassant. Il est possible avec la console du framework .NET de mettre un peu de gaieté dans sa console. Les couleurs disponibles se trouvent dans l'énumeration System.ConsoleColor qui contient les couleurs suivante:

évidemment le noir(Black) sur fond noir ne se voit pas très bien. Il est également possible de changer la couleur de fond de votre console ce qui donne selon les couleurs :
Cette fois-ci, vous noterez que c'est le gris(Gray) sur fond gris qui ne passe pas très bien.

Bon passons à la pratique. Comment afficher du texte coloré ou avoir un fond coloré sur son texte ? Voici un petit bout de code manipulant les couleurs de la console :
 Ce code modifie la couleur du texte écrit dans la console (Console.ForegroundColor) ainsi que la couleur de fond du texte écrit (Console.BackgroundColor). Après avoir joué avec les couleurs, il est possible de revenir aux couleurs par défaut en effectuant un appel à la méthode ResetColor. Voici l'exemple généré par ce code : 
Afin d'avoir le fond coloré sur toute la ligne, il est nécessaire de réaliser un padding sur votre chaîne de caractères à afficher. Heureusement pour nous, la classe string dispose d'une méthode RightPadding permettant de completer la ligne... La propriété statique WindowWidth de la classe Console permet d'obtenir la largeur actuelle de la console en nombre de caractères. Ainsi, meme si votre utilisateur a défini une taille différente, il est possible de connaitre le nombre de  caractères que vous pouvez écrire sur une ligne de la console avant de devoir faire un retour à la ligne.

Voila, maintenant vous n'avez plus d'excuses pour avoir des jolies consoles pleines de couleur. Je pense qu'avoir du texte rouge en cas de problème et du vert lorsque tout est ok permet de faire ressortir des messages importants dans une application console. Donc n'hésitez surtout pas à en faire (bon) usage. 

Ca y est je me lance

Depuis quelques temps je me dis que ca serait bien si je notais tous les trucs cools que je faisais lorsque je suis au boulot. Il m'arrive fréquemment de me dire :"J'ai déja fait ca... mmmh comment on le faisait déjà ?"

Donc voila, mes notes de geeks je vais les noter sur ce blog afin que d'autres puissent éventuellement s'en servir et le jour ou je devrai faire quelque chose que j'ai déja fait... Allez hop sur mes notes de g33k.

Ce blog me permettra de récupérer tous mes trucs et astuces, mes diverses notes et autres petites choses que je rencontre dans mes tâches journalières en informatique. Travaillant actuellement en ASP.NET/C# 3.5 et sur Oracle 10g mes notes seront principalement sur ces 2 technologies.

Réunir toutes ces notes sur ce blog me permettra ainsi de centraliser mes informations et cela me forcera également à les noter de manière propre et réutilisable.