venerdì 17 novembre 2017

Copia di una condizione da una query all'altra

Piccola nota interessante: in Web Intelligence Rich Client è possibile copiare una condizione di una query in un'altra query. Per farlo si deve trascinare la condizione sul tab della query di destinazione e attendere alcuni istanti, e poi, mantenendo il tasto del mouse premuto, trascinarla nella zona delle condizioni della query di destinazione.


lunedì 6 novembre 2017

SAP BI Platform Support Tool

Segnalo questo utilissimo tool di supporto gratuito, perchè tra le varie funzioni consente di fare l'analisi di impatto degli universi (diretta per gli universi UNX e indiretta per gli universi UNV, cioè tramite una temporanea conversione da UNV a UNX).
Anche le altre funzionalità sono molto interessanti, come le dipendenze degli oggetti partendo da un report oppure l'accesso diretto ai diritti di un gruppo e la comparazione rispetto ad un altro gruppo.
Esiste anche la possibilità di fare un'analisi end to end tramite un trace (modifica temporaneamente il file .ini), il tool quindi si può rivelare molto utile per chi si occupa di supporto tecnico alla piattaforma.
Il tool si installa facilmente su un PC Client (deve essere a 64 bit) ed ha un'interfaccia molto intuitiva.
Supporta le versioni dalla 4.0 in poi.

SAP BI Platform Support Tool

venerdì 3 novembre 2017

Confronto insiemistico tra due query

Con Web Intelligence a volte abbiamo la necessità di confrontare i contenuti di due query e vogliamo capire quali righe arrivano da una query e quali dall'altra.


Nell’esempio riportato sotto abbiamo due query, la prima estrae alcuni ID disponibili anche nella seconda query, ma per entrambe le query vi sono identificativi che non sono presenti in entrambi gli insiemi (verde e rosso).

In una tabella guidata dall’oggetto «id unito» Web Intelligence espone automaticamente l’unione degli insiemi; nessun filtro viene applicato alla tabella.



Creando due variabili che contano, per ogni query, gli ID, usando l’opzione «Tutto» per costringere il conteggio a contare in modo non distinto, si ottiene un flag che consente di capire se l’identificativo è presente in una query o in entrambe.



Filtrando opportunamente i due flag sarà possibile ottenere

1.l’intersezione dei due insiemi

2.la differenza A-B

3.La differenza B-A (il filtro che si vede in alto nell'immagine si riferisce alla tabella 3)




martedì 31 ottobre 2017

Distribuzione di frequenza

Quando si contano degli eventi avvenuti ad esempio per ogni cliente, è spesso importante poter calcolare la distribuzione della frequenza degli eventi, in forma aggregata.
Ad esempio: i nostri clienti hanno la facoltà di collegarsi alla nostra rete WiFi con il loro smartphone, vogliamo capire quanti sono i clienti che si collegano tanto, poco e pochissimo e magari capire quale può essere la distribuzione.

Se contiamo gli eventi di collegamento alla rete WiFi per cliente, possiamo avere un elenco di clienti, e per ognuno il numero di connessioni alla rete WiFi.
Ordinando il numero di collegamenti in modalità Z-A vedremo quali sono i clienti che si collegano più spesso, ma l'elenco sarà infinito, perchè ci saranno clienti che si collegano n volte, poi n-1, poi n-2.

Grazie ad una semplice formula possiamo raggruppare velocemente i clienti, ovvero possiamo creare una dimensione di analisi che aggreghi i clienti che fanno parte di una certa fascia, cioè hanno un range di numero di collegamenti comune, e quindi contare quanti clienti appartengono ad una certa fascia di numero di collegamenti.

Nell'ipotesi quindi di avere dall'universo una query che ci fornisce Codice cliente e Numero di connessioni WiFi (magari in un determinato periodo), possiamo creare la dimensione di analisi "Range", ecco la formula:

"Range"
=Se([WiFi Access - Nr of Connection] In ([Customer number])>20;">20";
Se(([WiFi Access - Nr of Connection] In ([Customer number])<=20 E [WiFi Access - Nr of Connection] In ([Customer number])>10);"10-20";
Se(([WiFi Access - Nr of Connection] In ([Customer number])<=10 E [WiFi Access - Nr of Connection] In ([Customer number])>5);"5-10";
[WiFi Access - Nr of Connection] In ([Customer number])
)
)
)

La formula aggrega il numero di collegamenti per singoli cliente e tramite un IF verifica in quale fascia ricade, quindi espone un'etichetta di testo.

Sarà quindi possibile passare dalla tabella di dettaglio riportata sulla sinistra, nell'immagine sotto, alla tabella aggregata di destra e magari fare un grafico se necessario.


Se la metrica che conta i collegamenti (ovvero gli eventi che vogliamo contare) non fosse disponibile nell'universo, ma sono comunque disponibili le informazioni di base, ovvero il Codice del cliente e il Codice dell'evento di collegamento (o il codice dell'evento che vogliamo contare), si può fare una query per estrarrei i due codici e quindi contare gli eventi per ogni cliente, tramite la seguente formula.


"Nr Connessioni"
=Conteggio([Codice collegamento]) In ([Customer number])

Creando una tabella che espone il Codice cliente e il nuovo oggetto che abbiamo appena creato, cioè il Numero di Connesisoni, otterremo per ogni cliente il numero di Connessioni.

Questa formula ci consentirà di avere la stessa tabella riportata nell'immagine in alto a sinistra; non sarà comunque possibile usare la formula dedicata al "Range" riportata sopra, perchè non avendo un conteggio nativo dall'universo, ma avendo fatto il conteggio degli eventi di collegamento dal Report, la formula dedicata al "Range" tenderà ad aggregare i dati, perchè il Conteggio all'interno dell'oggetto "Nr Connessioni" è una funzione di aggregazione.
Sarà possibile ovviare a questo problema pubblicando la tabella come servizio web (bottone destro del mouse sul bordo della tabella). A questo punto, creando un nuovo report, che usa come fonte il servizio web appena creato, sarà possibile ottenere un fornitore dati che ha in ingresso il conteggio già pronto, degli eventi di collegamento per cliente, quindi si potrà creare in questo nuovo report la dimensione "Range" descritta sopra.

lunedì 30 ottobre 2017

Personalizzare l'aspetto del BI Launch Pad

A volte è necessario personalizzare l'aspetto del "BI Launch Pad" (il portale di accesso via web a Business Objects); nella versione XI 3.x la modifica del logo era un'attività semplice e veloce (e questa magari poteva bastare) che si poteva fare dal CMC, tramite le proprietà dell'applicazione "Infoview".

Dalla versione BI 4.x l'attività di personalizzazione del sito è diventata un pò più complessa e richiede degli skill particolari, perchè si basa su file .css, ma a quanto pare sarà mantenuta in questa modalità nelle future versioni.

A tal proposito segnalo questo utilissimo tutorial.

giovedì 22 giugno 2017

Asse temporale senza buchi o nulli

Quando si realizzano dei grafici con Web Intelligence può capitare che, portando una dimensione temporale (ad esempio i giorni) sull'asse delle X, l'oggetto che utilizziamo per avere la data non fornisca sempre una data, per tutti i giorni che esistono nel periodo che stiamo analizzando.
La nuova versione di Web Intelligence fornisce una nuova formula che risolve questo problema.

La formula legge una data, ad esempio la data degli ordini, prende la minima e la massima in assoluto rispetto ai dati che la query ha estratto e crea un asse temporale completo, inserendo quindi anche le date in cui non ci sono ordini.
Funziona con i giorni, ma anche con le ore, i mesi, ecc.

=DimensioneOra([Query1].[Order Date];PeriodoGiorno)

Quando viene usata in una tabella si creano delle righe vuote relative ai giorni dove non ci sono ordini, le date mancanti vengono cioè aggiunte ai dati della tabella dalla formula e la tabella si espande.

Questa soluzione può essere utile in una Pivot (tabella a campi incrociati) dove si desidera avere una colonna per ogni giorno, senza buchi, oppure in un grafico dove sull'asse delle X si desiderano tutti i giorni di un particolare periodo.
Non è possibile usare questa formula per fare dei calcoli e delle considerazioni sulle informazioni temporali che mancavano nel cubo della query.

Tool per documentare gli universi e per generare l'SQL per il Query Builder

Uno dei problemi classici su BO, da quando siamo passati intorno al 2005 alla versione XI, è quello di documentare gli universi e in generale di avere informazioni sul sistema in modo globale e su file.

Esistono sul forum BOB diverse macro VBA in Excel molto efficaci, ma nel caso degli universi, pretendono di avere preventivamente importato l'universo in locale, e comunque documentano un solo universo alla volta.
Personalmente ho modificato una di queste macro per documentare in modo ricorsivo una cartella del file system piena di universi .UNV, ma dovevo preventivamente passare del tempo a importare tutti gli universi, cartella per cartella. Soluzione utile e veloce, ma comunque non completamente automarìtica.

Ho trovato sul web un tool gratuito molto interessante che fa tutto!
Al seguente link, a valle di una veloce registrazione, è possibile scaricare un eseguibile che:
- si autentica con login e password al repository di BO
- apre o importa gli universi che si devono documentare
- genera un file excel singolo, che documenta tutti gli universi scelti, ed in ogni sheet fornisce specifiche informazioni per ogni ambito, ovvero Oggetti, Classi, Join, ecc

Trovo questa soluzione molto interessante e grandiosa, visto che è gratuita.

Link al sito del tool:
http://biclever.com/

Il tool è disponibile sia per la versione 3.x che 4.x, sia per gli universi .UNV che per gli universi .UNX.

Il medesimo sito rende disponibile anche un tool che consente di generare facilmente l'SQL da inviare al CMS, quello che solitamente si scrive a mano nel Query Builder, per ottenere informazioni per esempio relative agli utenti e i gruppi, ai report e alle cartelle, ecc ecc.


Come vedere l'SQL se non si hanno i diritti per vederlo

In alcuni casi l'amministratore di sistema di BO nega all'utente di vedere l'SQL generato dalle query che crea, questo può essere un limite forte, perchè se l'utente ha delle nozioni di SQL può comprendere meglio quale interrogazione si sta inviando al DB.

La seguente formula permette di creare un cella libera nel report e vedere dentro la cella l'SQL di una particolare query del report, basta inserire nella formula un oggetto che proviene dalla query di cui si desidera l'SQL. Per utilizzarla sostituite la parte in rosso.

=FornitoreDiDatiSQL([nome_query].[nome_oggetto])

In inglese la funzione è

=DataProviderSQL([nome_query].[nome_oggetto])

mercoledì 14 giugno 2017

Giorni tra, senza sabati e domeniche

Trovo questa soluzione molto utile e geniale, permette di calcolare i giorni tra due date, escludendo i sabati e le domeniche, senza avere una tabella calendario a supporto.

L’ho tradotta in italiano per testarla


=(Tronca(GiorniTra([Start Date];[End Date]) / 7 ; 0) * 5) + InNumero(Sottostringa("1234555123444512333451222345111234500123450123455"; ((NumeroGiornoDellaSettimana([Start Date])-1)*7)+Resto(GiorniTra([Start Date];[End Date]);7)+1 ; 1))

Ecco la formula originale in inglese

=(Truncate(DaysBetween([Start Date]; [End Date]) / 7 ; 0) * 5) + ToNumber(Substr("1234555123444512333451222345111234500123450123455"; ((DayNumberOfWeek([Start Date])-1)*7)+Mod(DaysBetween([Start Date];[End Date]);7)+1 ; 1))

Ecco dove ho trovato questa soluzione, seguendo questo link è possibile leggere tutta la spiegazione dettagliata, passo per passo:

martedì 21 febbraio 2017

Caratteristiche di un buon universo BO

Riporto di seguito le caratteristiche che dovrebbe avere un universo Business Objects

Dal punto di vista "utente", ovvero per quanto riguarda ciò che l'utente finale dell'universo può "vedere" e usare:

- i nomi delle classi e degli oggetti devono essere molto familiari all'utente
- la disposizione delle classi e delle sottoclassi di oggetti deve essere ben organizzara e se possibile in gerarchia
- gli oggetti all'interno delle classi devono essere disposti dall'alto verso il basso dal padre verso il nipote, cioè in gerarchia se possibile, questo consente all'utente di usare il drill down anche se non sono state create delle gerarchie personalizzate
- l'universo deve avere una descrizione chiara e aggiornata
- gli oggetti devono avere una descrizione sempre (se possibile anche le classi); le descrizioni accettano i tag HTML, è possibile quindi inserire dei ritorni a capo e dei colori
- gli oggetti particolari devono avere il formato gestito a livello di universo
- le misure o metriche che hanno senso solo per una classe di oggetti devono stare nella medesima classe di questi oggetti
- i contesti di analisi devono avere un nome familiare all'utente, ma soprattutto devono avere una descrizione che consenta all'utente di prendere una decisione, cioè capire quale tipo di analisi otterrà scegliendo un contesto al posto di un altro
- devono essere gestite le incompatibilità tra oggetti
- devono essere gestiti i limiti di righe estratte e di tempo dedicati alla query perché i valori di default sono troppo restrittivi
- le liste di valori degli oggetti, se possono essere esposte all'utente come gerarchie padre/figlio, vanno modificate rispetto al default (select distinct di una colonna), in modo che l'utente sia agevolato nella scelta del valore interessato, potendo quindi scegliere il padre e quindi il valore di interesse
- le liste di valori se possibile devono avere un ordinamento, perchè per default eseguono una select distinct del campo senza ordinamento
- è utile creare degli oggetti che forniscano all'utente alcune date standard di riferimento, come ad esempio la data di oggi, di ieri, del primo e dell'ultimo giorno del mese in corso e del mese precedente, l'ultimo giorno dell'anno, ecc, dato che l'utente potrà poi usare questi oggetti, apparentemente inutili se esposti come risultato della query, ma fondamentali invece se utilizzati come condizioni nella query, perchè l'utente potrà usarli in combinazione con altri oggetti per costruire condizioni dinamiche, come ad esempio: DATA INGRESSO CLIENTE >= IERI oppure DATA DI APERTURA DEL TICKET >= INIZIO DELL'ANNO IN CORSO
- una variante del punto precedente, relativo agli oggetti dedicati alle date, dovrebbe includere dei @prompt nell'sql, in modo che l'utente possa utilizzare un oggetto che permetta di avere una data pari a oggi - X giorni, dove X viene gestito dall'utente grazie al @prompt

Dal punto di vista "tecnico", ovvero per quanto riguarda le funzionalità tecniche che l'utente subisce in modo trasparente

- deve in diversi casi essere rimosso il flag che costringe l'universo a creare molteplici query per ogni metrica o misura
- devono essere gestite eventuali outerjoin in modo che l'utente non inserisca involontariamente dei filtri man mano che aggiunge oggetti nelle query; ogni universo dovrebbe avere un obiettivo di analisi specifico, ad esempio il Cliente o i Ticket, quindi aggiungendo oggetti nella query non si dovrebbero filtrare le righe e quindi mantenere la cardinalità corretta di Clienti e Ticket
- devono essere gestiti i numeri di righe delle tabelle, in modo automatico (il sistema conta le righe) o in modo manuale; questa funzione è utile perchè l'sql sarà costruito considerando i "pesi" delle tabelle e quindi la FROM sarà gestita in modo coerente nell'SQL (per oracle ricordarsi di modificare il parametro REVERSE_TABLE_WEIGHT da Y a N)
- descrivere le varie versioni di modifica dell'universo, inserendo degli oggetti dimensione nascosti, che hanno per nome la versione o la data della modifica, e nella descrizione un testo che spieghi cosa è stato modificato
- inserire nel modello dati delle descrizioni vicino alle tabelle
- evitare se possibile l'uso eccessivo di alias e quindi il proliferare di oggetti ridondanti verso l'utente
- gestire il parametro BOUNDARY_WEIGHT_TABLE: questo parametro permette di evidenziare una soglia di righe, superata tale soglia, i filtri delle query creati dagli utenti con gli oggetti non saranno gestiti nella WHERE condition dell'SQL, ma come sotto SELECT all'interno della FROM, dove ovviamente la sotto SELECT avrà il filtro richiesto dall'utente nella sua WHERE
- ovviamente prima della pubblicazione deve essere fatto un check di integrità