All posts by Rob Wunderlich

Qlik Luminary Program

TLDR: Shameless self promotion and extensive use of links.

The Qlik Luminary Program “brings together the best and brightest customers, partners and enthusiasts in the Qlik ecosystem”. Being selected as a Luminary is an honor that acknowledges a significant contribution to the community of Qlik practitioners and customers.

The point of my post today is that all four presenters at the Masters Summit for Qlikview were selected as Qlik Luminaries in 2014.  What are the odds of that! I expect that one of my colleagues or a QlikCommunity member will post the applicable probability expression — written in QlikView syntax of course. Followed up by a gentle refinement by Henric Cronström — who was a special guest at our 2013 London Summit.  At that very  same summit Henric not only took us back in time to a QlikView 0.9 demo but also busted the count distinct myth.

Speaking of the London Summit, Steve Dark, another 2014 Luminary,  contributed valuable experiences during the general sessions and followed up with detailed posts in his blog on questions raised during the summit.

While the 2015 Luminary class has not been officially announced, I expect a least a couple of us will repeat as Luminaries. If we don’t all make it, I’ll chalk that off to a  smaller class rather than anyone slacking off.

Stephen Redmond has announced that he is a member of the 2015 Luminary class.  Stephen certainly deserves the honor, having written several excellent and well regarded books on QilkView. Stephen graced us as the guest speaker in the aforementioned London Summit.

Speaking of Summit memories, I have fond recollections of the Barcelona Summit. I forgot to pack my trademark hat. Frank Buender of Lynxx BV bought me a substitute hat during our evening social time. Frank also posited many challenging and provocative questions to the Masters  and went on to contribute in the private LinkedIn group for Summit attendees.

At each Summit, we have a carefully selected guest speaker.  In Amsterdam, Christof Schwarz of Qlik wowed the audience with his innovative tips and solutions.

I hope to see you at one of the 2015 Masters Summit for Qlikview.  I anticipate we’ll see a number of QlikView Luminaries.  I expect we will push the boundaries of QlikView, and  of course, now Qlik Sense.

-Rob

 

Share

Using Variables as Metadata

A customer asked me today if there was a QVW property for an application description that could be pulled as metadata by his scanner app.

I’ve found that using Variables is a very simple way to define additional metadata.

[qlikview]SET vAppDescription = This is the main Sales app. blah blah;[/qlikview]

A different script can load that variable with this bit of script:

[qlikview]Meta:
LOAD [RawValue] as AppDescription
FROM [some qvw path.qvw]
(XmlSimple, Table is [DocumentSummary/VariableDescription]) WHERE Name = ‘vAppDescription’ ;[/qlikview]

-Rob

Join me at the San Francisco Masters Summit for QikView for more scripting tips.

Share

SF Masters Summit Early Bird Discount ends Feb 27

SFBannerThe bird is in this photo is not a seagull. She’s an earlybird, headed to masterssummit.com to take advantage of the earlybird registration discount available until February 27.

At the Summit, birds of the Qlikview Developer variety will be immersed in three days of hands-on advanced and intermediate QlikView Developer training. We’ll be covering topics such as advanced scripting, advanced expressions & aggregation, visualization, data modeling, performance, server administration and Qlik Sense for QlikView  customers.

Training will be led by four popular instructors, all well known as Consultants, Bloggers, Qlik Luminaries and longtime QlikCommunity contributors.

Barry Harmsen: Co-author of the seminal book “QlikView 11 for Developers” and founder of the Q-on Training Center.

Oleg Troyansky:  Author of the upcoming “QlikView Your Business” , QlikView veteran and one of the all time top contributors to QlikCommunity.

Rob Wunderlich (hey that’s me!):  Publisher of QlikViewCookbook.com and founder of the QlikView Components open source script library.

Bill Lay: Visualization wizard and everyone’s favorite presenter. Bill’s entertaining  presentation style makes any topic interesting and engaging.

In addition to the class material, we’ll have an evening panel discussion, guest speakers and plenty of opportunities to network with peers.

Read more about the Masters Summit for Qlikview and Register here.  See you in San Francisco!

 

Share

Listbox Expressions

Prior to the introduction of Listbox Expressions in QV11, the only additional data you could put in a listbox was Frequency.  The Show Frequency option has some shortcomings:

  • The meaning of frequency is dependent on the data model. For a customer name in an orders table, frequency may correctly reflect the order count.  If the customer name is moved to a dimension table, the  frequency is “1” .
  • Frequency values show only for possible rows — green and white. Excluded gray rows show nothing in the Frequency column.
  • Show Frequency is not available for Key fields.

Listbox Expressions solve these problems and more. Here are are a few tips on using Listbox Expressions.

On the Expressions tab of a listbox properties,  you can add one or more expression columns, as you would in a chart. The “Dimension” will be the listbox field.

While the dialog may be similar to a chart, there are a few features that are not available, notably:

  • Number format — you must do any desired formatting in the expression.
  • Column labels — the workaround is to include the “label” text in the Caption.
  • Totals.

If you want your Listbox sorted by the expression value, repeat the expression in the Sort pane “Expression” property. There is no need to include the “Num()” formatting in the Sort Expression, but no harm in leaving it in either.

Now we have a nicely sorted listbox that provides context about “customer size”.

When selections are made, excluded data shows zero, probably not what we want. Fix that up by adding a Set  to the expression.

sum({1}LineSalesAmount)

What if we want to the Sales expression to reflect other selections, like Product, but still want to see all Customers? Simple, add a set modifier to ignore Customer.

sum({<Customer=>}LineSalesAmount)

Like a chart, we can add additional expressions such as order count,  days since last order, or account rep name.  We also have the full range of expression representations; Image, Gauge, Mini Chart etc. We can even put pictures in the listbox.

There is no visible vertical line separating  columns, but the columns may be resized by dragging at the invisible  boundaries.

If you get frustrated trying to make a listbox look like a chart, take a step back. Listbox expressions are meant to guide the user in making selections, not present a finished analysis.

-Rob

Share

Focus not Filter

I always enjoy Barry Harmsen’s popular-culture-and-Qlikview posts like last week’s “What QlikView developers can learn from The Karate Kid“.

If I got you back from reading Barry, here’s my bit of Mr Miyagi wisdom: “Focus not Filter”.

Green/white/gray in a listbox provides focus on the selected data while still keeping all data visible. The same concept can sometimes be useful in charts. Emphasizing selected data while keeping all data visible  maintains context and provides for consistent comparison.

Here are a few examples of techniques I use with QlikView charts to “Focus not Filter”.

All data and selected data can be shown side by side on a chart with the currently selected data emphasized.

 

Maintaining  constant scale as users make selections can be a good way to maintain context.  The image on the left is in the clear state, the image on the right  has 13 of 51 values selected. The y-axis scale remains constant which makes it clear to the user that they are now working with a relatively small number of schools.

 

 

“Graying out” unselected data is another favorite technique.

 

A variation on “graying out” is  maintain  color but mute unselected data and highlight selected data. In this line chart, unselected data is partially transparent and  lines for selected data are shown at 1.5 times standard width.

 

If you are trying to find the Karate Kid scene where Mr Miyagi says “Focus not Filter”, stop looking. It’s not in there, I made it up. But I’m sure Mr Miyagi would have said it if he used QlikView.

-Rob

Share

How to Choose an Expression

This is a follow on to my post “How Not to Choose an Expression” that described the performance problem sometimes experienced in large apps when choosing one of several expressions.

I received a number of questions about the scalability of my suggested solution to define multiple Expressions using the Expression Conditional property. In this post I’ll present an alternative for when you have a large number of option combinations.

Before I dive in,  an important comment about coding for performance. First, you should code for clarity and maintainability. If your document contains only a few million rows, it probably won’t matter if you use if() or an alternative technique.  I’m fond of the  Donald Knuth quote “Premature optimization is the root of all evil (or at least most of it) in programming”. The techniques presented in this post are meant to solve an identifiable performance problem. I wouldn’t bother implementing them unless I have a need.

Let’s use a scenario where calculations should reflect user selected options.

  • US Dollars or Local Currency  — USD | LC
  • Include VAT?  — Y|N

I’m only dealing with two options to keep my example manageable. You should be able to extend the concepts into many options.

The if method chart Expression for our choice may look like this:

if(CurrencyType='USD' AND [Include VAT?]='N'
 ,Sum(SalesAmount_USD)
,if(CurrencyType='USD' AND [Include VAT?]='Y'
 ,Sum(SalesAmount_USD + VAT_USD)
,if(CurrencyType='LC' AND [Include VAT?]='N'
 ,Sum(SalesAmount_LC)
,if(CurrencyType='LC' AND [Include VAT?]='Y'
 ,Sum(SalesAmount_LC + VAT_LC)
))))

The [CurrencyType] field controls which field we will sum() and the [Include VAT?] field controls if the associated VAT field is included in the sum(). What’s the difference between the alternatives? Only the fields listed in the sum().

Our Document contains 100M rows and we’ve identified this expression as a bottleneck. What are some alternatives to make this perform better?

In my previous post, I discussed dividing this into four expressions and making a choice using the Expression Conditional property. I won’t repeat the details of it here.  In this case, I don’t want to create multiple expressions in the charts. What is another possible technique?

Start by loading a table that reflects the choice fields and the associated sum() fields.

This is an island table that is not linked to any other tables in our model.

Create Listboxes for [CurrencyType] and [Include VAT?]. Set the “Always One Selected” property in the Listboxes.  This will force the user to make selections and at any given time only one row will be possible in our table.

We will then reference the SalesExprField in our chart using Dollar Sign Expansion (DSE). DSE is performed before the expression is evaluated. Our chart expression is now:

Sum($(=SalesExprField))

The “=” within the DSE says to evaluate this as an expression. In other words, substitute in the value of the SalesExprField and then evaluate the Sum().

Do you want to see what DSE is actually substituting? In a Straight Table, clear the Label field. The substituted expression will be visible in the column heading.

If we are not sure that “Always On Selected” is guaranteed, we should use some type of aggregation function to ensure a single SalesExprField is selected. For example, to take the first possible value:

Sum($(=FirstSortedValue(DISTINCT SalesExprField,1)))

Instead of just parameters to  the sum() function, we could have included the entire expression in our island table,  eg “Sum(SalesAmount_LC + VAT_LC)”. In that case our chart expression would be:

$(=SalesExprField)

What if want to control options via variables instead of fields? Use a Set expression in the Only() function.

Sum(
$(=only({<CurrencyType={$(vCurrencyType)},[Include VAT?]={$(vIncludeVAT)}>}SalesExprField))
)

If you’ve read this far, you are probably wondering “Is there a downloadable example”. Yes, it can be found here. Qlikview Cookbook: How to Choose an Expression.

-Rob

Want more performance tips?  Come see Oleg Troyansky’s Performance Tuning session and  additional tips  from other presenters at the “Masters Summit for Qlikvew”.

Share

How Not to Choose an Expression

We sometimes have a  requirement to select between two or more expressions  dependant on user selections or some other condition. For example, this chart Expression.

if(vWithCommission=1
 // Calculate with Commision
 ,sum({<CommissionFlag={1}>}
     SalesAmount - SalesAmount * CommissionRate)
 // Calculate without Commission
 ,sum(SalesAmount)
 )

The  if()  will select one or the other sum() expression based on the value of the vWithCommmision variable.  Because a variable is being tested —  not a row value — only one sum() will be chosen for the entire chart.

If performance is important,  this is not a good way to implement the requirement. QlikView does not “short circuit”. Short circuit means to stop evaluating when the condition is true. QlikView will calculate both sums and then return one of those results.

Some people mistakenly believe that putting the above expression in a variable changes the behavior. This is incorrect. The if() evaluation is still done at the chart level and the performance impact remains.

A performant way to solve the requirement is to put each calculation into a separate chart Expression and use the  Conditional property to select the Expression.

An Expression with  a Conditional evaluating to False will not be calculated or displayed.

There is also the possibility of choosing the calculation in a variable, but you have to follow a few rules.

  1. The variable should return the string representation of the formula. Note the single quotes in the example below.
  2. The variable definition should begin with “=”. This causes the if() to be evaluated only once.
  3. In the chart Expression, reference to the variable should be made with $(). eg  $(vChooseCalc)
=if(vWithCommission=1
    ,'sum({<CommissionFlag={1}>}
        SalesAmount - SalesAmount * CommissionRate)'
    ,'sum(SalesAmount)'
)

-Rob

For more performance tips, join us at the upcoming “Masters Summit for Qlikvew”  in San Francisco May 2015 where Oleg Troyansky presents an always enlightening session on Performance Tuning. Can’t make SF? Check out the other dates and locations on the website.

 

Share

Qlik Sense Opportunity for QlikView Customers

I had a great time participating in the Hackathon at the recent Qlik World Conference in Orlando. The Hackathon challenge was to create a visualization solution to a United Nations challenge using the Qik Sense Mashup APIs. It was a stimulating exercise for a number of reasons — the subject matter, the company of talented practitioners, and the Sense API ease of use and powerful functionality.

Through my experience with using the APIs and talking with a number of customers at the conference, I see a clear opportunity for existing QlikView customers to leverage Sense as an Extranet or Mashup solution.

Many QlikView customers have apps that currently deliver great value inside the company. These apps may be mature, data dense and backed by a sophisticated data model. Everyone is happy, but there may be some discussion about providing a subset of the solution to external users like B2B customers over the web.   That has been  possible with QlikView, but it can be to be complex to implement. It’s much easier with Sense and I think Sense could be the killer solution for extranet reuse. Here’s why:

  • The existing QlikView data model can be reused by Sense with a simple Binary Load. No need to write additional script and you maintain a single-version-of-truth for both internal and external users.
  • The sense charts and visualizations are much more “webby” in appearance and behavior,  meeting the modern expectations of web users and web developers alike.
  • The APIs are powerful, clearly designed and will be easily understood by web developers tasked with integrating Qlik content and data into portals or other  interface.
  • Better APIs to get data from the Qlik engine. For example, there are methods to create and return “hypercubes” of data. Pass in Dimensions and Expressions and calculated data is returned — without the need to create a chart. The returned data can be visualized or used to drive another process.
  • The new Session Authentication API can delegate user authentication to an existing portal session, eliminating the need for a piggybacking WebTicketing exchange. This satisfies the common customer requirement that “when the portal session ends, the Qlik session should end”.

-Rob

 

Share

Listbox Color Chips

I was recently poking around in the QlikView 11 demo “Social Media Data Analysis“.  This app was first brought to my attention in the excellent blog post “Use of a Silent Legend” by  Jennell McIntire.  I like how color is used to quickly create linkage between elements on the sheet. It’s one of my favorite tips.

Looking at the mechanics of the color & object construction, I thought that while fine for a demo, there were a few things I would do differently. One item in particular — the Company listbox — stood out because of a new technique available in QV11.

The listbox contains a color chip for each Company that maps to the color used in the charts. Very effective.

The color chips are constructed as 6 individual Text Objects. This is maybe the only possible way to get that particular effect in a V10 listbox.

However, that means that I, the challenged artist, have to line those boxes up and keep them aligned. It also means that I have to be very sensitive to the contents of the listbox changing.

V11 introduced Listbox Expressions which opens up a new option.  I took the individual color boxes and put them in  jpg files. I bundle loaded (embed in the qvw) the images with this script:

Images:
bundle info load * inline [
Company, image
Company A,image\Square_Orange.jpg
Company B,image\Square_Blue.jpg
Company C,image\Square_Green.jpg
Company D,image\Square_Brown.jpg
Company E,image\Square_Red.jpg
My Company,image\Square_Purple.jpg
];

Next step was to add this Expression to the listbox:

='qmem://Company/' & Company

and select “Image” for the Expression Representation.

And now my color chips are an integral part of the listbox. Also, the chips now disappear for excluded values which is consistent with the visual behavior of the rest of the sheet.

             

I won’t be surprised if commenters come up with an even better way 🙂

-Rob

Share

Qvc Gets Colorful

Qlikview allows customization of the basic eighteen color palette at the Document or User level through property dialogs. For color control beyond the palette,  many developers utilize variables.

The set of colors and variables I use for a document or project I refer to as a “color theme”.  I’ve built up several themes over the years as well as generously borrowed theme ideas from others.

Wait! Isn’t there an single ideal theme we should all use? No. I find a regular need to update or craft new themes in response to client requirements, the latest understanding of best practices, and frankly, fashion. 

In V9 of the Qlikview Components (Qvc) scripting library I’ve added a color theming routine.  The SUB Qvc.ColorTheme(themeFile) uses an external file to define color variables. The variables are then referenced by chart objects to implement the theme.

Implementing a color theme with Qvc requires two actions; assigning colors to the variables and assigning the variables to sheet objects.

Qvv.ColorTheme takes it’s input from an xlsx or xlsm file that contains at least these two columns:

ColorVariable — A variable name. Any variable name matching the pattern Qvc.Color.v.* will be kept by the routine. Other variable names may be used as intermediate names to compute final values.

ColorValue — a valid Qlikview script color function such as rgb(0,0,0) or white().

A sample theme is provided with the Qvc distribution in etc\Colors\ColorSample1.xlsm. This sample file also offers the option to use the Excel color picker to assign a color.

In the sample file you’ll see:

Specific colors defined early in the file that are referenced later:

“Logical” color variables that define “good” and “bad” things. 

“Object Attributes” that define items like the chart 18 color palette.

After including the qvc.qvs runtime we can add the script statement

CALL Qvc.ColorTheme('ColorSample1.xlsm')

and then reload. Great! Now our document contains a bunch of Qvc.Color.v.* variables with proper color values. How do we tell our object color properties to use those variables? Do we have to type them in each object? No.

Also included with the Qvc distribution is etc\QvcColor.qvt, a QV theme file that assigns the Qvc.Color.* variable names to object definition. You apply this qvt theme to your Document as you would any other qvt theme, using the “Layout, Apply Theme” button. Apply Theme is available at the Document level (Settings, Document Properties) or at the individual object level on the layout tab.

After pressing “Apply Theme”, select and apply the etc\QvcColors.qvt file. After Apply, you’ll see that color properties in the object (or all objects if done in Document Settings) reference the Qvc.Color.* properties.

Changes to the theme file will be reflected in the object colors after reload.

You may also assign the QvcColor.qvt theme as the default document theme for new objects in “Settings, Document Properties, Presentation”. This is particularly useful if you are starting a new document.

If you develop a color theme you find useful, please let me know on the QVC User Forum and I’ll include your theme as a sample in a future release.

-Rob

I’m now teaching a 3 hour on-line course on using the QVC library at http://q-on.bi/. The next course is scheduled for 7 Nov. See http://q-on.bi/courses/qlikview-components-scripting-library/ for details.

Share