Qlik Sense Calendar Measures & "Minicharts" in Tabellen


Unsere Kunden fragen häufiger, ob sie in Qlik Sense Tabellen auch Graphiken (Ampeln, Bars, Sparklines) darstellen können. Die Qlik verweist dann gerne auf Extensions, womit wir jedoch gemischte Erfahrungen gemacht haben (kein Support, Limitierung auf bestimmte Qlik Sense Versionen, Paging nicht sauber implementiert, etc.).


Nehmen wir die neuen "Calendar Measures" in Qlik Sense 3.2 zum Anlass, um zu sehen was man mit den Boardmitteln der aktuellen Qlik Sense Objekte erreichen kann!
 
Qlik Sense "Mini Diagramme" und Sparklines - mit Boardmitteln. Ist das möglich?

Calendar Measures

Mit Qlik Sense 3.2 sind Calendar Measures als neues Feature hinzugekommen. Sie verbinden einige Features die in voherigen Qlik Sense Versionen enthalten waren (Declare Statement für Kalender, Datamanger automatische Datumserkennung) mit einem Feature, welches wir schon lange kennen: Set Analysis!

Laut Doku muss man sich den Kalender über den Datamanager generieren lassen. Dieser erzeugt das Declare Statement im Script.

Qlik Sense Datamanager Date
Datamanager erkennt Bestelldatum als Datum und generiert Kalender

Das Measure, welches ein Calender Measure werden soll, rechtsklicken und "Kalenderkennzahlen erstellen"wählen.

Qlik Sense Calendar Measure Create
Neuer Menüpunkt

Es erscheint der neue Dialog bei dem man "mehrmals" die Zeitraum-Dropbox klicken kann um alle Masteritems zu genieren.  In der Vorschau sieht man bereits: Im Grunde werden Set Analysis Expressions am Declare-Kalender erzeugt.

Qlik Sense Calendar Measure Dialog
Calendar Measure Dialog

Alles im allem ist dieses Qlik Sense 3.2 Feature "ganz OK". Aber wer heute schon seinen eigenen Kalender hat, der bleibt damit momentan noch flexibler!

Limitationen die ich momentan sehe:
  • Laut Doku darf man in das Declare-Statement nicht mit dem Script Editor anlegen.  Ich habe es mir im Datenmanager generieren lassen, und dann sehr wohl modifiziert (statt today() das Jahr 1998, damit das YTD vom "aktuellen Jahr" in meiner Nordwind Demo funktioniert). Prinzipiell schient das also möglich, man muss wohl mit dem Qlik Support klären, ob wir das auch dürfen.
  • Der Wizard generiert nur einige Felder, braucht man zB ein YTD vom Vorvorjahr, muss man das Masteritem wieder manuell machen.
  • Die erzeugen Formeln sind nicht "dynamisch". Wählt der User also das Jahr 2015, sieht er im Vorjahresvergleich nicht 2015 und 2014, sondern weiterhin 2017 und 2016. Das kann man sehen, wenn man sich das Declare Statement des Kalenders im Skript ansieht.
  • Declare mit großen Datenmengen hat/hatte ein Performance Problem. Das müsste man in Qlik Sense 3.2 wieder testen.
  • Es werden viele Master Items generiert; ich hatte gehofft, dass man das SET via Parameter an das Masteritem übergeben kann. Ähnlich wie bei Variablen wären die $-Parameter gut gewesen, dann könnte man die Masteritems auch besser gruppieren.
  • Wenn man weitere Set Modifier (zb Source={BUDGET}) in seiner Expressionbenötigt, muss man alle MasterItems manuell nacharbeiten. Ein weiteres Inputfield direkt im Wizard wäre nett gewesen.
Naja, zumindest kann man jetzt eine Nordwinddemo mit YTD-Vergleich ohne jedliches Skripten bauen, und das soll hier auch die Grundlage für unser weiteres Beispiel sein :-)

Charts in Qlik Sense Pivot & Straight Table

Nachdem wir jetzt also YTD und YTD-Vorjahr Masteritems haben, möchten wir diese vergleichen. Eine Prozentzahl können wir natürlich als Zahl in einer Tabelle ausgeben. Aber wie sieht es mit Graphiken aus?

Die beschriebene Applikation finden Sie Online unter demo.heldendaten.net und als Download hier.

Ampel 

Ampeln sind in Straight Table und Pivottable möglich. Man nimmt einfach das Unicode-Zeichen, dass einem am meisten an eine Ampel erinnert und färbt es ein :-) Es gibt sogar eine Unicode Ampel 🚦, die lässt sich aber nicht gut färben, deswegen würde ich sagen ein Block █ ist am Besten! In Qlik Sense kann das dann folgendermaßen aussehen:

Expression: ='█'
ColorCode:  if(column(1) >=column(3), green(), lightred())

Qlik Sense Ampel Traffic Light

Nachteil in der Pivottabelle: dadurch, dass alle Spalten immer gleich breit sind, wirkt die Ampel manchmal ein wenig verloren!

Linear Gauge

Einen Schritt weiter muss man die Idee spinnen, um eine Linear Gauge zu schaffen. Um einen Prozentwert darzustellen kann man mehrere Blöcke █ mit der repeat-Funktion aneinanderreihen. 70% sind dann sieben Blöcke ███████ . Sieht aus wie ein kleines Balkendiagramm.

Expression: =repeat('█', 
                   rangemax(rangemin( ceil(((column(1)/column(2))-1)*10),10),1) 
                  )
ColorCode:       =if([Steigerung]>2, argb(255,0,150,0),
            if([Steigerung]>1, argb(255,0,200,0),
                     if([Steigerung]>0.5, yellow(),lightred())))
 

Qlik Sense Linear Gauge Bar

Die Rangemin/max-Funktionen dienen dazu, dass man minimal einen und maximal zehn Blöcke zeichnet. Negative Werte als "Butterfly" darzustellen ist schwierig, aber das war es in QlikView auch.

Minichart

Schaffen wir mit diesem Ansatz auch ein Minichart oder gar eine Sparkline? Jein! Zumindest die Unterart "Whiskers" von QlikView kann man andeuten. Zum Beispiel für die Fragestellung: habe ich im Vergleich zum Vormonat mehr oder weniger Umsatz gemacht.

Qlik View Mini Chart Whiskers
QlikView Mini Chart Whiskers

Dazu nutzen wir die neue "Sortable Aggr" und zwei verschiedene Blocktypen: ▀ (upper half) und ▄ (lower half)

Expression: 
=concat(
        aggr(
             if(sum(Umsatz) > above(sum(Umsatz)),
               '▀',if(not isnull(above(sum(Umsatz))),'▄',' ')
             )
             ,Kategoriename, (Bestellmonat,(NUMERIC, ASCENDING))
        )
 ,'',Bestellmonat)

Qlik Sense Mini Chart Whiskers


Das Kombidiagramm unterhalb zeigt die Details: wir haben im März 1998 weniger Getränke verkauft als im Feb 1998, im April weniger als im März, und im Mai weniger als im April. Deswegen sind 3 "lower"-Blöcke ▄▄▄ am Ende der Whiskers zu sehen.

Für eine vollwertige Sparkline kommt man mit UniCode-Characters wohl nicht viel weiter. Aber bis das Feature zur Verfügung steht, ist es vielleicht eine gangbare Alternative zu einer Extension!

PS: Alle Formeln sollten eigentlich auch in QlikView 12 funktionieren. Dort würde ich aber jeweils das angestammte Feature hernehmen :-)







QlikView 12 - Offline Hilfe als PDF

Als ich 2008 bei QlikTech begann, gab es noch Software auf CD und gedruckte Handbücher. Zeiten ändern sich! Auf die CD kann man mittlerweile getrost verzichten, mit den Handbüchern ist das so eine Sache...

Qlik gibt sich ja wirklich viel Mühe bei Ihrer neuen Online-Hilfe auf help.qlik.com! Es scheint gerade wieder ein neues Facelift bekommen zu haben.


help.qlik.com
help.qlik.com


Wer die Hilfe im QlikView 12 Developer aufgerufen hat, hat sicher schon bemerkt, dass - anstatt des bisherigen lokalen .chm-Files - nun direkt auf die Onlinehilfe verwiesen wird. Ich würde mir noch wünschen, dass man bei den einzelnen Script-Befehlen noch ein Messageboard integrieren würde, dann könnte man da direkt mit dem Qlik Support kommunizieren.


Schlecht jedoch, wenn man auf einem Entwicklungsserver ohne Zugang zum Internet arbeitet. Dann bekommt man nämlich gar keine Hilfe mehr zu sehen. Der Ärger ist groß bei Parntern & Kunden.

Letztens in der Knowledge Database habe ich es aber in einem Artikel entdeckt: Gut versteckt gibt es jetzt doch wieder PDF Handbücher zum Offline Arbeiten in Deutsch und Englisch:


QlikView PDF Guides



Schlanke 2039 Seiten sind es momentan beim "Arbeiten mit QlikView.pdf"! Ausdrucken werden wir es also wohl nicht :-)






Information Density bei Concatinierter Faktentabelle

Zu jedem Feld kann man sich in QlikView und Qlik Sense die Information Density anzeigen lassen. Das ist eine wichtige Information, um die Datenqualität Ihrer App zu überprüfen.

Hier ein Beispiel: im Kundenstamm haben nur 75,8% aller Kunden eine Telefax Nummer gepflegt. Das könnte bei Ihrer nächsten Telefax-Marketing Kampagne (falls es soetwas noch gibt :-)) störend, für Ihre nächste Rechnungslegung unter Umständen sogar sehr ärgerlich sein!

Information Density in Qlik
Information Density - links in Qlik Sense, rechts in QlikView

Jedes einzelne Feld zu überprüfen ist einigermaßen zeitaufwendig, weswegen wir in unserem Heldendaten Applikationstemplate gerne den Data Profiler von quickintelligence.co.uk nutzen. Dort sieht man die "Null Values" eines Feldes auf einem Blick.

Telefax hat 22 Null Values, was die Information Density von 75,8% ergibt
Auch andere Felder im Kundenstamm haben eine Information Density < 100 %

Information Density bei Concatinierter Faktentabelle

Schwieriger wird es mit der Information Density-Kennzahl, wenn Sie ein Datenmodell mit mehreren Faktentabellen bauen. Das passiert sehr häufig: Ihre Applikation hat mehrere Faktentypen (IST-Zahlen und Budget-Zahlen) oder Sie verheiraten die ERP-Altdaten mit Daten ihres aktuellen ERPs. Steht ist es wichtig zu wissen, welche Spalten wie gut gefüllt sind. Vor allem wenn man sicherstellen möchte, dass der Anwender mit seinen Selektionen die Daten aus allen Quellsystemen wählt (also die Information Density 100% ist)


Zur Veranschaulichung, hier ein Beispiel wie in  Qlik solche Faktentabellen aussehen:

Concat Fakten in gemeinsame Faktentabelle
Für den Faktentype Procurement Cost gibt es das Feld Region  in der Quelle nicht. Damit ist die Information Density für diese Feld  jetzt nur noch 14 (befüllte Zeilen) /20 (Zeilen insgesamt) = 70%. Viel interessanter wäre es aber zu wissen, dass das Feld Region folgende Information Densities hat:

  • Sales: 100%
  • Plan Yearly: 100%
  • Procurement Cost: 0%
Wählt ein Anwender einen Eintrag im Feld Region an der Oberfläche, so sieht er keine Procurment Costs mehr. Das kann gewünscht sein, oder ein fehlerhaftes Mapping/fehlende Daten sein. Eine Information Density pro Faktentyp ist also Notwendig für eine umfassende Problemanalyse.
Dafür benötigen wir zuallererst ein Feld Source um zu wissen aus welcher Quelle welche Datensatzzeile ursprünglich kommt. Das Aufbauen Ihrer Faktentabelle Facts sollte also etwa so aussehen (je nachdem ob aus Datenbank/QVD/resident)

Facts:
load
*,
'Sales' as Soure
from/resident Sales;

concatenate (Facts)
load
*,
'Plan Yearly' as Soure
from/resident Plan Yearly;

concatenate (Facts)
load
*,
'Procurement Cost' as Soure
from/resident [Procurement Cost];
 
 
Als nächsten Schritt müssen NullCounts() für alle Felder im Script berechnet werden. Wenn Sie ein 3-Schichtenmodell nutzen, würde ich das Script im Datenmodell hinzufügen. Bei großen Datenmengen und vielen Faktenspalten kann das Skript schon mal länger rechnen - fügen Sie sich vielleicht einen Variablen-Schalter ein, damit das Skript beim Entwickeln nicht ständig ausgeführt wird.

//config
let tFactTableName = 'Facts';
let tSourceTable_Field = 'Source';


//Generate Fields that are in Facttable
let vAggregations = '';
for i = 1 to nooffields('$(tFactTableName)')

 let vField = Fieldname($(i),'$(tFactTableName)');
 if (vField <> '$(tSourceTable_Field)') then
   let vAggregations = vAggregations & 'nullcount([$(vField)])  as [$(vField)] ,';
 end if
 
 
 
next
trace *************** Check for fields: $(vAggregations);

ttFactsInfo:
load
   $(tSourceTable_Field), 
   $(vAggregations)
   1 as dummy
resident $(tFactTableName) group by $(tSourceTable_Field);

drop field dummy;


//Transform table to get all Fieldnames in a single column
tFactsInfo:
CrossTable (FieldName,NullCount,1)
load
  *
resident ttFactsInfo;
drop table ttFactsInfo;
 
  
//Check how many rows each "Source Table" has
MappingFactsSourceCount:
mapping
load
 $(tSourceTable_Field),
 count($(tSourceTable_Field))  as AllCount
resident $(tFactTableName) group by $(tSourceTable_Field);


//Generate FactsInfo
FactsInfo:
load
 $(tSourceTable_Field),
 FieldName,
 applymap('MappingFactsSourceCount',$(tSourceTable_Field), -99) 
           as AllCount,
 NullCount,
 applymap('MappingFactsSourceCount',$(tSourceTable_Field), -99)-NullCount 
          as FoundCount
resident tFactsInfo;

drop table tFactsInfo;

//optional drop table Facts;


let tFactTableName = ;
let tSourceTable_Field = ;


Das Skript erzeugt einen neue Tabelle FactsInfo mit den Feldern NullCount und FoundCount für jeden Fieldname pro Source-Tabelle. Damit lässt sich dann eine Pivottabelle bauen, die Ihnen die Information Density pro Feld zeigt. Unterhalb sehen Sie ein beladenes Beispiel in Qlik Sense
Information Density Example Concat Facts
Information Density für die Fakten: Buget, ORDERS und VBRP
Die Gesamtwerte-Spalte zeigt die Information Density wie sie Qlik im Datenmodell anzeigen würde. Daneben sehen wir die Befüllung in den Faktenquellen. Man sieht zum Beispiel auf einen Blick, dass das Feld PRODH (Produkthierarchie) in einigen ORDERS-Faktenzeilen nicht befüllt ist, da die Information Density dort nur 99,98% ist. Das Feld %KUNNR hat leere Einträge in ORDES und VBRP. Die Spalte NetSalesBudget hat nur eine Information Density von 1,94% - das ist aber OK weil es nur in der Source-Tabelle Budget befüllt ist (und dort dafür mit 100% immer einen Wert hat)

Als keines Gimmick sei auch noch das Sortieren der Pivot-Tabelle genannt. Sowohl die Sortierung nach Information Density, als auch eine alphabetische Sortierung der Feldnamen kann Sinn machen. Mit einer Variable kann die Sortierung hin- und hergeschalten werden. Siehe Screenshot mit alphabetisch sortierten Feldnamen - jetzt mit QlikView:

Information Density alphabetisch sortiert

Das komplette Beispiel für QlikView und Qlik Sense finden Sie unter content.heldendaten.eu/InformationDensity.zip









Automatische Email Benachrichtigung - Notification Connector For QlikView & Qlik Sense

Zuletzt habe ich auf einem Projekt gearbeitet, bei dem die QlikView Dashboards "Near Realtime" kontinuierlich geladen werden. Das funktioniert sehr gut - außer wenn der QlikView Publisher auf einen dauerhaften Fehler läuft - denn dann wird man mit Alert-Emails nur so zugespammt. Jeder fehlgeschlagener Reloadtask schickt eine eigene Email. Da kommen in der Stunde schnell 300 Emails zusammen.

Notification Connector For QlikView & Qlik Sense

Um die Emailflut einzudämmen, aber trotzdem über Fehler informiert zu werden, haben wir den Notification Connector For QlikView & Qlik Sense benutzt. Ende des Sommers hat Qlik unsere alten Freunde von qvsource.com übernommen, und dankenswerterweise einige Konnektoren zur freien Benutzung bereitgestellt. Darunter eben auch den Notification Connector, der es erlaubt, aus dem QlikView-Script heraus Emails zu verschicken.

Die freien, ehemaligen QVSource Connectoren, die Sie aus dem Qlik Market herunterladen können


Prinzipiell war der Emailversand auch mit den QlikView Alerts schon immer möglich. Aber die hübsche Formatierung in HTML, und die Flexibilität des QlikViewScripts ist  mit dem Notification Connector doch besser. In Qlik Sense ist der Connector überhaupt die erste Wahl um automatisiert Emails zu senden.

Fehlgeschlagene Tasks erkennen


Um Fehler aus den Publisher Logs zu lesen, haben wir uns bei den Skripten aus dem QlikView Governance Dashboard 2.0 bedient. Dort ist das Skript im versteckten Scriptreiter sichtbar, wenn man das Passwort "QVGD2.0" eingibt.

Das Hidden Script des Governance Dashboards

 Email Versand


Die .qvw  wird in unserem Projekt jede Stunde vom Publisher angestoßen, und sucht nach allen Taskfehlschlägen die seit dem letzten Run passiert sind.  Findet es Fehler, so schickt es eine Email mit allen betroffenen Applikationsnamen und den Log-Pfaden. So hat man mit einem Klick die Möglichkeit den Grund des Fehlers zu analysieren.

Email des Notification Connetors, insgesamt sind in der letzten Stunde 7 Tasks fehlgeschlagen

Einmal am Tag schickt die Applikation außerdem eine "Alive"-Email und sagt wie viele Reloads erfolgreich durchgeführt wurden. 

Email des Notification Connectors: von den 137 Reloads in der letzen Stunde waren alle erfolgreich. Kein Grund zur Sorge

Auch wenn Sie keine häufigen Reloads haben, so ist der Notification Connector hilfreich. Anstatt morgens in die QMC zu sehen, können Sie sich hier beliebige Informationen der nächtlichen Beladung zukommen lassen. Natürlich können Sie sich mit dem Notification Connector alle möglichen Informationen&Alarme versenden (Umsatzgrenze unterschritten, Datenqualitätsprobleme, etc.). Ihrer Phantasie ist da im QlikView Script keine Grenze gesetzt.

Die .qvw finden Sie zum Download hier. Sie müssen den Notification Connector am gleichen Rechner wie den Publisher auf Port 5555 installiert haben. In der .qvw müssen Sie am Reiter "Main" Ihre Einstellungen in den Variablen vornehmen. Bei Fragen stehen wir gerne zur Verfügung!


 

Search in Qlik Sense

Die Kollegen vom Qlik Design Blog haben einen schönen Artikel über die Suchmöglichkeiten in Qlik Sense verfasst. Das Cheat Sheet welches dabei herausgekommen ist, sollte man am besten jedem Anwender zur Verfügung stellen.


Qlik Sense Search Cheat Sheet
Suchen in Qlik
In QlikView sind die Suchmöglichkeiten leichter zu finden, weil der Anwender einige davon mit einem Rechtsklick auswählen kann. Dienlich ist das Cheatsheet aber sicherlich auch für QlikView-Anwender, da alle angeführten Suchen ebenfalls existieren.

Als Alleinstellungsmerkmal hat Qlik Sense 3.0 in der globalen Suche ein neues Feature, bei dem der Suchbegriff auch in den Diagrammen gesucht wird. Wenn Sie etwa in der Helpdesk Application nach "Infra" suchen, liefert die globale Suche direkt ein Preview auf ein Balkendiagramm und ein Liniendiagramm, in denen der Suchbegriff als "IT Infrastructure" und "Web Infrastructure" vorkommt.

Qlik Sense 3.0 Search Expression in Charts
Qlik Sense 3.0 Suche in Charts

Das Feature ist sehr prominent platziert. Manchmal geht dabei fast die normale Feldsuche ein wenig unter. Wir sind gespannt wie diese Feature von den Anwendern adaptiert wird.

Wozu ich in der Qlik Sense Dokumentation  leider nichts finden konnte, sind dynamische Bookmarks. Zum Bespiel benötigen wir öfter einen Button der das aktuelle Datum auswählt. Die Syntax dafür ist leider nicht so simple, dass jeder Anwender ohne weiteres die entsprechende Expression aus dem Ärmel schüttelt: man muss den Feldnamen und die Funktion tippen. =today() alleine greift leider nicht.

Qlik Sense Dynamische Suche in Feld
Eine Suche nach "heute" im Feld Date - ausgeführt am 16.09.2016

Soweit so "QlikView" könnte man sagen. Dort ist es die gleiche Syntax! Der Unterschied zeigt sich aber in der Auswahlbox. In QlikView steht dort der Dynamische Ausdruck, in Qlik Sense jedoch das Ergebnis der Suche: "9/16/2016".

QlikView Auswahlstatus dynamische Suche
In QlikView sieht man den dynamischen Ausdruck


Damit hatte ich eigentlich angenommen, dass es momentan keine dynamischen Lesezeichen in Qlik Sense gibt. Auch in der Lesezeichen Definition kann man leider nicht erkennen, ob es ein dynamischer Ausdruck gespeichert wird, oder das Ergebnis der Suche...

Qlik Sense Bookmark Dialog


Legt man jedoch das Lesezeichen auf einen Button, wartet mal kurz einen Tag und klickt diesen dann, so merkt man, dass auch in Qlik Sense das Lesezeichen die dynamische Suche (und nicht den 16.9.2016) speichert.

Qlik Sense Button Apply Bookmark
Button mit "Apply Bookmark"


Qlik Sense Dynamic Bookmark
Der Klick auf den "Select Today" Button am 17.09.2016



Wer sich selbst überzeugen möchte, die Applikation ist online auf demo.heldendaten.net zu finden! Dynamische Bookmarks funktionieren also auch in Qlik Sense. Wer die Applikation vor dem Jahr 2029 testet, sollte mit dem Button immer den aktuellen Tag gewählt bekommen. Danach müsste ich das Skript anpassen ;-)

heldendaten GmbH,2020