samedi 31 décembre 2011

Livres lus en 2011


L'enfant Allemand de Camilla Lackberg du 13 décembre au 30 décembre 2011
L'oiseau de mauvaise augure de Camilla Lackberg du 08 novembre au 12 décembre 2011
Harry Potter à l'école des sorciers (volume 1) de JK Rowling du 04 octobre au 07 novembre 2011
Les cathédrales du vide de Henri Loevenbruck du 10 septembre au 03 octobre 2011
Cessez d'être gentil, soyez vrai (communication non violente) 1è partie de Thomas d'Ansembourg du 21 Août au 09 septembre 2011
Le Burn Out - Comprendre et vaincre l'épuisement professionnel de Suzanne Peters et Dr Patrick Mesters du 17 Août au 20 Août 2011
Le pourquoi du comment de Daniel Lacotte du 11 Août au 16 Août 2011
Le tailleur de Pierre de Camilla Läckberg du 13 juillet au 10 Août 2011
Seras-tu là de Guillaume Musso du 03 juillet au 12 juillet 2011
Fragments d'une femme perdue de Patrick Poivre d'Arvor du 21 juin au 02 juillet 2011
Freedom de Daniel Suarez du 13 juin au 20 juin 2011
Le musée perdu de Steve Berry du 05 juin au 13 juin 2011
Napoléon - vol 4 - L'immortel de Sainte-Hélène de Max Gallo du 03 mai au 04 juin 2011
Napoléon - vol 3 - L'empereur des Rois de Max Gallo du 16 mars au 02 mai 2011
Daemon de Daniel Suarez du 01 mars au 15 mars 2011
Le concours de Millénaire vol 1-2 & 3 de Roger Zelasny du 20 décembre au 28 février 2011

mercredi 21 décembre 2011

Imprimer avec Python

Cela fait un moment que je travaille avec PowerShell.
Si c'est un environnement de scripting efficace, je suis quand même tombé sur un OS.
Pas facile de générer et d'imprimer des documents complexes (Texte et graphique, code barre, etc) à partir de PowerShell.

Dans ma déveine, je me demandais si Python pouvait faire mieux pour voir ?
J'ai trouvé deux références prometteuses:
Qui sait, peut-être que je devrais un jour laisser tomber PowerShell pour utiliser Python?
Mais sur une machine Windows, ce n'est pas certain que c'est gagné d'avance (j'utilise énormément d'automation Excel et Word) :-/

Programme par défaut sous Windows 7 - quand il est impossible de le changer

Changer une association de fichier
Sous Win7 Pour changer le programme par défaut associé à une extension de fichier, il existe le programme "Programme par défaut" fournit disponible dans le menu démarré.
En choisissant l'option "", il est possible d'associer un programme particulier à un extension de fichier (ou un protocole).
Programme a démarrer

Option à choisir

Comment changer de programme


Quand il n'est pas possible de changer l'association
Cependant, il existe des cas où cette option ne fonctionne pas.
En effet, l'option "Toujours utiliser le programme sélectionner pour ouvrir ce type de fichier" reste désespérément grisé/incessible !

Dans ce cas, voici une méthode beaucoup plus directe trouvé dans une conversation sur Clubic (ici).
Au moins celle là fonctionne parfaitement. Merci Clubic :-)

Ouvre l'Editeur du registre (clic-droit + Exécuter en tant qu'administrateur dans Vista ou 7):

C:Windows\regedit.exe

Sous la ruche HKEY_CLASSES_ROOT sont toutes les extensions de fichiers enregistrées. Je te donnerai un exemple pour changer le programme d'ouverture et l'icône par défaut pour les fichiers audio .mp3.

Double-clique sur la clé HKEY_CLASSES_ROOT\.mp3, et cherche une valeur sans nom (Par défaut) disant le type de fichier associé à l'extension .mp3 Par exemple: (par défaut) REG_SZ mp3file

Ceci te dit que l'extension .mp3 est associée à mp3file. Maintenant double-clique sur la clé HKEY_CLASSES_ROOT\mp3file

Dans la sous-clé DefaultIcon il y a une valeur REG_SZ avec le répertoire du fichier contenant l'icône utilisée par ce type de fichier.

Tu peux double-cliquer sur cette valeur et changer ses données. Par exemple "C:\Program files\Winamp\winamp.exe", 3

Pour changer le programme qui ouvre ce type de fichier par défaut, double-clique sur la clé HKEY_CLASSES_ROOT\mp3file\shell\open\command puis sur la valeur REG_SZ dedans et change les données pour le répertoire du programme désiré suivi de "%1". Par exemple "C:\Program files\Winamp\winamp.exe" "%1"

lundi 19 décembre 2011

Excel 2010 - Formatage conditionel sur une colonne

Le formatage conditionnel c'est bien mais par défaut il ne s'applique qu'a une seule cellule !
Lorsque l'on veut généraliser le formatage sur une colonne entière, les choses deviennent vite frustrantes.
C'est que rien dans l'interface ne vient vous aider pour trouver la bonne réponse.

C'est entre autre ce qui m'est arrivé lorsque je voulais mettre en lumière les différences entre le stock enregistré (dans le logiciel) et celui d'un inventaire.
Sur plus de 600 lignes, dupliquer le formatage conditionel n'était pas une option mais une nécessite.

Le principe
En fin de compte, c'est assez simple. Il suffit d'utiliser une formule dans le formatage conditionnelle pour comparer les cellules.
En dupliquant le formatage conditionnel, on duplique aussi la formule qu'il utilise. Si on a une formule utilisant une comparaison relative, cela devient alors très simple.
 Seulement voila, il faut le savoir pour le faire.

Marche à suivre
1) Sélectionner la cellule sur laquelle s'applique le formattage conditionnel.
2) Activer le formatage conditionnel

3) Encoder la formule type pour comparer les valeurs entre cellule
Mais attention, il est important de retirer les signes "$" pour permettre le déférencement relatif lorsque l'on copiera la formule sur toutes les cellules. (Sinon la comparaison se fera toujours entre $F$2 et $E$2 même après copie de la formule).
3) Copier la formule et le formatage conditionnel sur toutes les cellule de la colonne

Petite amélioration
La comparaison d'une valeur par rapport a #N/A est toujours fausse.
Dans mon cas, le #N/A indique que l'inventaire n'a pas répertorié la référence de l'article.
Donc, un Stock de 6 par rapport à #N/A devrait déclencher le formatage conditionnel mais il ne le fait par car 6 <> #N/A est faux.

Pour résoudre ce problème, il suffit de tester le contenu de la cellule pour savoir si elle contient #N/A.
Le test suivant permet de tester ce la valeur #N/A de la cellule F2 (elle retourne 0 si F2 est #N/A sinon retourne la valeur F2)
=SI(ESTNA(F2)=VRAI;0;F2)

Le formatage conditionnel devient donc
=(SI(ESTNA(F2)=VRAI;0;F2)=E2)

lundi 12 décembre 2011

Font pour Code Barre

Si vous avez besoin d'imprimer des codes barres, vous pouvez toujours jeter un oeil sur le site Free Linear Barcode Image Online Generator (IDAutomation).
Outre la mise a disposition d'un outil en ligne, le site de IDAutomation propose également un zone de téléchargement permettant de se procurer les fonts nécessaire.

J'ai aussi noté la mise à disposition de la font UPC, EAN & GTIN qui devrait permettre de générer des codes barres EAN (13 positions). Cependant, je ne suis pas arrivé à produire de code barre lisible par un scanner.

Par contre, The Code Project publie l'article "Creating EAN-13 BarCode" sur la génération des codes barres en C#.
Malheureusement rien d'utilisable directement en PowerShell (snif)

Ressources:

mercredi 7 décembre 2011

Ripper ses CD sous Ubuntu

Le réponse c'est "Sound_juicer" disponible dans la logithèque.
Source: WikiMedia

Bien que le monde Open-Source offre des format Open-Source de qualité, j'ai tendance à préférer le format propriétaire MP3... simplement parce que je l'utilise depuis des années (en autre sous Windows avec l'encodeur lame).

Par défaut, "Sound_Juicer" ne supporte pas le format MP3 mais ce n'est pas pour autant sans solution.
La document Ubuntu-FR propose cet article qui offre un très bon point de départ pour télécharger et configurer le codeur MP3

jeudi 1 décembre 2011

Manipulation XML en PowerShell

Manipuler XML en PowerShell
PowerShell est capable de lire et de manipuler facilement du contenu XML.
J'ai d'ailleurs trouvé deux excellentes références sur le sujet.
Ou encore:

Comment sauver un HashTable en XML
Il est possible de sauver le contenu d'un HashTable en une seule ligne de code... c'est assez bleufant.
Dans l'exemple suivant,  $list est un HashTable contenant des autres HashTables... voici le contenu de la liste
>>> $__list
Name                           Value                                                                                                                                                                                 
----                           -----                                                                                                                                                                                   
5410439120722                  {ArtCode, EAN, NoteRef, Descr...}                                                                                                                                                       
5410439350358                  {ArtCode, EAN, NoteRef, Descr...}                                                                                                                                                       
5410439354202                  {ArtCode, EAN, NoteRef, Descr...}  

>>> $__list["5410439120722"]
Name                           Value                                                                                                                                                                                   
----                           -----                                                                                                                                                                                   
ArtCode                        BZ1933060080                                                                                                                                                                            
EAN                            5410439120722                                                                                                                                                                           
NoteRef                                                                                                                                                                                                                
Descr                          Vis à tête hex. 8.8 Din 933/934 M 6x 80 zingué                                                                                                                                          
TotalReceiptQty                12 

La sauvegarde se fait à l'aide de la commande suivante:
($__List.Values | convertTo-Xml).Save( "c:\test.xml" )

Et cela produit le résultat suivant:
<?xml version="1.0"?>
<Objects>
  <Object Type="System.Collections.Hashtable">
    <Property Name="Key" Type="System.String">ArtCode</Property>
    <Property Name="Value" Type="System.String">BZ1933060080</Property>
    <Property Name="Key" Type="System.String">EAN</Property>
    <Property Name="Value" Type="System.String">5410439120722</Property>
    <Property Name="Key" Type="System.String">NoteRef</Property>
    <Property Name="Value" Type="System.String" />
    <Property Name="Key" Type="System.String">Descr</Property>
    <Property Name="Value" Type="System.String">Vis à tête hex. 8.8 Din 933/934 M 6x 80 zingué  </Property>
    <Property Name="Key" Type="System.String">TotalReceiptQty</Property>
    <Property Name="Value" Type="System.Int32">12</Property>
  </Object>
  <Object Type="System.Collections.Hashtable">
    <Property Name="Key" Type="System.String">ArtCode</Property>
    <Property Name="Value" Type="System.String">BZ1094050063</Property>
    <Property Name="Key" Type="System.String">EAN</Property>
    <Property Name="Value" Type="System.String">5410439350358</Property>
    <Property Name="Key" Type="System.String">NoteRef</Property>
    <Property Name="Value" Type="System.String" />
    <Property Name="Key" Type="System.String">Descr</Property>
    <Property Name="Value" Type="System.String">Goupille fendue Din 94 * 5,0x 63 zingué  </Property>
    <Property Name="Key" Type="System.String">TotalReceiptQty</Property>
    <Property Name="Value" Type="System.Int32">12</Property>
  </Object>
  <Object Type="System.Collections.Hashtable">
    <Property Name="Key" Type="System.String">ArtCode</Property>
    <Property Name="Value" Type="System.String">BZ1021050015</Property>
    <Property Name="Key" Type="System.String">EAN</Property>
    <Property Name="Value" Type="System.String">5410439354202</Property>
    <Property Name="Key" Type="System.String">NoteRef</Property>
    <Property Name="Value" Type="System.String" />
    <Property Name="Key" Type="System.String">Descr</Property>
    <Property Name="Value" Type="System.String">Rondelle Din 9021 M  5 zingué (5,3/15/1,2)</Property>
    <Property Name="Key" Type="System.String">TotalReceiptQty</Property>
    <Property Name="Value" Type="System.Int32">12</Property>
  </Object>
</Objects>

Le rechargement de la HashTable
Par contre, de toute évidence, le rechargement sera une autre paire de manche.
Ainsi, les données sont rechargées à l'aide de
$xmldata = [xml](Get-Content c:\test.xml) 
Et tous les élement de la la première HashTable visible à l'aide de
$xmlData.Objects.Object[0].Property
Ce qui produit le résultat:
Name                                                                    Type                                                                    #text                                                                  
----                                                                    ----                                                                    -----                                                                  
Key                                                                     System.String                                                           ArtCode                                                                
Value                                                                   System.String                                                           BZ1933060080                                                           
Key                                                                     System.String                                                           EAN                                                                    
Value                                                                   System.String                                                           5410439120722                                                          
Key                                                                     System.String                                                           NoteRef                                                                
Value                                                                   System.String                                                                                                                                  
Key                                                                     System.String                                                           Descr                                                                  
Value                                                                   System.String                                                           Vis à tête hex. 8.8 Din 933/934 M 6x 80 zingué                      
Key                                                                     System.String                                                           TotalReceiptQty                                                        
Value                                                                   System.Int32                                                            12   

Recomposer les paires Clé-Valeur
Pour accéder le contenu des paire clé-valeur de la première HashTable, il faut exécute le code
$xmlData.Objects.Object[0].Property | foreach-object{ if( $_.Name -eq "Key" ){ $KeyName = $_."#Text" } else { $value = $_."#Text"; "$KeyName=$value" }  }

Ce qui produit le résultat:
ArtCode=BZ1933060080
EAN=5410439120722
NoteRef=
Descr=Vis à tête hex. 8.8 Din 933/934 M 6x 80 zingué  
TotalReceiptQty=12

Recomposer une HashTable devient alors assez élémentaire
$ht = @{}
$xmlData.Objects.Object[0].Property | foreach-object{ if( $_.Name -eq "Key" ){ $KeyName = $_."#Text" } else { $value = $_."#Text"; $ht.Add( $KeyName, $value) }  }

L'affichage de la HashTable à l'aide de la commande
$ht
produit le résultat suivant:
Name                           Value                                                                                                                                                                                   
----                           -----                                                                                                                                                                                   
ArtCode                        BZ1933060080                                                                                                                                                                            
EAN                            5410439120722                                                                                                                                                                           
NoteRef                                                                                                                                                                                                                
Descr                          Vis à tête hex. 8.8 Din 933/934 M 6x 80 zingué                                                                                                                                       
TotalReceiptQty                12     

Rechargement de ma liste de HashTable
Sur base du code présenté juste avant, une liste de HashTable telle que présentée en début d'article (une HashTable de HashTable) se recharge comme suit:
$__list = @{}       
       
foreach( $hashTableNode in $xmlData.Objects.Object ) {
  $ht = @{}

   $hashTableNode.Property | foreach-object{ if( $_.Name -eq "Key" ){ $KeyName = $_."#Text" } else { $value = $_."#Text"; $ht.Add( $KeyName, $value) }  }
           
$__list.Add( $ht.EAN.Clone(), $ht.Clone() )

Conversion text vers entier sécurisée (String to Int)

Conversion non sécurisée
La méthode la plus simple de convertir un texte vers sa valeur entière est de faire un casting à la dure.
Bien qu'il existe d'autres méthodes, je vous propose celle-ci en guise d'exemple

$b = [int]"123"
$b
Affiche:
123

Par contre, s'il y a des caractères alphanumérique dans la chaine source, cela se termine en plantage.
Par exemple:
$b = [int]"123a"
Affiche
Impossible de convertir la valeur « 123a » en type « System.Int32 ». Erreur : « Le format de la chaîne d'entrée est incorrect. »
Au niveau de ligne : 1 Caractère : 11
+ $b = [int] <<<< "123a"
    + CategoryInfo          : NotSpecified: (:) [], RuntimeException
    + FullyQualifiedErrorId : RuntimeException


Une conversion sécurisée
La conversion sécurisée est obtenue avec l'opérateur "-as". Si la conversion est impossible, le résultat sera simplement Null.
Voici les deux exemples précédents:
$b = "123" -as [int]
$b -eq $null
Affiche
False

La valeur de $b peut-être utilisée directement
$b
Affiche
123

Et maintenant, s'il y a un problème dans la chaine source:

$b = "123a" -as [int]
$b -eq $null
Affiche... notez que la conversion ne génère pas d'erreur :-)
True

Formattage de string en Power-shell

Avec ses nombreux exemple, l'article "Formatting with PowerShell" est vraiment une excellent référence dans le domaine.

Bonne lecture