jeudi 1 novembre 2012

Introduction à GIT

Git est devenu un système de versionning de fichier très populaire.
Comme je m'intéresse à GitHub pour la publication de librairies, je passe forcement par l'étape de GIT, ce que c'est et comment cela fonctionne.

Voici donc une excellent référence qui explique ce qu'il faut savoir sur GIT

dimanche 21 octobre 2012

Découvrir un DataCenter Google en streetview et en vidéo

Je serais content quand cela sera aussi disponible pour le Data Center Belge (près de Mons)

View Larger Map

Aimez-vous Python? Vous aimerez Raspberry PI!

Aimez-vous Python?
Oui... ca tombe bien, nous aussi.
Nous avons justement trouvé un SoC (System On Chip=Ordinateur sur une Puce) qui se programme en Python! Abordable, Hackable, Linux Based, Python Programming... <3 <3 <3 <3 <3 <3 <3

Il y a quelques semaines, MCHobby à commencer à commercialiser Raspberry-PI.

Le Pi dispose d'un OS Linux (wheezy Raspbian... dérivé direct de Debian) et se programme en... Python.
Disposant d'un port d'entrée/sortie, d'un disque SD, d'une connectique ethernet et USB, Raspberry se trouve être un excellent environnement pour developper et faire fonctionner des applications embarquées écrites en Python.

Raspberry PI disponible chez MC Hobby

Il est vraiment simple de prendre le contrôle de Raspberry en SSH (c'est prévu "out-of-the-box").
raspberry PI dispose également d'une sortie HDMI, il est donc possible de le raccorder sur un moniteur DVI-D avec un clavier et souris.
Cela ne signifie pas que vous êtes limités à la ligne de commande... Wheezy Raspbian est suffisamment puissant pour faire tourner l'environnement graphique XCFE et un editeur Python avec une bonne fluidité.

Comme c'est une machine Linux à base de Debian, les possibilités et champs d'application sont vraiment large.
Pour les hacker, vous apprendrez qu'il est également possible d'overclocker un Raspberry-Pi à 1 Ghz... et très facilement même.

Ce week-end nous nous sommes penché sur les possibilités du port GPIO avec le Cobbler d'AdaFruit.
PI Cobbler + extra
Disponible chez MC Hobby

Le moins que l'on puisse dire c'est que nos tutoriels français ont littéralement explosés sous les découvertes (que nous documentons bien évidemment).


mardi 2 octobre 2012

Mondial Relay - Error 97 - PrestaShop

Voila une erreur apparue sur www.mchobby.be qui a bien faillit me rendre chèvre.

Durant le processus de sélection d'un moyen de transport Mondial Relay, PrestaShop affichait le message d'erreur suivant:

There is an error number : 97
Details : Clé de sécurité invalide
 
Quand ont sait pourquoi, c'est "en fin de compte" assez simple a corriger.
Cette erreur 97 est produite parce que le "Code Postal" et "Ville" mentionnées ne sont pas compatible.
 
Comprenez: La combinaison CP + Ville n'existe pas dans la DB de Mondial Relay. Et cela peut être une question de caractères comme dans l'exemple qui nous concerne. 

La fiche client contenait:

En fait, 7021 correspond exactement à "Havré" et non à "Mons (Havré)".

Une fois la fiche client corrigée... plus d'erreur 97 :-)

MountVol et lecteur USB plus reconnu

Si vous essayez la commande

mountvol z: /D
ou
mountvol z: /P

vous constaterez vite que le volume n'est plus reconnu (gloups!).
Le périphérique USB est bien visible dans "périphérique et imprimante" mais il n'y a plus de lecteur pour accéder aux fichiers.

Cela arrive parce qu'il n'y a plus de lettre assignée au volume.
Le plus simple est de réassigner manuellement une lettre par l'intermédiaire du gestionnaire de disque (clique droit sur la partition puis "ajouter lettre")

Le plus gros problème c'est de trouver le gestionnaire de disque dans les méandres de Windows Seven.
Le raccourcis c'est:
(touche <Windows> + <R>, tape diskmgmt.msc puis <Entrer>)

RemoveDrive
Pour pouvoir éjecter un lecteur USB en toute sécurité, il faut utiliser un utilitaire disponible sur le NET.
Il s'appelle RemoveDrive et fonctionne parfaitement sans heurt.

RemoveDrive V2.3.3 - Safe removal of drives

Disponible http://www.uwe-sieber.de/drivetools_e.html

Cobian Backup et Multiple disque USB

Cobian Backup est un excellent logiciel de backup open-source... l'un des meilleurs sans être une usine à gaz!
Même après des années d'utilisation j'en reste pleinement satisfait.

Il y a cependant une ombre au tableau.
Si l'on peu utiliser plusieurs disques USB pour faire des backups (disons 1 disque différent par jour), il est impossible d'avoir une lettre de volume unique pour tous ces lecteurs.
On a pas non plus la certitude que l'on aura toujours la même lettre pour un lecteur lorsuq'il est rebranché plus tard.

C'est ennuyant parce que Cobian Backup est intimement lié à la lettre d'identification du volume.

Il reste alors deux solutions possibles:
  1. Créer une tâche Cobian Backup par disque de backup (en assignant une lettre différente à chaque lecteur)... une approche pas vraiment "pro"
  2. Utilise un batch qui essaye de re-mapper le lecteur sur une lettre choisie arbitrairement (par exemple Z:)... nettement plus pro
MapDrive.bat
Dans le billet "Usb drivers / Subst solution", j'ai trouvé un batch qui teste l'existence d'un fichier pour détecter le lecteur backup.
Une fois le lecteur détecté, il utilise l'instruction MountVol pour remonter le lecteur sur une lettre arbitrairement choisie.

Hé bien... chapeau bas! Voici une méthode simple et élégante.

@echo off
rem ********************************************************
rem changes disk drive letter based off file test

rem     File/dir To Test For
rem     ex   E:\backup.tag   = backup.tag
rem     ex2  E:\iPod_Control = iPod_Control

SET TEST=backup.tag


rem    Drive to Move To

SET DEST=Z:

rem    Media Name
rem    ex Backup or "USB STICK"

SET NAME=GGBackup

rem ********************************************************

echo Testing Destination %DEST%
if exist %DEST%\%TEST% goto good
if exist %DEST% goto fail_inuse
echo Finding %NAME%

set DRV=E:
echo testing %DRV%
if exist %DRV%\%TEST% goto found

set DRV=F:
echo testing %DRV%
if exist %DRV%\%TEST% goto found

set DRV=G:
echo testing %DRV%
if exist %DRV%\%TEST% goto found

set DRV=H:
echo testing %DRV%
if exist %DRV%\%TEST% goto found

set DRV=I:
echo testing %DRV%
if exist %DRV%\%TEST% goto found

set DRV=J:
echo testing %DRV%
if exist %DRV%\%TEST% goto found

set DRV=K:
echo testing %DRV%
if exist %DRV%\%TEST% goto found

set DRV=L:
echo testing %DRV%
if exist %DRV%\%TEST% goto found

goto fail


:found
echo Found  %NAME% At %DRV%
echo Moving %NAME% To %DEST%

FOR /F "delims=" %%x IN ('MOUNTVOL %DRV% /L') DO SET DF=%%x

IF "%DF%"=="The system cannot find the file specified." GOTO failmap

echo.
echo Unmapping Drive %DRV%
MOUNTVOL %DRV% /D
echo Remapping Drive %DEST%
MOUNTVOL %DEST% %DF%

echo.
Echo Testing %DEST%
if exist %DEST%\%TEST% goto good
echo Faild Test
echo %NAME% Status Unknown
goto end

:good
echo.
echo %NAME% Is Properly Located At %DEST%
goto end

:failmap
echo Failed To Reassign Found Drive
goto end

:fail_inuse
echo %DEST% Is Inuse And Not Target Drive
echo Remap Failed
goto end

:fail
echo %NAME% Not Found
goto end


:end

Ce qu'il y a de vraiment bien avec ce batch, c'est que "Cobian Backup" peut l'exécuter juste avant la tâche de backup :-)))

RemoveDrive
N'essayez pas de démonter votre clé USB avec mountvol, vous allez avoir une sacré surpris!!!
MountVol est un peu trop radical et le périphérique n'est plus remonté lorsqu'il est rebranché (voir l'autre article publié ce jour).

Pour démonter un Volume en toute sécurité, il faut utiliser le programme RemoveDrive qui fonctionne à merveille.
RemoveDrive peut être trouvé ici http://www.uwe-sieber.de/drivetools_e.html

UnMapDrive
Sur base du premier script, ce dernier à été modifié pour appeler la commande RemoveDrive.exe au lieu de MountVol.
Il teste l'existence d'un fichier (backup.tag) et démonte ensuite le volume.

C'est une version vite fait... mais un bon début ;-)
@echo off
rem ********************************************************
rem changes disk drive letter based off file test

rem     File/dir To Test For
rem     ex   E:\backup.tag   = backup.tag
rem     ex2  E:\iPod_Control = iPod_Control

SET TEST=backup.tag


rem    Drive to Move To

SET DEST=Z:

rem    Media Name
rem    ex Backup or "USB STICK"

SET NAME=GGBackup

rem ********************************************************

echo Testing Destination %DEST%
if exist %DEST%\%TEST% goto good
if exist %DEST% goto found
echo Finding %NAME%

set DRV=E:
echo testing %DRV%
if exist %DRV%\%TEST% goto found

set DRV=F:
echo testing %DRV%
if exist %DRV%\%TEST% goto found

set DRV=G:
echo testing %DRV%
if exist %DRV%\%TEST% goto found

set DRV=H:
echo testing %DRV%
if exist %DRV%\%TEST% goto found

set DRV=I:
echo testing %DRV%
if exist %DRV%\%TEST% goto found

set DRV=J:
echo testing %DRV%
if exist %DRV%\%TEST% goto found

set DRV=K:
echo testing %DRV%
if exist %DRV%\%TEST% goto found

set DRV=L:
echo testing %DRV%
if exist %DRV%\%TEST% goto found

goto fail


:found
echo Found  %NAME% At %DRV%
echo Moving %NAME% To %DEST%

rem FOR /F "delims=" %%x IN ('MOUNTVOL %DRV% /L') DO SET DF=%%x

rem IF "%DF%"=="The system cannot find the file specified." GOTO failmap

echo.
echo Unmapping Drive %DRV%
removedrive.exe %DRV%
goto end

:good
echo.
echo %NAME% Is Properly Located At %DEST%
echo Unmapping Drive %DEST%
c:\dev\removedrive.exe %DEST%
goto end

rem :failmap
rem echo Failed To Reassign Found Drive
rem goto end

:fail
echo %NAME% Not Found
goto end


:end

mardi 25 septembre 2012

Clipper - OutputDebugString en Harbour

Parmi mes premiers articles relatifs au développement clipper sous Harbour, l'un me mes principaux problème était l'obtention de message de débuggogage.

Ce problème fut solutionné en mettant en place un fichier "debug" dans lequel j'envoyais les messages par l'intermédiaire d'une fonction DMSG.

Aujourd'hui j'ai amélioré la fonction DMSG avec un simple appel de fonction qui envoi également le message de débogage au Kernel de Windows.
Du coup, je peux tracer les activités de mon programme à l'aide du DebugView de SysInternals :-)
Trop Top!!!

Appel à l'API OutputDebugString
Aussi simple que :

WAPI_OUTPUTDEBUGSTRING( sMsg )

Résultat dans DebugView
Vous pouvez trouvez DebugView en tapant "debugview" dans une recherche Google.
N'oubliez pas de démarrer DebugView en mode Administrateur... sinon vous ne verrez aucun message!

Yes!!!

Harbour et l'API Window
Vous trouverez une liste complète de l'API Windows supportée dans le fichier
c:\hb30\include\HbWin.hbx
A titre d'exemple, voici une liste complète de ce que j'ai trouvé dans ma release 3.0 d'Harbour.
Pour savoir comment les utilisés... il suffit de faire une recherche dans tous les fichiers de c:\hb30\ , il y a généralement des exemples d'utilisation

...
DYNAMIC ANSITOWIDE
DYNAMIC CALLDLL
DYNAMIC CALLDLLBOOL
DYNAMIC CALLDLLTYPED
DYNAMIC CREATEOBJECT
DYNAMIC CREATEOLEOBJECT
DYNAMIC FREELIBRARY
DYNAMIC GETACTIVEOBJECT
DYNAMIC GETDEFAULTPRINTER
DYNAMIC GETLASTERROR
DYNAMIC GETPRINTERS
DYNAMIC GETPROCADDRESS
DYNAMIC LOADLIBRARY
DYNAMIC MESSAGEBOX
DYNAMIC OLE2TXTERROR
DYNAMIC OLEERROR
DYNAMIC PRINTEREXISTS
DYNAMIC PRINTERPORTTONAME
DYNAMIC PRINTFILERAW
DYNAMIC SETDEFAULTPRINTER
DYNAMIC SETLASTERROR
DYNAMIC TOLEAUTO
DYNAMIC WAPI_ABORTDOC
DYNAMIC WAPI_ADDFONTRESOURCEEX
DYNAMIC WAPI_APPENDMENU
DYNAMIC WAPI_ARC
DYNAMIC WAPI_CHECKMENUITEM
DYNAMIC WAPI_CHECKMENURADIOITEM
DYNAMIC WAPI_COMBOBOX_ADDSTRING
DYNAMIC WAPI_CREATEACCELERATORTABLE
DYNAMIC WAPI_CREATEDC
DYNAMIC WAPI_CREATEFONT
DYNAMIC WAPI_CREATEFONTINDIRECT
DYNAMIC WAPI_CREATEHATCHBRUSH
DYNAMIC WAPI_CREATEMENU
DYNAMIC WAPI_CREATEMUTEX
DYNAMIC WAPI_CREATEPEN
DYNAMIC WAPI_CREATEPOPUPMENU
DYNAMIC WAPI_CREATESOLIDBRUSH
DYNAMIC WAPI_CREATEWINDOWEX
DYNAMIC WAPI_DELETEMENU
DYNAMIC WAPI_DESTROYACCELERATORTABLE
DYNAMIC WAPI_DESTROYMENU
DYNAMIC WAPI_DESTROYWINDOW
DYNAMIC WAPI_DIALOGBOXPARAM
DYNAMIC WAPI_DRAWMENUBAR
DYNAMIC WAPI_DRAWTEXT
DYNAMIC WAPI_ELLIPSE
DYNAMIC WAPI_ENABLEMENUITEM
DYNAMIC WAPI_ENABLESCROLLBAR
DYNAMIC WAPI_ENDDIALOG
DYNAMIC WAPI_ENDDOC
DYNAMIC WAPI_ENDPAGE
DYNAMIC WAPI_EXTTEXTOUT
DYNAMIC WAPI_FILLRECT
DYNAMIC WAPI_FINDWINDOW
DYNAMIC WAPI_FORMATMESSAGE
DYNAMIC WAPI_FREELIBRARY
DYNAMIC WAPI_GETACP
DYNAMIC WAPI_GETACTIVEWINDOW
DYNAMIC WAPI_GETBKCOLOR
DYNAMIC WAPI_GETBKMODE
DYNAMIC WAPI_GETCOMMANDLINE
DYNAMIC WAPI_GETCURRENTPROCESS
DYNAMIC WAPI_GETCURRENTPROCESSID
DYNAMIC WAPI_GETCURRENTTHREAD
DYNAMIC WAPI_GETCURRENTTHREADID
DYNAMIC WAPI_GETDESKTOPWINDOW
DYNAMIC WAPI_GETDEVICECAPS
DYNAMIC WAPI_GETDLGITEM
DYNAMIC WAPI_GETDLGITEMTEXT
DYNAMIC WAPI_GETKEYSTATE
DYNAMIC WAPI_GETLASTERROR
DYNAMIC WAPI_GETLONGPATHNAME
DYNAMIC WAPI_GETMAPMODE
DYNAMIC WAPI_GETMENU
DYNAMIC WAPI_GETMENUDEFAULTITEM
DYNAMIC WAPI_GETMENUITEMCOUNT
DYNAMIC WAPI_GETMENUITEMID
DYNAMIC WAPI_GETMENUSTATE
DYNAMIC WAPI_GETMODULEHANDLE
DYNAMIC WAPI_GETOEMCP
DYNAMIC WAPI_GETPROCADDRESS
DYNAMIC WAPI_GETSCROLLINFO
DYNAMIC WAPI_GETSCROLLPOS
DYNAMIC WAPI_GETSCROLLRANGE
DYNAMIC WAPI_GETSHORTPATHNAME
DYNAMIC WAPI_GETSUBMENU
DYNAMIC WAPI_GETSYSTEMDIRECTORY
DYNAMIC WAPI_GETSYSTEMMENU
DYNAMIC WAPI_GETSYSTEMMETRICS
DYNAMIC WAPI_GETTEXTALIGN
DYNAMIC WAPI_GETTEXTCOLOR
DYNAMIC WAPI_GETTEXTFACE
DYNAMIC WAPI_GETWINDOWSDIRECTORY
DYNAMIC WAPI_IMAGELIST_ADD
DYNAMIC WAPI_IMAGELIST_ADDMASKED
DYNAMIC WAPI_IMAGELIST_BEGINDRAG
DYNAMIC WAPI_IMAGELIST_COPY
DYNAMIC WAPI_IMAGELIST_CREATE
DYNAMIC WAPI_IMAGELIST_DESTROY
DYNAMIC WAPI_IMAGELIST_DRAGENTER
DYNAMIC WAPI_IMAGELIST_DRAGLEAVE
DYNAMIC WAPI_IMAGELIST_DRAGMOVE
DYNAMIC WAPI_IMAGELIST_DRAGSHOWNOLOCK
DYNAMIC WAPI_IMAGELIST_DRAW
DYNAMIC WAPI_IMAGELIST_DRAWEX
DYNAMIC WAPI_IMAGELIST_DUPLICATE
DYNAMIC WAPI_IMAGELIST_GETBKCOLOR
DYNAMIC WAPI_IMAGELIST_GETICON
DYNAMIC WAPI_IMAGELIST_GETICONSIZE
DYNAMIC WAPI_IMAGELIST_GETIMAGECOUNT
DYNAMIC WAPI_IMAGELIST_GETIMAGEINFO
DYNAMIC WAPI_IMAGELIST_LOADIMAGE
DYNAMIC WAPI_IMAGELIST_MERGE
DYNAMIC WAPI_IMAGELIST_REMOVE
DYNAMIC WAPI_IMAGELIST_REPLACE
DYNAMIC WAPI_IMAGELIST_REPLACEICON
DYNAMIC WAPI_IMAGELIST_SETBKCOLOR
DYNAMIC WAPI_IMAGELIST_SETDRAGCURSORIMAGE
DYNAMIC WAPI_IMAGELIST_SETICONSIZE
DYNAMIC WAPI_IMAGELIST_SETIMAGECOUNT
DYNAMIC WAPI_INSERTMENU
DYNAMIC WAPI_ISICONIC
DYNAMIC WAPI_ISMENU
DYNAMIC WAPI_ISUSERANADMIN
DYNAMIC WAPI_ISWINDOW
DYNAMIC WAPI_ISZOOMED
DYNAMIC WAPI_LINETO
DYNAMIC WAPI_LOADIMAGE
DYNAMIC WAPI_LOADLIBRARY
DYNAMIC WAPI_LOADMENU
DYNAMIC WAPI_MESSAGEBEEP
DYNAMIC WAPI_MESSAGEBOX
DYNAMIC WAPI_MOVETOEX
DYNAMIC WAPI_MULDIV
DYNAMIC WAPI_OPENMUTEX
DYNAMIC WAPI_OUTPUTDEBUGSTRING
DYNAMIC WAPI_PLAYSOUND
DYNAMIC WAPI_RECTANGLE
DYNAMIC WAPI_RELEASEMUTEX
DYNAMIC WAPI_REMOVEFONTRESOURCEEX
DYNAMIC WAPI_REMOVEMENU
DYNAMIC WAPI_RESETDC
DYNAMIC WAPI_ROUNDRECT
DYNAMIC WAPI_SELECTOBJECT
DYNAMIC WAPI_SETACTIVEWINDOW
DYNAMIC WAPI_SETBKCOLOR
DYNAMIC WAPI_SETBKMODE
DYNAMIC WAPI_SETDLGITEMTEXT
DYNAMIC WAPI_SETERRORMODE
DYNAMIC WAPI_SETFOCUS
DYNAMIC WAPI_SETLASTERROR
DYNAMIC WAPI_SETMAPMODE
DYNAMIC WAPI_SETMENU
DYNAMIC WAPI_SETMENUDEFAULTITEM
DYNAMIC WAPI_SETPROCESSWORKINGSETSIZE
DYNAMIC WAPI_SETSCROLLINFO
DYNAMIC WAPI_SETSCROLLPOS
DYNAMIC WAPI_SETSCROLLRANGE
DYNAMIC WAPI_SETTEXTALIGN
DYNAMIC WAPI_SETTEXTCOLOR
DYNAMIC WAPI_SETWINDOWPOS
DYNAMIC WAPI_SHELLEXECUTE
DYNAMIC WAPI_SHOWSCROLLBAR
DYNAMIC WAPI_SLEEP
DYNAMIC WAPI_STARTDOC
DYNAMIC WAPI_STARTPAGE
DYNAMIC WAPI_TABCTRL_ADDITEM
DYNAMIC WAPI_TABCTRL_ADJUSTRECT
DYNAMIC WAPI_TABCTRL_CREATE
DYNAMIC WAPI_TABCTRL_DELETEALLITEMS
DYNAMIC WAPI_TABCTRL_DELETEITEM
DYNAMIC WAPI_TABCTRL_DESELECTALL
DYNAMIC WAPI_TABCTRL_GETCURFOCUS
DYNAMIC WAPI_TABCTRL_GETCURSEL
DYNAMIC WAPI_TABCTRL_GETEXTENDEDSTYLE
DYNAMIC WAPI_TABCTRL_GETIMAGELIST
DYNAMIC WAPI_TABCTRL_GETITEM
DYNAMIC WAPI_TABCTRL_GETITEMCOUNT
DYNAMIC WAPI_TABCTRL_GETITEMRECT
DYNAMIC WAPI_TABCTRL_GETROWCOUNT
DYNAMIC WAPI_TABCTRL_GETTOOLTIPS
DYNAMIC WAPI_TABCTRL_GETUNICODEFORMAT
DYNAMIC WAPI_TABCTRL_HIGHLIGHTITEM
DYNAMIC WAPI_TABCTRL_HITTEST
DYNAMIC WAPI_TABCTRL_INSERTITEM
DYNAMIC WAPI_TABCTRL_REMOVEIMAGE
DYNAMIC WAPI_TABCTRL_SETCURFOCUS
DYNAMIC WAPI_TABCTRL_SETCURSEL
DYNAMIC WAPI_TABCTRL_SETEXTENDEDSTYLE
DYNAMIC WAPI_TABCTRL_SETIMAGELIST
DYNAMIC WAPI_TABCTRL_SETITEM
DYNAMIC WAPI_TABCTRL_SETITEMEXTRA
DYNAMIC WAPI_TABCTRL_SETITEMSIZE
DYNAMIC WAPI_TABCTRL_SETMINTABWIDTH
DYNAMIC WAPI_TABCTRL_SETPADDING
DYNAMIC WAPI_TABCTRL_SETTOOLTIPS
DYNAMIC WAPI_TABCTRL_SETUNICODEFORMAT
DYNAMIC WAPI_TEXTOUT
DYNAMIC WAPI_TRACKPOPUPMENU
DYNAMIC WAPI_TREEVIEW_CREATEDRAGIMAGE
DYNAMIC WAPI_TREEVIEW_DELETEALLITEMS
DYNAMIC WAPI_TREEVIEW_EDITLABEL
DYNAMIC WAPI_TREEVIEW_ENDEDITLABELNOW
DYNAMIC WAPI_TREEVIEW_ENSUREVISIBLE
DYNAMIC WAPI_TREEVIEW_EXPAND
DYNAMIC WAPI_TREEVIEW_GETBKCOLOR
DYNAMIC WAPI_TREEVIEW_GETCHECKSTATE
DYNAMIC WAPI_TREEVIEW_GETCHILD
DYNAMIC WAPI_TREEVIEW_GETCOUNT
DYNAMIC WAPI_TREEVIEW_GETDROPHILIGHT
DYNAMIC WAPI_TREEVIEW_GETEDITCONTROL
DYNAMIC WAPI_TREEVIEW_GETFIRSTVISIBLE
DYNAMIC WAPI_TREEVIEW_GETIMAGELIST
DYNAMIC WAPI_TREEVIEW_GETINDENT
DYNAMIC WAPI_TREEVIEW_GETINSERTMARKCOLOR
DYNAMIC WAPI_TREEVIEW_GETISEARCHSTRING
DYNAMIC WAPI_TREEVIEW_GETITEM
DYNAMIC WAPI_TREEVIEW_GETITEMHEIGHT
DYNAMIC WAPI_TREEVIEW_GETITEMRECT
DYNAMIC WAPI_TREEVIEW_GETITEMSTATE
DYNAMIC WAPI_TREEVIEW_GETLASTVISIBLE
DYNAMIC WAPI_TREEVIEW_GETLINECOLOR
DYNAMIC WAPI_TREEVIEW_GETNEXTITEM
DYNAMIC WAPI_TREEVIEW_GETNEXTSIBLING
DYNAMIC WAPI_TREEVIEW_GETNEXTVISIBLE
DYNAMIC WAPI_TREEVIEW_GETPARENT
DYNAMIC WAPI_TREEVIEW_GETPREVSIBLING
DYNAMIC WAPI_TREEVIEW_GETPREVVISIBLE
DYNAMIC WAPI_TREEVIEW_GETROOT
DYNAMIC WAPI_TREEVIEW_GETSCROLLTIME
DYNAMIC WAPI_TREEVIEW_GETSELECTION
DYNAMIC WAPI_TREEVIEW_GETTEXTCOLOR
DYNAMIC WAPI_TREEVIEW_GETTOOLTIPS
DYNAMIC WAPI_TREEVIEW_GETUNICODEFORMAT
DYNAMIC WAPI_TREEVIEW_GETVISIBLECOUNT
DYNAMIC WAPI_TREEVIEW_HITTEST
DYNAMIC WAPI_TREEVIEW_INSERTITEM
DYNAMIC WAPI_TREEVIEW_SELECT
DYNAMIC WAPI_TREEVIEW_SELECTDROPTARGET
DYNAMIC WAPI_TREEVIEW_SELECTITEM
DYNAMIC WAPI_TREEVIEW_SELECTSETFIRSTVISIBLE
DYNAMIC WAPI_TREEVIEW_SETBKCOLOR
DYNAMIC WAPI_TREEVIEW_SETCHECKSTATE
DYNAMIC WAPI_TREEVIEW_SETIMAGELIST
DYNAMIC WAPI_TREEVIEW_SETINDENT
DYNAMIC WAPI_TREEVIEW_SETINSERTMARK
DYNAMIC WAPI_TREEVIEW_SETINSERTMARKCOLOR
DYNAMIC WAPI_TREEVIEW_SETITEM
DYNAMIC WAPI_TREEVIEW_SETITEMHEIGHT
DYNAMIC WAPI_TREEVIEW_SETITEMSTATE
DYNAMIC WAPI_TREEVIEW_SETLINECOLOR
DYNAMIC WAPI_TREEVIEW_SETSCROLLTIME
DYNAMIC WAPI_TREEVIEW_SETTEXTCOLOR
DYNAMIC WAPI_TREEVIEW_SETTOOLTIPS
DYNAMIC WAPI_TREEVIEW_SETUNICODEFORMAT
DYNAMIC WAPI_TREEVIEW_SORTCHILDREN
DYNAMIC WAPI_WAITFORMULTIPLEOBJECTS
DYNAMIC WAPI_WAITFORMULTIPLEOBJECTSEX
DYNAMIC WAPI_WAITFORSINGLEOBJECT
DYNAMIC WAPI_WAITFORSINGLEOBJECTEX
DYNAMIC WAPI_WNETGETLASTERROR
DYNAMIC WCE_SIM
DYNAMIC WCE_SIMDEINITIALIZE
DYNAMIC WCE_SIMDELETEPHONEBOOKENTRY
DYNAMIC WCE_SIMINITIALIZE
DYNAMIC WCE_SIMPHONEBOOKSTATUS
DYNAMIC WCE_SIMREADPHONEBOOKENTRY
DYNAMIC WCE_SIMWRITEPHONEBOOKENTRY
DYNAMIC WCE_SMSSENDMESSAGE
DYNAMIC WIDETOANSI
DYNAMIC WIN_ABORTDOC
DYNAMIC WIN_ANSITOWIDE
DYNAMIC WIN_ARC
DYNAMIC WIN_AXGETCONTROL
DYNAMIC WIN_AXINIT
DYNAMIC WIN_BITMAPDIMENSIONS
DYNAMIC WIN_BITMAPISSUPPORTED
DYNAMIC WIN_BITMAPSOK
DYNAMIC WIN_BITMAPTYPE
DYNAMIC WIN_BMP
DYNAMIC WIN_COM
DYNAMIC WIN_COMCLOSE
DYNAMIC WIN_COMDEBUGDCB
DYNAMIC WIN_COMDTRFLOW
DYNAMIC WIN_COMERROR
DYNAMIC WIN_COMERRORCLEAR
DYNAMIC WIN_COMFUNCLAST
DYNAMIC WIN_COMISVALID
DYNAMIC WIN_COMOPEN
DYNAMIC WIN_COMPURGE
DYNAMIC WIN_COMQUEUESTATUS
DYNAMIC WIN_COMREAD
DYNAMIC WIN_COMRECV
DYNAMIC WIN_COMRTSFLOW
DYNAMIC WIN_COMSETDTR
DYNAMIC WIN_COMSETQUEUESIZE
DYNAMIC WIN_COMSETRTS
DYNAMIC WIN_COMSETTIMEOUTS
DYNAMIC WIN_COMSTATUS
DYNAMIC WIN_COMWRITE
DYNAMIC WIN_COMXONXOFFFLOW
DYNAMIC WIN_CREATEDC
DYNAMIC WIN_CREATEFONT
DYNAMIC WIN_DELETEDC
DYNAMIC WIN_DRAWBITMAP
DYNAMIC WIN_ELLIPSE
DYNAMIC WIN_ENDDOC
DYNAMIC WIN_ENDPAGE
DYNAMIC WIN_ENUMFONTS
DYNAMIC WIN_FILLRECT
DYNAMIC WIN_GETCHARSIZE
DYNAMIC WIN_GETCOMMANDLINEPARAM
DYNAMIC WIN_GETDEVICECAPS
DYNAMIC WIN_GETDOCUMENTPROPERTIES
DYNAMIC WIN_GETEXEFILENAME
DYNAMIC WIN_GETOPENFILENAME
DYNAMIC WIN_GETPRINTERFONTNAME
DYNAMIC WIN_GETSAVEFILENAME
DYNAMIC WIN_GETTEXTSIZE
DYNAMIC WIN_HINSTANCE
DYNAMIC WIN_HIWORD
DYNAMIC WIN_HPREVINSTANCE
DYNAMIC WIN_LINETO
DYNAMIC WIN_LOADBITMAPFILE
DYNAMIC WIN_LOADRESOURCE
DYNAMIC WIN_LOWORD
DYNAMIC WIN_MAPISENDMAIL
DYNAMIC WIN_N2P
DYNAMIC WIN_NCMDSHOW
DYNAMIC WIN_OLEAUTO
DYNAMIC WIN_OLEAUTO___ONERROR
DYNAMIC WIN_OLEAUTO___OPINDEX
DYNAMIC WIN_OLECREATEOBJECT
DYNAMIC WIN_OLEERROR
DYNAMIC WIN_OLEERRORTEXT
DYNAMIC WIN_OLEGETACTIVEOBJECT
DYNAMIC WIN_OSIS2000
DYNAMIC WIN_OSIS2000ORUPPER
DYNAMIC WIN_OSIS2003
DYNAMIC WIN_OSIS7
DYNAMIC WIN_OSIS95
DYNAMIC WIN_OSIS98
DYNAMIC WIN_OSIS9X
DYNAMIC WIN_OSISME
DYNAMIC WIN_OSISNT
DYNAMIC WIN_OSISNT351
DYNAMIC WIN_OSISNT4
DYNAMIC WIN_OSISTSCLIENT
DYNAMIC WIN_OSISVISTA
DYNAMIC WIN_OSISVISTAORUPPER
DYNAMIC WIN_OSISWINXPORUPPER
DYNAMIC WIN_OSISXP
DYNAMIC WIN_OSNETREGOK
DYNAMIC WIN_OSNETVREDIROK
DYNAMIC WIN_OSVERSIONINFO
DYNAMIC WIN_P2N
DYNAMIC WIN_PRINTDLGDC
DYNAMIC WIN_PRINTEREXISTS
DYNAMIC WIN_PRINTERGETDEFAULT
DYNAMIC WIN_PRINTERLIST
DYNAMIC WIN_PRINTERPORTTONAME
DYNAMIC WIN_PRINTERSETDEFAULT
DYNAMIC WIN_PRINTERSTATUS
DYNAMIC WIN_PRINTFILERAW
DYNAMIC WIN_PRN
DYNAMIC WIN_RECTANGLE
DYNAMIC WIN_REGCLOSEKEY
DYNAMIC WIN_REGCREATEKEYEX
DYNAMIC WIN_REGDELETE
DYNAMIC WIN_REGDELETEKEY
DYNAMIC WIN_REGDELETEVALUE
DYNAMIC WIN_REGGET
DYNAMIC WIN_REGOPENKEYEX
DYNAMIC WIN_REGPATHSPLIT
DYNAMIC WIN_REGQUERY
DYNAMIC WIN_REGQUERYVALUEEX
DYNAMIC WIN_REGREAD
DYNAMIC WIN_REGSET
DYNAMIC WIN_REGSETVALUEEX
DYNAMIC WIN_REGWRITE
DYNAMIC WIN_REPORTEVENT
DYNAMIC WIN_RUNDETACHED
DYNAMIC WIN_SERVICEDELETE
DYNAMIC WIN_SERVICEGETSTATUS
DYNAMIC WIN_SERVICEINSTALL
DYNAMIC WIN_SERVICESETEXITCODE
DYNAMIC WIN_SERVICESETSTATUS
DYNAMIC WIN_SERVICESTART
DYNAMIC WIN_SERVICESTOP
DYNAMIC WIN_SETBKMODE
DYNAMIC WIN_SETCOLOR
DYNAMIC WIN_SETDOCUMENTPROPERTIES
DYNAMIC WIN_SETMAPMODE
DYNAMIC WIN_SETPEN
DYNAMIC WIN_SHELLNOTIFYICON
DYNAMIC WIN_SHFILEOPERATION
DYNAMIC WIN_STARTDOC
DYNAMIC WIN_STARTPAGE
DYNAMIC WIN_SYSREFRESH
DYNAMIC WIN_TEXTOUT
DYNAMIC WIN_UNICODE
DYNAMIC WIN_UUIDCREATESTRING
DYNAMIC WIN_WIDETOANSI
DYNAMIC XISPRINTER
DYNAMIC __AXDOVERB
DYNAMIC __AXGETCONTROL
DYNAMIC __AXREGISTERHANDLER
DYNAMIC __OLECREATEOBJECT
DYNAMIC __OLEENUMCREATE
DYNAMIC __OLEENUMNEXT
DYNAMIC __OLEGETACTIVEOBJECT
DYNAMIC __OLEPDISP
DYNAMIC __WAPI_DEVMODE_GET
DYNAMIC __WAPI_DEVMODE_NEW
DYNAMIC __WAPI_DEVMODE_SET
...

lundi 24 septembre 2012

Clipper - Gestion des Hash sous Harbour

Introduction
Les Hash (Hash Table) sont des structures qui, typiquement, permettent d'implémenter des dictionnaires.
Les dictionnaires permettent d'enregistrer des pairs CLE = VALEUR dans une liste... c'est pratique à de nombreux égards.

Le grand avantage d'un dictionnaire, c'est que l'on peut y lire une valeur grâce à une syntaxe simplifiée

ma_valeur := Le_dictionnaire[ "la_cle" ]

Un rapide coup d'oeil sur les fonctions Harbours
Voici quelques bouts de code ci-et-là qui permettent de se familiariser avec les instructions relatives au Hash.

 IF hb_isHash( xData ) .AND. hb_hHasKey( xData, "Today" )
      OutStd( xData[ "Today" ], hb_eol() )
   ENDIF

Il est possible de créer un hash grâce à l'instruction:
hParams := hb_Hash()

Mais j'ai le sentiment que l'instruction suivante produit aussi un Hash:
LOCAL hData := {=>}

Le fichier de compatibilité de Harbour (hbcompat.ch) nous apprend qu'il existe de nombreuses autre fonctions utilitaires autour des Hash:
   #xtranslate hb_HASH([<x,...>])          => HASH(<x>)
   #xtranslate hb_HHASKEY([<x,...>])       => HHASKEY(<x>)
   #xtranslate hb_HPOS([<x,...>])          => HGETPOS(<x>)
   #xtranslate hb_HGET([<x,...>])          => HGET(<x>)
   #xtranslate hb_HSET([<x,...>])          => HSET(<x>)
   #xtranslate hb_HDEL([<x,...>])          => HDEL(<x>)
   #xtranslate hb_HKEYAT([<x,...>])        => HGETKEYAT(<x>)
   #xtranslate hb_HVALUEAT([<x,...>])      => HGETVALUEAT(<x>)
   #xtranslate hb_HVALUEAT([<x,...>])      => HSETVALUEAT(<x>)
   #xtranslate hb_HPAIRAT([<x,...>])       => HGETPAIRAT(<x>)
   #xtranslate hb_HDELAT([<x,...>])        => HDELAT(<x>)
   #xtranslate hb_HKEYS([<x,...>])         => HGETKEYS(<x>)
   #xtranslate hb_HVALUES([<x,...>])       => HGETVALUES(<x>)
   #xtranslate hb_HFILL([<x,...>])         => HFILL(<x>)
   #xtranslate hb_HCLONE([<x,...>])        => HCLONE(<x>)
   #xtranslate hb_HCOPY([<x,...>])         => HCOPY(<x>)
   #xtranslate hb_HMERGE([<x,...>])        => HMERGE(<x>)
   #xtranslate hb_HEVAL([<x,...>])         => HEVAL(<x>)
   #xtranslate hb_HSCAN([<x,...>])         => HSCAN(<x>)
   #xtranslate hb_HSETCASEMATCH([<x,...>]) => HSETCASEMATCH(<x>)
   #xtranslate hb_HCASEMATCH([<x,...>])    => HGETCASEMATCH(<x>)
   #xtranslate hb_HSETAUTOADD([<x,...>])   => HSETAUTOADD(<x>)
   #xtranslate hb_HAUTOADD([<x,...>])      => HGETAUTOADD(<x>)
   #xtranslate hb_HALLOCATE([<x,...>])     => HALLOCATE(<x>)
   #xtranslate hb_HDEFAULT([<x,...>])      => HDEFAULT(<x>)

jeudi 20 septembre 2012

Environnement de developpement graphique + basic sous Ubuntu

C'est en prenant des renseignement sur Laurux (logiciel comptable OpenSource) que je découvre Gambas.

Gambas est un environnement de développement graphique en Basic supporté par les librairies Graphique Qt réputée pour sa grande qualité.



Ressource:

Backup d'une DB PostGreSql Windows avec PgAgent

Cet article présente toutes les étapes de mon périple pour exécuter un backup pg_dump avec pgAgent... y compris celles permettant la résolution des différents problèmes.

Je précise quand même que le backup pg_dump + pgAgent sur Windows Serveur 2008 est fonctionnel ;-)

Ce billet est rédigé en étapes... toutes les étapes par lesquelles je suis passé (dans l'ordre de lecture).
Qui sait, il sera peut être source d'inspiration si un jour vous en avez besoin.

Installation
J'utilise PostgreSQL 9.1, par conséquent, l'installation est des plus simple.
Il suffit d'utiliser l'utilitaire "StackBuilder" de PostgreSql et de selectionner l'utilitaire pgAgent

Commande pg_dump
Commencer par faire fonctionner une tâche de backup en utilisant l'instruction pg_dump
Ensuite, faite le nécessaire pour l'appeler depuis une ligne de commande sur le serveur.
Dans mon cas, j'obtiens la commande batch suivante:

"c:\Program Files\PostgreSQL\9.1\bin\pg_dump.exe" --no-password --host localhost --port 5432 --username "postgres" --role "postgres"  --format tar --blobs --encoding UTF8 --oids --verbose --file "d:\GGBackup\Serveur\StockProd.backup" "stockprod"

La commande pg_dump peut être obtenu à l'aide de l'utilitaire backup de pgAdmin III (qui indique la commande pg_dump à utiliser).
Voir l'article " PostgreSql - Backup et restaure d'une base de donnée" pour plus d'information.

Configuration d'un Job
La fin de l'article "Setting up pgAgent and schedule backup job" de PostGresOnline.com.
Il faut bien entendu stipuler une tâche de type BATCH pour pouvoir exécuter une commande DOS.

Service pgAgent
J'ai quand même eu quelques problèmes pour faire fonctionner mon Job de backup.
Le pire, c'est quand il reste dans l'état "running" alors que le job ne fonctionne visiblement pas.
Savoir qu'il y a un service Windows et pouvoir le démarrer et l'arrêter est une information utile pour gérer l'inattendu.

net stop pgAgent
net start pgAgent

Information utile trouvé sur cet article de Vibhor Kumar

Malheureusement, ma première tâche de backup ne cesse m'indiquer le message "failed" à chaque fois que j'essaye de l'exécuter.

J'ai donc créé une simple tâche qui fait une requête SQL dans une table.
Cette requête est "select * from FILE0050 LIMIT 12".
Malheureusement, cette tâche aussi ne retourne que des erreurs. Le problème est probablement la configuration du service!

pgAgent en mode DEBUG
En cas de problèmes, l'un des options est de démarrer le service en mode DEBUG.


net stop pgAgent


Localiser l'exécutable (qui se trouve en C:\Program Files (x86)\pgAgent\bin sur un système 64 bits).
Exécuter ensuite:


pgAgent.exe DEBUG hostaddr=127.0.0.1 dbname=postgres user=postgres password=xxx


Où xxx est le mot de passe que vous utilisez pour vous connecter sur la DB avec pgAdmin III.
User contient l'identification de l'utilisateur PostgreSql. Attention, il est sensible à la case. Dans mon premier essais j'ai utilisé user=Postgres alors que ma connexion avec pgAdmin III utilise postgres.

Si le nom d'utilisateur (ou mot de passe) est incorrect, vous obtenez un message du genre...
WARNING: Couldn't create the primary connection (attempt 1): FATAL:  authentification par mot de passe ÚchouÚe pour l'utilisateur  ½ Postgres ╗

pgAgent avec log DEBUG

Pour obtenir plus de message de log, il faut ajouter l'option -l 2 .
Cela donne la commande suivante:

pgAgent.exe DEBUG hostaddr=127.0.0.1 dbname=postgres user=postgres password=xxx -l 2

L'exécution en Mode Debug m'apprend que mon Job sql est exécuté mais n'indique pas pourquoi il continue à échouer!

Source de l'information:
  • L'article pgAgent sur Let's Prosgres
Le "Host Agent" du Job
Il semblerait que le paramètre "Host Agent" du job soit vraiment important.
Toujours en suivant les recommandation de l'article pgAgent, j'ai éxécuté la requête suivante sur le serveur.
Une info en provenance de PostgreSql.fr laisse à penser que cela n'est pas forcement utile (voir ce lien).

SELECT jagstation FROM pgagent.pga_jobagent;


pour apprendre que Host Agent devrait valoir exactement:
SERVEUR.home


Une fois le Job modifié et relancé, ma petite tâche SQL continue à échouer... sans plus d'information Arrghhh!?!?


Obtenir les messages d'outputs
Lorsqu'un JOB est exécuté, il est possible de retrouver le message d'output  d'un Step d'exéction du JOB.
En cas d'erreur, cet output peut devenir vraiment très utile.
Pour l'obtenir:
  1. Sélectionner le Step dans le Job
  2. Sélectionner le volet Statistique
  3. Chercher la colonne Output.
Il est également possible d'obtenir la liste des messages d'output exécutés par le l'Agent

SELECT jslid, jsloutput from pgagent.pga_jobsteplog WHERE jslstatus != 's' AND jsloutput != '' ORDER BY jslstart DESC; 

Attention: il faut copier coller le résultat dans notepad pour vraiment voir le message (la cellule est quelques-fois vide dans pgAdmin... pourtant elle contient quelque-chose :-) ).

Ma tâche SQL - toujours en failed mais exécutée!!!
En y regardant de plus près, les statistiques du step (commande SQL) sont à failed mais retourne un "result" de 12.
C'est bien le nombre d'enregistrement retourner par la requête.
La requête est donc bien exécutée... mais est interprétée comme "failed" pour une raison que j'ignore.


En replaçant ma requête sql avec 
   SELECT "HELLO"
le result de la statistique indique "1" (une row).

Le problème est donc ailleurs que dans l'exécution... c'est déjà une bonne nouvelle.

Retour sur ma tâche de backup
La tâche était donc définie comme
"c:\Program Files\PostgreSQL\9.1\bin\pg_dump.exe" --no-password --host localhost --port 5432 --username "postgres" --role "postgres"  --format tar --blobs --encoding UTF8 --oids --verbose --file "d:\GGBackup\Serveur\StockProd.backup" "stockprod"

De l'expérience juste acquise, je peux consulter l'output.
Je note le message d'erreur suivant:

"
C:\Program Files (x86)\pgAgent\bin>"c:\Program Files\PostgreSQL\9.1\bin\pg_dump.exe" --no-password --host localhost --port 5432 --username "postgres" --role "postgres"  --format tar --blobs --encoding UTF8 --oids --verbose --file "d:\GGBackup\Serveur\StockProd.backup" "stockprod"
pg_dump: [programme d'archivage (db)] la connexion à la base de données « stockprod » a échoué : fe_sendauth: no password supplied
pg_dump: *** interrompu du fait d'erreurs
"


C'est donc un problème de mot de passe... pourtant pg_dump.exe n'accepte pas de mot de passe en ligne de commande. Il faut donc absolument l'option --no-password sinon la tâche restera en cours d'exécution (en demandant un mot de passe qui ne peu pas être encoder puisque la session n'est pas interactive!).

Astuce:
L'erreur est plus facile à repérer en utilisant le SQL


SELECT jslid, jsloutput from pgagent.pga_jobsteplog WHERE jslstatus != 's' AND jsloutput != '' ORDER BY jslstart DESC; 

Et en copiant/collant le résultat des cellule (apparemment vide mais pas tellement que cela) dans notepad ;-)

Un password pour mon pg_dump
En se référant à l'article "The password file" de PostgreSql, j'apprends que le fichier pgpass.conf doit se trouver dans le répertoire %APPDATA%\postgresql\pgpass.conf
En vérifiant sur mon Windows Serveur 2008, je trouve le fichier pgpass.conf de l'administrateur dans le répertoire de Roaming.
c:\Users\Administrateur\AppData\Roaming\postgresql\pgpass.conf

Je vais commencer par modifier ce pgpass.conf car je fais des tests en mode DEBUG... et donc avec l'utilisateur interactif qui n'est autre que Administrateur!

Le fichier pgpass.conf d'Administrateur est modifier pour contenir une ligne pour ma DB stockprod.
Ce fichier devient donc:

localhost:5432:postgres:postgres:SECRET
localhost:5432:stockprod:postgres:SECRET

Ensuite, je fais un essai en ligne de commande avec:
"c:\Program Files\PostgreSQL\9.1\bin\pg_dump.exe" --no-password --host localhost --port 5432 --username "postgres" --role "postgres"  --format tar --blobs --encoding UTF8 --oids --verbose --file "d:\GGBackup\Serveur\StockProd.backup" "stockprod"
 
et cette fois, le pg_dump s'exécute immédiatement!

Tester la tâche pg_dump avec pgAgent en DEBUG
Finalement, un dernier essai avec pgAgent en mode DEBUG.
Je démarre le pgAgent en mode DEBUG avec l'instruction:
pgAgent.exe DEBUG hostaddr=127.0.0.1 dbname=postgres user=postgres password=SECRET -l 2

Cette session s'exécute en mode interactif et utilisera donc le pgpass.conf de le l'utilisateur Administrateur.
En utilisant pgAdmin III, on redemande l'exécution de la tâche de Backup.
Cette fois aussi la tâche fonctionne, le backup est créé... même si la tâche est indiquée "failed" (mon pgAgent est certainement en pleine crise d'opposition :-) )

pgpass.conf pour le service pgAgent
Le service pgAgent ne fonctionne pas avec le crédential de l'utilisateur Administrateur mais avec celui de son propre utilisateur Windows. Cet utilisateur qui ne nomme normalement "postgres".
Il faut donc créer le fichier avec un contenu identique (voir ci-dessus).

c:\Users\postgres\AppData\Roaming\postgresql\pgpass.conf 

Un essai avec pgAgent
J'arrête mon pgAgent en mode DEBUG pour ensuite démarrer mon service pgAgent à l'aide de 
NET START pgAgent 
Le service est normalement configuré correctement avec l'utilisateur Windows "postgres", celui utilisé durant l'installation avec StackBuilder.

En utilisant pgAdmin III, on redemande l'exécution de la tâche de Backup.
Cette fois-ci, cette tâche sera exécutée par le service pgAgent.
Maintenant, la tâche de backup fonctionne correctement   YES!!!

Ressources
Proposition d'installation du Service
Au détour de mes lecture, j'ai trouver une instruction d'installation du service pgAgent
“C:\Program Files\PostgreSQL\8.2\bin\pgAgent" INSTALL pgAgent –l 2 -u postgres -p XXXX hostaddr=127.0.0.1 dbname=postgres user=Postgres

Un fichier backup par jour
J'ai aussi trouvé cet autre batch qui crée un fichier de backup différent chaque jour.
Bonne idée que j'exploiterais plus tard.
    @echo off
   for /f "tokens=1-4 delims=/ " %%i in ("%date%") do (
     set dow=%%i
     set month=%%j
     set day=%%k
     set year=%%l
   )
   set datestr=%month%_%day%_%year%
   echo datestr is %datestr%
    
   set BACKUP_FILE=<NameOfTheFile>_%datestr%.backup
   echo backup file name is %BACKUP_FILE%
   SET PGPASSWORD=<PassWord>
   echo on
   bin\pg_dump -i -h <HostName> -p 5432 -U <UserName> -F c -b -v -f %BACKUP_FILE% <DATABASENAME>

Source: Automated Backup on Windows sur le woki de postgresql.org 

Output message d'un JOB
Voici une petite requête SQL permettant d'obtenir les messages d'output d'un Job pgAgent.
Merci à rjuju (sur forums.postgresql.fr).

SELECT jsloutput
FROM pgagent.pga_job j
JOIN pgagent.pga_jobstep js ON jstjobid = jobid
JOIN pgagent.pga_jobsteplog jsl ON jsljstid = jstid
WHERE jobname = 'Test'

jeudi 13 septembre 2012

Informations métriques sur une DB PostgreSql

Voici comment obtenir toute une série d'information utile concernant une ou plusieurs bases de donnée installée sur un serveur PostgreSql

Taille des DB
Taille de toutes les bases de données sur le serveur
select datname,pg_database_size(datname) from pg_database
mais aussi l'espace utilisé par les bases de données
select sum(pg_database_size(datname)) from pg_database

Les tables
Nbre de tables dans une DB
Cette requête est idéale pour évaluer la complexité d'une base de données
select count(*) as TableCount 
from information_schema.tables 
where table_schema not in ('information_schema', 'pg_catalog')

Lister les tables d'une DB
select table_schema, table_name 
from information_schema.tables 
where table_schema not in ('information_schema', 'pg_catalog')

Taille des tables d'une DB
select table_schema, table_name, pg_relation_size('"'||table_name||'"')
from information_schema.tables 
where table_schema not in ('information_schema', 'pg_catalog')

Pourquoi la notation bizarre '"'||table_name||'"' ?
Hé bien parce que j'ai eu la malheur de définir une table avec un lettre capitale (Counters).
Ainsi, l'instruction select pg_relation_size('Counters') m'indique que la table counters n'existe pas.
Par contre, l'intruction select pg_relation_size('"Counters"') retourne le résultat attendu.

Voici une petite version améliorée qui affiche la taille en Ko
select table_schema, table_name, pg_relation_size('"'||table_name||'"')/1024 as Table_size_Kb
from information_schema.tables 
where table_schema not in ('information_schema', 'pg_catalog')

jeudi 6 septembre 2012

PostgreSql - Backup et restaure d'une base de donnée

Voici quelques références relatifs au opérations de backup et restore d'une base de donnée PostgreSql.

Impossible de restaurer un backup créé avec with pgAdmin III

J'ai créé un fichier de backup en utilisant pgAdmin III, mais quand j'ai voulu le restaurer (restore), le bouton OK restait grisé.
pgAdmin III utilise l'outil PostgreSQL nommé pg_restore, ce dernier supporte seulement les formats compressés (COMRESS) et les archives (TAR). Le backup fait avec pg_dump (ou l'interface pgAdmin III doit donc utiliser ces options. Un fichier de backup compressé est alors accepté sans problème par pgAdmin (et le bouton est dégrisé).

Note: le format PLAIN ne peut pas être interprété par pgAdmin III et pg_restore (il peut être édité manuellement et exécuté avec l'outil SQL de pgAdmin III), c'est la raison pour laquelle il n'est pas accepté comme un fichier valide.

Je recommande l'utilisation du format COMPRESS pour les backups journaliers. Le format PLAIN est réservé à aux modifications manuelle avant exécution du SCRIPT. Le format PLAIN à d'ailleurs quelques restrictions (pas les blobs) qui rend se format moins utile pour les tâches de backup standard.

Création du backup
Notez l'encodage en UTF8 (plus répandu).

J'ai activé les OIDs pour avoir les clés numérotés
 Ce backup correspond à la commande sql suivante:

C:/Program Files/PostgreSQL/9.1/bin\pg_dump.exe --host localhost --port 5432 --username "postgres" --role "postgres" --no-password  --format tar --blobs --encoding UTF8 --oids --verbose --file "c:\temp\stockdev.backup" "stockdev"

Restaurer le backup
Le plus simplement du monde, je me suis rendu sur l'autre serveur. J'ai effacé et recréé une DB vide.
Ensuite, j'ai utilisé l'outil de restauration de pgAdminIII avec mon fichier de backup (sans changer aucune option).
Résultat: Nickel !

Ressources

lundi 3 septembre 2012

Pour nos enfants handicapés/différents, A la TEC et à nos ministres je crie mon INDIGNATION

Vous qui passez par là, prenez le temps de lire et de relayer cette information car l'histoire quelle contient est vraie... c'est la notre!

Je vous présente Benjamin
Mon fils Benjamin à 11 ans, issus d'un premier mariage, il est différent... assez pour se faire traiter de Mongole quand il va  au stages normaux durant les vacances.
Pas fortement atteint, les gens ne regardent pas ailleurs quand ils le croise! N'empêche dans sa tête, il est plus proches des huit ans, il additionne difficilement au delà de 10 et a accumulé un retard scolaire conséquent (il est en "2 et 1/2" année primaire pour vous aider à situer ce retard).
Nous avons une chance inouï, j'ai réussi à lui apprendre à lire mais cela ne suffit pas a combler son inconscience et, il faut l'avouer, il reste un peu dans sa bulle.
Malgré nos efforts de structuration, mon fils reste aussi différent d'un point de vue caractériel. Il oscille entre type 8 (retard d'apprentissage) et type 3 (caractériel)... mais c'est le type 8 qui le caractérise administrativement.
Finalement, un point important à ajouter dans ce billet, Benjamin reste atteint d'un trouble psychomoteur important pour vivre en société... il a du mal à se repérer dans le temps et dans l'espace.
Benjamin est donc en enseignement spécial dans une école de Court-Saint-Etienn.
Comme elle est située à 20 minutes de routes (au minimum), c'est la TEC qui prends gratuitement ce déplacement en charge.

Notre cadre de vie
Une semaine sur deux, Benjamin vis avec sa soeur et ses deux demi-frères/soeur en garde alternée.
Pour assumer toutes ces bouches, ma femme et moi travaillons à temps plein. Mon horaire se termine à 18h00 dans mon cas et celui de ma femme à 17h00. Et forcement, nous n'avons pas la chance de travailler tous les deux à "deux pas" de la maison.
Le prix des assurances et de l'essence ne nous permet plus d'avoir deux véhicules. Nous nous débrouillons donc avec une seule voiture.
Qu'elle foire d'empoigne pour satisfaire à nos déplacements, nos employeurs et les exigences de la vie de famille (nous vivons à 6 sous le toit). Quel Rodéo épuisant et pourtant nous nous efforçons de faire au mieux.

La prise en charge du TEC
Le transport de Benjamin, souffrant de son handicap, est prit en charge par la TEC. Mais depuis la première année, nous devons faire face a une forme de mauvais vouloir de la part de cette administration qui essaye sans cesse de comprimer leurs budgets.
Paraît-il que c'est a cause de nos ministres... bien commode de se laver les mains de la sorte.

Donc, chaque année, la rentrée de Septembre est un moment de tension où il faut s'assurer que Benjamin soit bien déposé au pas de la porte (il souffre de problèmes d'orientation et temporel) et nous avons toujours fait au mieux pour qu'il y ait quelqu'un pour l’accueillir.
A ce sujet, je remercie mon beau fils de 14 ans qui coopère beaucoup pour nous aider... à son age, beaucoup d'autres Ado font/impose autre chose quand à l'occupation de leur horaire. Merci Didi!

Mais arranger ce dépôt ne se passe pas sans mal. Nous contactons la TEC (je meurs d'envie de mettre des nom!!!) mais aussi l'école réintroduire un dossier pour que le cas de Benjamin soit correctement prit en compte.
L'année dernière c'est à la gare que l'on voulait déposer mon fils!!!! Un enfant retardé (même légèrement)... inconscient.... et ayant des troubles de l'orientation.
Situation inacceptable à laquelle nous avons échappé de peu... Benjamin ayant encore été déposé chez nous. Et à nous de nous organiser pour le recevoir à des horaires où nous ne savons pas être disponible car "il nous faut bosser pour gagner notre croûte".

Prise en otage pernicieuse
Durant les deux mois de vacances, nous avons reçu un courrier nous indiquant que l'enlèvement se ferait à un autre arrêt de bus.
Pour nous, pas de problème... le plus important étant le retour chez nous... celui que nous avons déjà tant de mal à organiser correctement (pour maintenir un bon cadre de vie... dans les meilleures conditions).
Rien à propos du dépôt donc pas de quoi d’inquiété même si l'on reste échaudé du coup du "dépôt à la gare" de l'année dernière.

Par contre, ce matin, à l’enlèvement, nous avons appris que le dépôt à la maison c'est fini.
Ce sera vers 16h30 à la gare!!!! ça y est, la TEC remet encore cela!!!.
Et lorsque nous contactons la TEC, nous apprenons que le dossier mentionne déjà un dépôt à la gare toute l'année précédente... et donc, difficile pour nous de faire valoir notre bonne foi puisque les éléments en possession de la TEC sont en contradiction avec la réalité. Pratique non?!?!
Paraît-il d'ailleurs que les Type 8 sont maintenant délesté sur des lignes de BUS normal (La TEC affirmant officieusement que c'est l'oeuvre de notre ministre de tutelle... pas de chance pour nous... nous n'avons plus le temps de regarder la télévision depuis longtemps.).
J'ai un peu de mal à accepter cette argumentation en contradiction avec la nécessité social du service!

Pas la gare s'il vous plait!
En ce matin, nous nous battons pour que le lieu de dépôt ne soit pas une gare mais à l'arrêt de bus d'enlèvement, il se trouve à un kilomètre de chez nous.
Ce dernier kilomètre, mon fils devra apprendre à le faire seul, dans la bonne direction et en faisant attention à ne pas se faire renverser... et à ne pas être distrait en traversant.
Le retard apprentissage s'accompagne souvent de trouble de l'attention. Si la Rilatine l'aide, il est des heures où elles ne fait plus effet... comme la fin d'après-midi!!!

Malheureusement pour nous, mon beau fils n'a pas toujours terminé à 16h00 pour aller le chercher à l'arrêt de bus...et nous... et bien nous travaillons pour payer nos impôts, notre maison, notre croûte, etc!
 
Proposition à nos ministres concernés - Emploi, Enseignement et transport - : la solution la plus simple serait peut être encore que je sois chômeur complet indemnisé, en tant que chef de ménage... ce serait peut être plus simple pour tout le monde "non"? Au moins j'aurais le temps d'être là à l'heure imposée, à l'endroit imposé pour prendre mon enfant en charge... au lieu de me crever comme un imbécile 8 heures par jours pour soutenir le système social et me retrouver année après année des situations aussi absurdes que celle-ci! 

La colère et l'indignation
Je suis fâche (les mots qui me passent pas la tête sont... inappropriés). Que me reste t'il d'autre que cela!
Même les animaux sont traités avec plus d'égard. 
Sommes nous donc devenu une sous classe de la société... du genre Cafard que l'on peut écrasé sans autre chose qu'un petit "haut le coeur"?

Ces Messieurs et Mesdames de la TEC, ces Messieurs et Mesdames de la politique, je suis écœuré... et c'est peu dire.

Notre cas, et bien, ce n'est pas grand chose dans notre société de plus de 10 millions d'habitants.
Et nos enfants différents sont une charge pour la société... pour nos politiciens... et pour la TEC.

Et les cas difficiles, tout le monde le sait, c'est mieux de s'en débarrasser vite fait...
La TEC s'y emploi d'ailleurs très bien... année après année... à user administrativement ces parents déjà fatigués par une vie déjà "plus compliquée".
Etes-vous seulement humains?

La vie est déjà bien difficile comme ça. Avec un enfant en handicap (même léger comme mon fils) c'est encore plus difficile. Pas question de simplement rentrer le soir, souper et passer une vie de famille en toute simplicité.
Pourquoi faut-il donc que cela soit rendu encore plus compliqué? Pourquoi charger les affaiblis? Pourquoi cette administration "destructrice" (elle nous nous enfonce dans nos difficultés au lieu de nous aider et nous guider) ?

Et tout ces autres parents
J'ai une pensée pour ces parents, qui comme nous, ont un enfant différent, que l'on menace de déposer dans la nature avec pour seul message "Débrouiller vous parents!".
Le kilomètre que mon fils devra apprendre à parcourir à pied (si on nous le dépose à l'arrêt demandé!), en toute sécurité, sera un vrai challenge pour lui. Pour nous ce sera une inquiétude mordante chaque jours entre 16h30 et 18h00 (le temps que nous rentrions constater sa "survie" après notre travail).

Et dire que notre cas est encore "soft". Je suis certain que de nombreux autres parents sont aussi démunis que nous ce 3 septembre 2012... certains d'entre eux avec des cas et des situations encore plus dramatiques.

Qu'elle est belle ma société...
Qu'ils sont bons à la TEC...
Qu'ils sont bien nos ministres...
    Vous l'aurez compris, c'est l'humour mordant.
    Je suis fatigué de me battre...

jeudi 30 août 2012

Clipper: Creer un GUID

J'avais besoin de créer un GUID à partir de Clipper.
J'ai mis un certain temps à trouver l'exemple \contrib\hbwin\tests\testrpc.prg

#include "simpleio.ch"

PROCEDURE Main()
/*
 * Harbour Project source code:
 *
 * Copyright 2010 Viktor Szakats (harbour.01 syenar.hu)
 * www - http://harbour-project.org
 *
 */

    ? win_UuidCreateString()

    RETURN

dimanche 26 août 2012

Comptabilité sous Linux

Introduction
MC Hobby grandit... et le besoin en comptabilité aussi!
Maintenir la comptabilité sur Calc d'Open Office commence à devenir un vrai challenge.
En effet, la quantité d'information devient vraiment très importante et OpenOffice Calc présente ses limites non pas sur la quantité d'information mais sur l'interface graphique permettant d'y accéder... la vue sous forme de tableau à aussi ses contrainte... et donc ses limites.
Nous partons donc à la recherche d'une vrai solution comptable fonctionnant sous Ubuntu... pour rappel, MC Hobby est encore entièrement "Open-Source".  

La solution pour MC Hobby
Besoins de MC Hobby
Le logiciel sélectionné doit répondre à nos besoins... mais les besoins de MC Hobby ne sont bien entendu pas ceux d'une PME de taille moyenne. C'est une précision importante que vous devez connaître si vous désirez vous inspirez de notre expérience.

Le logiciel doit répondre à nos besoins comptables et gestion de stock et eventuellement facturation (notre facturation client est prise en charge par notre WebShop www.mchobby.be).
MC Hobby est une petite société de deux personnes avec activité à temps partiel.

Logiciel sélectionné par MC Hobby 
Pour le moment, nous évaluons les différentes options (moi et mon épouse qui est "comptable").
Dès que celle-ci sera fixée, nous compléterons cette section avec notre choix.

Etat du marché des soft de comptabilité
Une petite recherche sur le NET m'indique qu'une option sous Ubuntu n'est pas si désespérée que cela.

Groupe de travail Comptabilité de l'APRIL
Pour commencer, j'aimerai mentionner le groupe de travail de l'April relatif à la gestion de la comptabilité en Open-Source.

http://wiki.april.org/w/Comptabilite

Il présente déjà un certain nombre d'options dont phpCompta (http://www.phpcompta.eu/) disponible en live démo. (user=demo , password=demo)

CommentCaMarche.Net
Ce fil de discussion relatif aux logiciel comptable sous Linux est également une source d'information intéressante.

Le commentaire  ci-dessous me laisse a penser que Laurux est un outil a tester. Il est d'ailleurs repris dans la liste des softs de l'APRIL (mentionné ci-dessus)

"Sans hésiter après avoir TOUT passé en revu:: http://www.laurux.fr/"


LinuxFR.org
L'article "Commercial Comptabilité sous linux... état des lieux" reprend également quelques références.
C'est en fait ma toute première source d'information.

Parmi les différents liens, j'ai trouvé Eurogiciel (Free Gica), en jetant un coup d'oeil sur le site, je suis tombé sur une news relative à InterVat et une mise-à-jour du logiciel pour supporter les modifications de format. Information très intéressante pour un Belge, cela signifiant sur le fond que le logiciel Gica pourrait fort bien convenir pour notre comptabilité 

jeudi 23 août 2012

QR-Code - IPad Mobile tag - Unitag.fr et QL-570

Introduction
Cet article va se concentrer sur la production de QR-Code (QRCode) sur une imprimante Brother QL-570.
Cela est possible à l'aide du soft & SDK P-Touch mais demande un minimum de formalisme.

Logiciel P-Touch pour QL-570
Le programme gratuit P-Touch editor de Brother permet de faire le design d'étiquette incluant un code barre.
Par la suite, il sera possible d'utiliser le SDK pour modifier le contenu du QR-Code (voir autre article).
Parmi les code barre supporté, j'ai déjà aborder le EAN128 (voir autre article) mais il est aussi possible de concevoir des QR-Code.

Lire le QR-Code
Sur IPad, il existe l'application "MobileTag" qui permet de lire des QR Code.
Il est également possible de générer des QR-Code depuis Internet depuis le site www.unitag.fr (référence exceptionnelle) très bien pour faire des premier tests de MobileTag.
Je constate assez vite qu'il est possible de produire des tags de type URL et adresse e-mail.
Testé avec la combinaison unitag.fr + MobileTag, un Tag URL fonctionne immédiatement.
Par contre, mon premier QR-Code avec adresse e-mail produit depuis P-Touch ne fonctionne pas comme attendu (snif).

Encoder un QR-Code
Après quelques recherches, j'ai trouvé cette excellente référence sur Google Code.
Comment encoder du contenu (e-mail, url, etc)

P-Touch QR-Code
Pour encoder un QR de type URL:
Simplement taper l'URL en la faisant précéder du protocole "http://". J'ai utiliser le code de contrôle LF en fin d'URL (il suffit de taper la touche [enter] en fin d'URL).
Ce qui produit:

Pour encoder un e-mail:
Se fait à l'aide de la structure:
MAILTO:email@ledomaine.be?subject=test&body=letexte

Malheureusement, je ne suis pas arrivé à obtenir un résultat intéressant même en produisant le tag depuis unitag.fr.

Ressources

mercredi 22 août 2012

Clipper: Comment imprimer un Code barre avec une imprimante HP

Introduction
Nous disposons d'un vieux soft Clipper que j'ai migré en multi-poste sur une DB PostGreSql.
A peine croyable, grâce à Mediator et aux projets Open-Sources Harbour et PostGreSql, ce logiciel connait une seconde vie.

Nous imprimons nos notes d'envoi sur une imprimante HP (LasetJet P2055), ce qui permet de faire quelques formatages en utilisant le language PCL toujours supporté en 2012 :-)

L'étape suivante consiste à imprimer un Code barre sur la note d'envoi pour automatiser le processus de préparation et suivit de Colis.
Figurez-vous que grâce à PCL, cela est possible, sous Clipper SANS UTILISER DE CARTE MEMOIRE IMPRIMANTE stockant les fonts.

J'ai trouver un très vieux code sur OASIS permettant de générer du BarCode39 en PCL.
Cela est bien suffisant pour de nombreux cas d'utilisation et lisible par de nombreux scanner!

Après quelques modifications du programme et l'écriture de compile.bat (pour compiler sous Harbour + Visual Studio 2008), j'ai réussi à générer le PCL correspondant au BarCode dans un fichier grâce à l'instruction SET ALTERNATE... voir le contenu du fichier BarCodeHPFile.txt

Quelques-manipulation à l'aide de PSPAD (qui supporte le mode binaire) m'aura permi d'intégrer le code barre à l'endroit approprié d'une note d'envoi... Hé HOP... imprimé :-)
Avec l'aimable autorisation de
la société Guy Gerard SPRL

Code Source
J'ai reconstitué une archive avec le code source modifié.
C'est un peu brouillon car toujours à l'état de prototype mais cela compile et fonctionne parfaitement.
Le code génère une fichier BarCodeHPFile.txt contenant le PCL code pour le code barre (intégré dans l'image ci-dessus) :-)

Le code source: BarCode39HpPcl.zip

Compile.bat permet de compiler le programme avec Harbour-Project (version 30) et utilise Visual Studio Express 2008.
Il faut absolument démarrer la compilation "compile.bat" depuis un "prompt visual studio 2008" (Start Menu | Programmes | Visual Studio 2008 Express edition | utilities ... ou quelque-chose de très similaire)

PSPad (encore Open-Source) est un outil pratique vous permettant de visualiser facilement le contenu du fichier généré... il support un affichage de fichier Binaire ainsi que les opérations de copier/couper/coller bien nécessaire  pour faire ce type de prototypage :-)

Crédits
  • Merci à Bill Wood  Milwaukee pour le code en VB, 1985
  • Merci à George T. Neill pour la source Clipper (portage)... probablement en 1989
Comme quoi, même du code écrit en 1985 peut toujours être exploité 2012

jeudi 9 août 2012

Clipper: fonctions de traitement des dates

Rien de tel qu'une bonne référence.... voici une liste des fonctions permettant de traiter les dates en Clipper (et Harbour).

TRUE || FALSE       BETWEEN(<TargetData>, <FirstData>, <SecondData>)
cDayName            CDOW(<dExp>)
cMonth              CMONTH(<dDate>)
dDate               CTOD(<cDate>)
dSystem             DATE()
nDay                DAY(<dDate>)
nDay                DOW(<dDate>)
cDate               DTOC(<dDate>)
cDate               DTOS(<dDate>)
lEmpty              EMPTY(<exp>)
dDate               FT_ACCTADJ( [ <dGivenDate> ], [ <lIsEnd> ] )
aDateInfo           FT_ACCTMONTH( [ <dGivenDate> ], [ <nMonthNum> ] )
aDateinfo           FT_ACCTQTR( [ <dGivenDate> ], [ <nQtrNum> ] )
aDateInfo           FT_ACCTWEEK( [ <dGivenDate> ], [ <nWeekNum> ] )
aDateInfo           FT_ACCTYEAR( [ <dGivenDate> ] )
nTrueDays           FT_ADDWKDY( <dStart>, <nWorkDays> )
aRetVal             FT_CALENDAR ( [ <nRow> ], [ <nCol> ], [ <cColor> ], [ <lShadow> ] , [ <lShowHelp> ] )
cMILTIME            FT_CIV2MIL( <cCIVTIME> )
aDateInfo           FT_DATECNFG( [ <cFYStart> ], [ <nDow> ] )
aDateInfo           FT_DAYOFYR( [ <dGivenDate> ], [ <nDayNum> ], [ <lIsAcct> ] )
nDays               FT_DAYTOBOW( [ <dGivenDate> ] )
<nResult>           FT_DOY( <dDate> )
dEdate              FT_EASTER( <xYear> )
nMINUTES            FT_ELAPMIN( <cTIME1>, <cTIME2> )
aTimedata           FT_ELAPSED([ <dStart> ], [ <dEnd> ], ; <cTimeStart>, <cTimeEnd>)
cDiff               FT_ELTIME( <cTime1>, <cTime2> )
dFirstDay           FT_FDAY( [ <dDateToChk> ] )
dLastDay            FT_LDAY( [ <dDateToChk> ] )
dDate               FT_MADD( [ <dGivenDate> ], [ <nAddMonths> ], [ <lMakeEOM> ] )
dMILTIME            FT_MIL2CIV( <cCIVTIME> )
nMINUTE             FT_MIL2MIN( <cMILTIME> )
aDHM_               FT_MIN2DHM( <nMinutes> )
cMILTIME            FT_MIN2MIL( <nMINUTE> )
aDateInfo           FT_MONTH( [ <dGivenDate> ], [nMonthNum] )
aDateInfo           FT_QTR( [ <dGivenDate> ], [ <nQtrNum> ] )
cMILTIME            FT_SYS2MIL()
aDateinfo           FT_WEEK( [ <dGivenDate> ], [ <nWeekNum> ] )
nDays               FT_WORKDAYS( [ <dStart> ], [ <dStop> ] )
<nResult>           FT_WOY( <dDate> )
aDateInfo           FT_YEAR( [ <dGivenDate> ] )
dLarger             MAX(<nExp1>, <nExp2>) --> nLarger MAX(<dExp1>, <dExp2>)
dSmaller            MIN(<nExp1>, <nExp2>) --> nSmaller MIN(<dExp1>, <dExp2>)
nMonth              MONTH(<dDate>)
NIL                 QOUT([<exp list>]) --> NIL QQOUT([<exp list>])
nSeconds            SECONDS()
NIL                 SLEEP(<nSec>)
cTimeString         TIME()
cFormatString       TRANSFORM(<exp>, <cSayPicture>)
cType               TYPE(<cExp>)
cType               VALTYPE(<exp>)
nYear               YEAR(<dDate>)

samedi 28 juillet 2012

Engagement et implication au travail - Modèle en X employés-employeur

Il y a longtemps, j'ai écrit un article sur "Engagement et Implication".
L'engagement et l'implication sont des éléments clés de théorie de management Scrumm.
Beaucoup d'employés se sentent impliqués (voire engagés) dans leur travail... mais le management adéquat n'est que trop rarement au rendez-vous pour soutenir un engagement.
C'est ainsi que l'on retrouve des situations de Burn Out dramatiques.

Justement, dans un cas de Burn Out, le management a souvent (trop trop souvent) tendance à se voiler la face et à considérer qu'il n'est pas responsable... ni à l'origine de l'état de l'employé.

Ainsi, pour ceux qui ne se sont pas encore fait d'idée sur la relation "employer-employer-satisfaction-burnout", je vous propose de prendre connaissance de la vidéo suivante qui présente le "modèle en X de l'engagement au travail".

Elle est vraiment bien faite, facile à suivre, agréable mais surtout très pertinente!
Vers la fin, cette vidéo présente également l'importance du rôle des managers et du management exécutif (ex: chef de service, superviseur de service, etc) dans ce modèle. Il est crucial pour maintenir les bonnes performances de la société et des employés.



A recommander!

samedi 21 juillet 2012

Indicateur Caps-Lock, Num-Lock pour Ubuntu 12.04

Les machines plus récentes ne disposent plus toujours d'indicateur Caps-Lock et Num-Lock.
Cela n'ennuie probablement pas le commun des mortels mais un comptable vis assez mal l'absence d'un Num-Lock.

Pour contourner le problème, il suffit d'installer des Indicateurs sous Ubuntu.

Je vous propose donc la lecture de l'article "10 Must Have Indicator Applets for Ubuntu 12.04".
Assez intéressant.

Dans le cas qui concerne ma comptable bien aimée, la solution se trouve dans le script suivant:
sudo add-apt-repository ppa:tsbarnes/indicator-keylock
sudo apt-get update
sudo apt-get install indicator-keylock

J'ai également trouvé quelques autres indicateurs sur cet article de noobslab.com.

lundi 9 juillet 2012

Erreur 601 à la signature d’une déclaration de TVA via InterVAT

J'ai une très grosse... GROSSE... GROSSE ENVIE DE POUSSER UN COUP DE G....!

J'utilise Firefox... et Intervat vient de me fournir un document dont la signature n'est plus reconnue (sur mon beau FireFox).
C'est incroyable, mon propre gouvernement m'impose une technologie dont il ne peut pas assurer la tenue dans le temps... (je parle de "l'expiration des certificats"... heureusement que VeriSign n'est pas aussi peu professionnel).
Dire que j'ai fait une mise-à-jour de mes certificats il y a quelques mois et ce n'est déjà plus valable!

Sur la forme... il n'y a qu'a mettre à jour les certificats Belgium-CA (ou quelque-chose comme ça).

La solution semble simple... si on a Windows et Acrobat Reader (cfr site Intervat).
C'est pas de chance, j'utilise Firefox et JE N'AI PAS WINDOWS!!!! j'utilise que des machines sous Ubuntu.
Je ne sais pas charger le fameux fichier "fdf" d'Acrobat permettant cette dite mise-à-jour facilement (facilement???).

Comment est-il possible que mon gouvernement m'impose de tel moyens de communication, de tels options technologiques AVEC DES SYSTEMES FERMES ? PS: pour ceux qui ne le savent pas, il n'est plus possible d'envoyer une déclaration TVA par simple formulaire papier.

  • C'est inacceptables d'avoir répudié la signature papier au profit d'une signature électronique. 
  • C'est inacceptable de ne pas produire de signature papier. 
  • C'est inacceptable d'avoir imposé la transmission informatique. 
  • C'est inacceptable d'imposer une option technologique! Moins fiable que le papier d'ailleurs!
Dites moi ces Messieurs et Mesdames de l'Etat, quand m'obligerez vous à acheter un IBrolbrol de N'Apple à 400 Eur pour encoder ma déclaration TVA parce que ce sera la seule possibilité supportée par Nain-tervat.

Si vous avez un problème de signature de document (signé par l'état), je vous propose les liens suivants:
NB:
Je suis sincèrement désolé pour ceux d'entre-vous que j'aurais heurté... mais j'ai du mal à rester de marbre quand la sacré-sainte-technologie entrave la productivité. A plus forte raison quand elle nous est imposée en guise de "cul de sac".