To avoid having to create very complex Set Analysis, it can be quite a good idea to create flags in your script.  Doing the complex calculation in the script to create a simple 1 or 0 value means it happens once - when your users are not involved - and makes the front end calculations a lot quicker - when your users are involved.
Sometimes we want to dual-purpose that flag field.  As well as having the value of 1 or 0, we want to allow the users to select the field.  "1" and "0" are not very friendly so we want to have the users click on something like "Yes"/"No" or "True"/"False".  There are a few ways of achieving this:
1.  Just create the 1 or 0 in the script and in the front-end use an Expression in the list box like:
   If(Flag=1, 'True', 'False')
This works fine but, of course, is putting some calculation back into the front-end.  While it is not an arduous calculation, it will re-calculate on all selections so it does add some clock cycles.  It also makes no impact on how you would use the value in Set Analysis so I don't need to worry about this option any further in this post.
2.  Create the 1 or 0 in the Flag field and create a 2nd field (e.g. Flag_Text) with the text values that you want.  The user gets to select the value from Flag_Text, but we use the Flag value in Set Expressions.
There are a couple of issues with this.  First off, it adds additional overhead in the Script because we need to do the same calculation twice and create 2 fields.  Secondly, if we use the Flag value in a Set, we need to ensure that we also exclude the Flag_Text value from that set:
   Sum({<Flag={1}, Flag_Text=>} Sales)
There is also the possibility that a user using collaboration features might add the Flag field as a list box and that might cause confusion.
3.  Instead of creating the values as 1 or 0, we create Dual values:
   ...
   If(Condition=True, Dual('Yes',1), Dual('No',0)) As Flag,
   ...
This is more efficient because everything happens in the script and we are only creating the one field there from one piece of code.
There is a complication though in your Set Analysis.  You would like to do something like this:
   Sum({<Flag={1}>} Sales)
But it will now fail!  This is because the set comparison always compares against the text value of a dual (except for Dates - more of that below).  That means that you would have to use:
   Sum({<Flag={'Yes'}>} Sales)
Of course, this is a text comparison so will not execute as efficiently as a numeric one.  What can we do?
Well, we can force the calculation to be numeric by using a search syntax instead of the actual value and that search should involve > or <.  For example:
   Sum({<Flag={">0"}>} Sales)
Will work!
Interestingly, this does not work immediately with a date value that has been created with one of the date functions (like Date(), MakeDate, etc.)  I am not totally sure of why but I suspect that this is handled differently because the system recognizes it as a date (so it understands what ">2/6/2013" means) and doesn't handle the same way as other numeric Duals. 
This means that we often need to add formatting into a date set to get it to work.  Like this:
   Sum({<Date={$(=Date(vDate,'M/D/YYYY'))}>} Sales)
We can override this and make our dates handle like other Duals by loading them as a Dual explicitly in the Script.  Instead of this:
   ...
   Date(date_field) As Date,
   ...
We can do this:
   ...
   Dual(Date(date_field), Num(date_field)) As Date,
   ...
Have fun!
Stephen Redmond is author of QlikView for Developer's Cookbook
He is CTO of CapricornVentis a 
QlikView Elite Partner.  We are always looking for the right people to join our team.
Follow me on Twitter: @stephencredmond
 
 
Hi Stephen,
ReplyDeletethanks for your interesting post. I have one question, why do you think "Of course, this is a text comparison so will not execute as efficiently as a numeric one"?
IMHO, this should be mutch faster than evaluating a search expression.
Best regards,
Ralf
Hi Ralf,
ReplyDeleteI have tested both on a simple dataset of about 10million rows and the {">0"} set executes about 20% faster than the {'Yes'} comparison.
Regards,
Stephen