Cacher une cellule dans WebIntelligence pour un tri

Sous Deski on peut facilement cacher une cellule dans un tableau mais en gardant le tri sur ses valeurs. Cette option est très pratique quand on veut afficher des libellés liés à des codes obscurs, qui n’ont aucun intérêt à être affichés.

Par contre webi ne propose pas cette fonctionnalité. Le plus simple est alors de cacher la cellule en réduisant sa taille et en jouant sur les couleurs ( écriture blanche sur fond blanc ), un peu comme si on avait un tableau à l’encre invisible !!!
Mais cela reste artisanal …

Une astuce est de passer par les alerteurs.
Lire la suite

Les invites BO – part IV – Affichage détaillé des valeurs possibles

Lors de la saisie d’une invite, l’utilisateur peut aussi ( ou est obligé de ) sélectionner une valeur dans une liste prédéfinie. Cette dernière est définie soit par la liste de valeurs ( LOV ) d’un objet, soit par une énumération des différentes valeurs dans le paramètre approprié du @prompt() .
Le résultat reste assez basique, et il est légitime de vouloir une présentation plus sophistiquée pour :
– afficher un libellé explicite quand on doit saisir un code un peu obscur
– regrouper des valeurs quand on a une liste importante pour plus de lisibilité
Lire la suite

Les invites BO – part V – Utilisation avancée : Désactiver une invite

On l’a vu, les invites permettent d’avoir des états « paramétrables », ce qui permet de personnaliser les données en fonction des destinataires.

Par exemple on peut avoir un rapport donnant le chiffre d’affaire par région, avec le détail par magasin. Un rapport personnalisé est envoyé aux responsables de région, grâce à l’invite.

Mais en pratique on a aussi besoin d’un rapport global, qui donne les résultats de toutes les régions. Ce rapport serait envoyé à d’autres personnes. Mais la structure, le format resteraient les mêmes, on aurait la même requête mais sans l’invite.
Lire la suite

Des tables de faits sans faits

Il y a des expressions décisionnelles qui me donnent des boutons, limite la varicelle.

Par exemple, le fait qu’il existe des tables de faits sans faits
C’est un peu comme si on avait des moules sans frites, une bière sans mousse, un avion sans ailes, un film de Tim Burton sans Johnny Deep ou une version de BO sans bug …
Lire la suite

RoamBI sur iPhone et iPad

Il y a des fois où je regrette d’avoir pris un smartphone sous Android et non un iPhone …

Dommage, car il existe des applications que j’aurais bien voulu triturer dans tous les sens de l’écran tactile …
Comme RoamBi, avec ses rapports animés et glossy ( c’est sur, on est bien sur la planète pomme ), et qui existe en version lite ( et donc ) gratuite. Et en plus ils sont déjà sur iPad !

http://www.roambi.com/
J’aurais surement aimé plus particulièrement le Cardex, même si un défilement à la iTunes ne m’aurait pas déplu

Les invites BO – part III – Utilisation sous Designer

On a vu la définition des invites dans le rapport, mais on peut aussi les créer directement dans l’univers, pour pouvoir les utiliser dans les requêtes et pour assurer la cohérence des noms des invites du parc des documents d’entreprise.

La syntaxe est donnée comme d’habitude dans l’aide, mais on peut récupérer facilement la formule définitive en visualisant le sql généré dans l’éditeur de requête. Bizarrement les 2 clients donnent des résultats différents, deski génère un

@variable('Entrez une date :')

Alors que webi lui écrit un

@prompt('Entrez une date :','D',,Mono,Free,Persistent,,User:0)

Les 2 fonctions sont acceptées, mais il vaut mieux utiliser la fonction @prompt qui est plus restrictive et apporte plus d’options que @variable.

La syntaxe de @prompt est la suivante :

@Prompt('message','type',[{'value1'[,'value2',...]},class_nameobject_name'],mono/multi,free/constrained [,Persistent/Not_Persistent,[{'value1'[,'value2',...]} [, [User:#] [, Optional ]] ] )

Les paramètres sont :

  • message / libellé de l’invite
  • type de donnée : A=Alpha, D=Date, N=Numérique
  • valeurs affichées : on peut prendre celles d’un objet de l’univers ( LOV ) en donnant le nom complet de l’objet ou les lister en les enclosant entre accolades
  • mono/multi : mono si on ne peut prendre qu’une seule valeur, multi si on peut en prendre plusieurs ( pour l’opérateur « dans liste » )
  • free/constrained : free si l’utilisateur peut saisir ce qu’il veut, constrained s’il ne peut choisir que dans les valeurs affichées.

Les paramètres suivants ne sont pas documentés dans l’aide BO :

  • Persistent/Not_Persistent : Persistent garde la dernière valeur sélectionnée lors de l’affichage de l’invite, Not_Persistent non. Par défaut c’est Not_Persistent
  • Valeur par défaut : si ce paramètre est laissé à vide aucune valeur par défaut n’est utilisée, si on a plusieurs valeurs il faut les encadrer par des { } et séparer par des ,
    Attention, il faut que la valeur existe dans les valeurs affichées ( 3ème paramètre )
  • User:#: Ordre de l’invite dans l’affichage, pour éviter de préfixer les invites par 1), 2), 3) …
  • Optional : indique si l’invite est facultative ( à partir de XI r3 )

Exemples :
@Prompt(‘Entrez le code pays’,'A’,'Zones\Code Pays’,mono,free)
Invite de type Caractère ne permettant de sélectionner qu’une valeur, saisie possible

@Prompt(‘Entrez le code pays’,'A’,'Zones\Code Pays’,multi,constrained,Not_Persistent,{‘US’,'FR’},User:1)
Invite de type Caractère ne permettant de sélectionner plusieurs valeurs, saisie impossible., ne sélectionne pas par défaut les dernières valeurs choisies mais prend US et FR, affichage en 1ère position.

Les invites BO – part II – Affichage dans un rapport

C’est bien d’avoir des requêtes dynamiques avec des invites, mais il faudrait aussi pouvoir les afficher dans le rapport.

Dans Deski on les affiche facilement en passant par le menu Insertion / Champ Spécial / Invite de requête.

On récupérera la syntaxe dans la barre de formule :
=RéponseUtilisateur ("req" , "Entrez une date :")

La syntaxe générale est
RéponseUtilisateur (<nom du fournisseur de données> , <libellé de l’invite>)

On peut l’utiliser dans un titre en concaténant avec du texte :
="Arrêté au "&RéponseUtilisateur ("req" , "Entrez une date :")

Dans Webi il faut directement taper la formule dans une cellule, comme :
=RéponseUtilisateur([req];"Entrez une date :")
On notera que la formule est similaire, mais :

  • il faut mettre le fournisseur de données entre crochets
  • le fournisseur est facultatif, mais il vaut mieux le mettre si vous en avez plusieurs dans le document.

Là aussi on peut concaténer avec du texte ou utiliser les fonctions de texte et de date pour une cellule de titre :
="Arrêté au "+SousChaîne(RéponseUtilisateur([req];"Entrez une date :") ;1 ;10)
Ici la date renvoyée sous webi comportant l’heure, la fonction SousChaîne n’affichera que les 10 1ers caractères, soit uniquement la date.

Cubed

Un coup de cœur pour Cubed ( ^3 ) un lecteur mp3 sous Android.

Si vous trouvez comme moi que le lecteur par défaut est fade, essayez Cubed de Filipe Abrantes.
J’ai été bluffé par son interface 3D fluide et efficace. Je pense d’ailleurs qu’elle pourrait être utilisée dans d’autres applications, comme par exemple la liste des contacts où le défilement laisse à désirer.

Cubed

Cubed est disponible en beta sur Android Market ( recherchez ³ ou le nom de l’auteur ), il est opensource et marche très bien sur mon gw620 en 1.5 !!!

Un conseil sur les colonnes de type date sous Oracle …

Les colonnes date sous Oracle permettent de stocker des dates « simples », sans heure, et aussi des dates avec l’heure. C’est sympa, mais cela provoque vite des erreurs dans les traitements d’alimentation ou dans les univers BO quand on effectue une jointure sur des colonnes de ce type contenant effectivement des heures.

Par exemple nous avons une table VENTES et la table calendrier TEMPS.
La table TEMPS est au jour, la PK est JOUR de type date – sans heure
La table VENTES a plusieurs dates, dont la date de vente ( colonne DATE_VENTE ) qui est aussi de type date, mais avec l’heure.
On a tendance à lier directement les tables sur les 2 colonnes, mais cela ne ramène aucune donnée car d’un côté on a l’heure, de l’autre on ne l’a pas …

Pire, une requête sur la table calendrier avec la date d’aujourd’hui ( sysdate ) semble légitime pour un utilisateur, mais la requête suivante ne renvoie rien !

SELECT * FROM TEMPS WHERE JOUR=SYSDATE

Il faut « enlever » l’heure avec la fonction trunc() pour avoir un résultat :
SELECT * FROM TEMPS WHERE JOUR=trunc(SYSDATE)

Généralement quand je n’ai pas la main sur le modèle je mets des trunc() un peu partout pour blinder les choses, mais c’est mieux quand en amont la conception et les normes sont bien faites et bien pensées, et que les noms des colonnes permettent de distinguer les dates avec heure et les dates sans.

Par exemple on peut nommer les colonnes avec heure en préfixant par
DATE_HEURE_ et les dates sans heure par DATE_ uniquement …
( ou DATE_ et DATH_ ou … cela dépend des normes of course … )
Idem pour l’univers BO, il est utile de préciser dans le nom des colonnes si on a affaire à une date avec heure ou sans.

Ainsi on sait tout de suite s’il faut rajouter un trunc() dans les jointures, et cela évite bien des erreurs …

Il reste le problème des dates qui contiennent des dates avec heure ET des dates sans heure, mais c’est une autre histoire …

Retour d’expérience sur … Sunopsis / ODI

Sunopsis est un ETL fondé par un français, Alain Dumas en 1998. Contrairement aux ETL qui possèdent leurs propres moteurs de transformation, Sunopsis est un génarateur de code qui repose sur une architecture d’intégration distribuée. Au lieu de transformer les données sur un serveur spécifique, il lance les traitements directements sur les bases de données, en exploitant au mieux les spécificités de chacune. Cette architecture est aussi définie comme ELT ( Extract/Load & Transform ).
Sunopsis a été racheté en 2006 par Oracle et depuis a été renommé en ODI ( Oracle Data Integrator ).

Les + :

  • les performances ( mode ELT )
  • les KM ( modules de connaissance ) qui définissent les process « standard » ETL comme la détection des doublons, des valeurs inconnues de tables de référence ( écartés dans une table d’erreur ),
    l’alimentation des tables ( en Insert pur, Insert en delta, en SCD … )
  • pas besoin de connaitre un nouveau langage, le SQL du SGBD suffit généralement !
  • debugage facile
  • reprise d’un plantage à partir d’un certain point ( où ça s’est planté, ou depuis le début, ou 3 sql avant … )
  • optimisation orientée SGBD donc facile ( un expert ETL n’est pas nécessaire, un DBA suffit )
  • l’analyse d’impact très fine
  • l’éditeur de requête sql qui permet de construire des requêtes assez complexes
  • les contextes qui facilitent le déploiement d’un environnement à un autre
  • la séparation modèle physique / modèle logique

Les – :

  • traitements unitaires basiques ( plusieurs tables constituent une requête qui alimente une seule table ) : il faut généralement utiliser des tables temporaires, le flux de la donnée n’est pas visible en un seul job.
  • nécessité de connaitre les SGBD … et des fonctions complexes dans certains cas
    comme pour les comparaisons relatives entre lignes,
    par ex pour comparer un statut par rapport au statut précédent
    –> fonctions analytiques oracle
  • la perte des dépendances pour l’analyse d’impact sur certains traitements
  • la prise en main – il faut bien décomposer ses traitements

L’éditeur de requête SQL permet d’élaborer des requêtes complexes tout en gardant les références aux objets. Ainsi il n’y a pas besoin de coder les clauses « where », « group by » ou « having » comme dans les autres ETL, et l’analyse d’impact se fait à la colonne …

Quelques astuces :

  • simuler un MINUS – je vais faire un tuto dessus bientôt …

En conclusion :
Pour moi Sunopsis/ODI fait partie des meilleurs ETL du marché, il se démarque de ses concurrents principalement par ses performances et par l’intégration des process habituels d’alimentation dans l’outil.