<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-5070255803043802824</id><updated>2012-01-24T15:48:57.339-08:00</updated><category term='tuning'/><category term='layout'/><category term='Few'/><category term='group'/><category term='qlikview'/><category term='Qlikview qvw'/><category term='Tufte'/><title type='text'>Qlikview Notes</title><subtitle type='html'>A collection of notes about my experience with Qlikview</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://qlikviewnotes.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://qlikviewnotes.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Rob Wunderlich</name><uri>http://www.blogger.com/profile/13048694338956825695</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://3.bp.blogspot.com/_IhQc1-zXHmU/SwH7Z2D8lUI/AAAAAAAAADo/UY17XpuzKLw/S220/avatar.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>42</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-5070255803043802824.post-4284939051819660611</id><published>2012-01-18T22:01:00.000-08:00</published><updated>2012-01-18T22:14:24.460-08:00</updated><title type='text'>Incremental Load using Qlikview Components</title><content type='html'>&lt;a href="http://qlikviewcomponents.org/" target="_blank"&gt;Qlikview Components&lt;/a&gt;&amp;nbsp;(Qvc)&amp;nbsp;&amp;nbsp;is a script library that simplifies and improves the quality of Qlikview scripting. You can read an introduction to Qvc &lt;a href="http://qlikviewnotes.blogspot.com/2012/01/introducing-qlikview-components.html" target="_blank"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Today I'll show you how to do Incremental Load (IL) using Qvc. Incremental Load means extracting only the latest changes from a database table and merging those changes with a master QVD file. Writing your own IL script can be rather tedious and frequently involves copy/paste operations followed by forgetful edit errors. Qvc can make it much easier.&lt;br /&gt;&lt;br /&gt;Incremental Load is not necessary for every table. We typically use IL for large source tables. IL can reduce the elapsed reload time and impact on the database system by loading only new or updated rows.&lt;br /&gt;&lt;br /&gt;To utilize Incremental Load a source table must have both of the following attributes:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;A unique identifier -- a Primary Key -- for each row.&amp;nbsp;&lt;/li&gt;&lt;li&gt;A "Modification" &amp;nbsp;column that identifies when a row was added or updated. The column type may be a Date, Datetime or ascending Revision number.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;The classic IL logic is this:&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;Determine the "Last reload Time". The most robust technique is to extract the max value for the "Modification" column from the Master QVD.&lt;/li&gt;&lt;li&gt;Select rows from the database table where "Modification" is greater than "Last Reload Time".&lt;/li&gt;&lt;li&gt;Add and update rows in the Master QVD, based on primary key.&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;Here is the complete Incremental Load script using Qvc.&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #6aa84f; font-family: 'Courier New', Courier, monospace;"&gt;// Include Qvc code&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;$(Include=..\qvc_runtime\qvc.qvs)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #6aa84f; font-family: 'Courier New', Courier, monospace;"&gt;// Calling parameters are QVTablename, UpdateColumn, PrimaryKey.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;CALL Qvc.IncrementalSetup ('Rates', 'LastUpdate', 'RateId'); &amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #6aa84f; font-family: 'Courier New', Courier, monospace;"&gt;// v.Tablename is set by IncrementalSetup&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;[$(Qvc.Loader.v.Tablename)]:&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-tab-span" style="color: #6aa84f; white-space: pre;"&gt;// Whatever LOAD and SELECT goes here &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;SQL SELECT * FROM dbo.RateTable&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #6aa84f; font-family: 'Courier New', Courier, monospace;"&gt;// v.IncrementalExpression is set by IncrementalSetup&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;WHERE $(Qvc.Loader.v.IncrementalExpression)&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #6aa84f; font-family: 'Courier New', Courier, monospace;"&gt;// Update the QVD with the changed rows&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;CALL Qvc.IncrementalStore&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;That's it.&lt;br /&gt;&lt;br /&gt;You'll also get useful log messages telling you what was done.&lt;br /&gt;&lt;br /&gt;&lt;table bgcolor="#ffffff" border="1" bordercolor="#C0C0C0" cellpadding="2" cellspacing="0" style="font-size: 9pt;"&gt;&lt;tbody&gt;&lt;tr align="LEFT" bgcolor="#f5f5f5"&gt; &lt;th&gt;&lt;span style="color: #363636;"&gt;&lt;b&gt; &lt;b&gt;&lt;/b&gt;&lt;/b&gt;&lt;/span&gt;&lt;b&gt;&lt;/b&gt;&lt;/th&gt;&lt;/tr&gt;&lt;tr align="LEFT" bgcolor="#ffffff"&gt; &lt;td bgcolor="#ffffff" nowrap=""&gt;&lt;span style="font-size: xx-small;"&gt;&lt;span style="color: #363636;"&gt;00002 1/17/2012 1:23:46 PM; QVD\Rates.qvd exists, rows=31&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr align="LEFT" bgcolor="#ffffff"&gt; &lt;td bgcolor="#ffffff" nowrap=""&gt;&lt;span style="font-size: xx-small;"&gt;&lt;span style="color: #363636;"&gt;00003 1/17/2012 1:23:46 PM; Loading rows where LastUpdate &amp;gt;=''01/14/2011''&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr align="LEFT" bgcolor="#ffffff"&gt; &lt;td bgcolor="#ffffff" nowrap=""&gt;&lt;span style="font-size: xx-small;"&gt;&lt;span style="color: #363636;"&gt;00004 1/17/2012 1:23:46 PM; Rates loaded, rows=1&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr align="LEFT" bgcolor="#ffffff"&gt; &lt;td bgcolor="#ffffff" nowrap=""&gt;&lt;span style="color: #363636; font-size: xx-small;"&gt;00005 1/17/2012 1:23:46 PM; QVD\Rates.qvd updated, rows=31&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;br /&gt;Review the Qvc Documentation for explanation of parameters and configuration variables. The documentation also contains a working example.&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5070255803043802824-4284939051819660611?l=qlikviewnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qlikviewnotes.blogspot.com/feeds/4284939051819660611/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5070255803043802824&amp;postID=4284939051819660611' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/4284939051819660611'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/4284939051819660611'/><link rel='alternate' type='text/html' href='http://qlikviewnotes.blogspot.com/2012/01/incremental-load-using-qlikview.html' title='Incremental Load using Qlikview Components'/><author><name>Rob Wunderlich</name><uri>http://www.blogger.com/profile/13048694338956825695</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://3.bp.blogspot.com/_IhQc1-zXHmU/SwH7Z2D8lUI/AAAAAAAAADo/UY17XpuzKLw/S220/avatar.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5070255803043802824.post-1819045889734835343</id><published>2012-01-09T11:10:00.000-08:00</published><updated>2012-01-11T11:51:07.659-08:00</updated><title type='text'>The Power of Gray</title><content type='html'>I'm sometimes asked by developers "How do I make un-associated (gray)&amp;nbsp;data&amp;nbsp;disappear from listboxes?". After some discussion as to why they want to do this, I usually attempt to convince&amp;nbsp;them to not hide any data.&lt;br /&gt;&lt;br /&gt;Gray data is an important part of the power of Qlikview -- the associative experience. &amp;nbsp;Associative is the way our mind connects data. When I try to recall a face I may narrow my candidates by an attribute like hair color or where we met. But I don't forget everyone else. I just take them out of focus.&lt;br /&gt;&lt;br /&gt;I recall one of my first Qlikview "Wow!" moments when I saw the power of the associative process. I was working with a Industrial Safety analyst who was studying the effectiveness of various glove styles in preventing hand injuries. We had a database of injuries and a&amp;nbsp;separate&amp;nbsp;dataset of glove models in use by period and location.&lt;br /&gt;&lt;br /&gt;Up to this point, the analyst had been working from static reports that counted injuries of interest by looking for "where BodyPart='Hand'".&lt;br /&gt;&lt;br /&gt;We loaded the data into Qlikview. BodyPart &amp;nbsp;became a listbox. He selected "Hand" and the table charts displayed the same counts as the static reports. In the gray data we noticed a significant number of injuries for "Hend", a misspelling of "Hand". A simple click added those into the total. The analyst also discovered "finger" and "fingers" were of interest and added those. Furthermore, for certain glove styles -- those with a gauntlet sleeve -- &amp;nbsp;"forearm" should be added.&lt;br /&gt;&lt;br /&gt;With just a few clicks the Analyst had greater accuracy in this important work. It was the display of gray data that allowed this to happen, along with the ability to quickly convert gray to green (selected).&lt;br /&gt;&lt;br /&gt;So while there may be edge cases where it's necessary to hide gray data, I generally find that displaying all data in the associative manner is a unique and special advantage of Qlikview.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5070255803043802824-1819045889734835343?l=qlikviewnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qlikviewnotes.blogspot.com/feeds/1819045889734835343/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5070255803043802824&amp;postID=1819045889734835343' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/1819045889734835343'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/1819045889734835343'/><link rel='alternate' type='text/html' href='http://qlikviewnotes.blogspot.com/2012/01/power-of-gray.html' title='The Power of Gray'/><author><name>Rob Wunderlich</name><uri>http://www.blogger.com/profile/13048694338956825695</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://3.bp.blogspot.com/_IhQc1-zXHmU/SwH7Z2D8lUI/AAAAAAAAADo/UY17XpuzKLw/S220/avatar.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5070255803043802824.post-8264687515499171652</id><published>2012-01-05T18:07:00.000-08:00</published><updated>2012-01-05T18:07:55.302-08:00</updated><title type='text'>Easy Period Analysis using Qlikview Components</title><content type='html'>&lt;span style="font-family: Verdana, sans-serif;"&gt;If you think coding complex Set Analysis expressions and writing repetitive script is an efficient use of your QV development time, then this post is not for you. Go back to memorizing pi or whatever it was you were working on. For the rest of us, read on.&lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;With Qlikview Components (Qvc)&amp;nbsp;you can &lt;b&gt;quickly &lt;/b&gt;build all the parts needed for many point in time and period over period analyses. Let's walk through an example.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;Download the latest distribution (this article require &lt;b&gt;V0.7+&lt;/b&gt;) of Qvc&amp;nbsp;from the download link at&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="color: #0000ee; font-family: Verdana, sans-serif;"&gt;&lt;u&gt;http://qlikviewcomponents.org.&amp;nbsp;&lt;/u&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;Unzip the distribution file anywhere on your disk. If you are new to Qvc, start by reading the ReadMe file.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;Let's assume our QVW contains a fact table of Orders with a field named "OrderDate" that we will use as the date for period reporting.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;Add this include at the beginning of the script to bring in the Qvc routines.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt; $(Include=..\qvc_runtime\qvc.qvs);&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;After loading the fact table, generate a Master Calendar with this call:&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;CALL Qvc.CalendarFromField('OrderDate');&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;The Qvc.CalendarFromField routine will build a calendar with dimension fields named &amp;nbsp;OrderDate, Day, Month, Year, Year-Month and Quarter. You can optionally include a language file to use your local language for the fieldnames -- in this example Swedish.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;$(Include=..\qvc_runtime\language\qvc_language_SE.qvs);&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;Now that we have a calendar, we can use any of the calendar fields in listboxes or chart dimensions. And... Qvc.CalendarFromField() also creates a collection of set analysis expressions stored in variables. The variables follow the naming convention &lt;/span&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;vSet&lt;i&gt;Period&lt;/i&gt;&lt;/span&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;. For example:&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;vSetYTD&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;vSetPreviousYearYTD&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;The documentation for &lt;b&gt;Qvc.Calendar&lt;/b&gt; provides a list of all generated &lt;/span&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;vSet*&lt;/span&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt; variables.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;These variables in a chart expression like:&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;=Sum(Sum($(vSetPreviousYearYTD) OrderQuantity)&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;which will sum up OrderQuantity for YTD of the previous year. The actual set analysis expression is rather lengthy but the variable is compact.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;I'd like to credit Mike over at iQlik for first teaching me the set analysis variable idea at&amp;nbsp;&lt;a href="http://iqlik.wordpress.com/2011/01/01/point-in-time-reporting-out-of-the-box/"&gt;http://iqlik.wordpress.com/2011/01/01/point-in-time-reporting-out-of-the-box/&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;Now we can quickly whip up a chart like this without coding any of the complex stuff:&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-b-bF_nAYLlQ/TwZSVzGVVuI/AAAAAAAAALs/2R0nAFA687c/s1600/PITchart.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="170" src="http://4.bp.blogspot.com/-b-bF_nAYLlQ/TwZSVzGVVuI/AAAAAAAAALs/2R0nAFA687c/s400/PITchart.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;The documentation&amp;nbsp;supplied with Qvc provides examples for all Qvc routines. On the Documentation.qvw "Details" sheet select Qvc.CalendarFromField. You'll be able to open a sample qvw where you can explore the vSet variables and learn how they interact with selections.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;If you have comments or questions about Qvc, use the User Forum found on the project page.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5070255803043802824-8264687515499171652?l=qlikviewnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qlikviewnotes.blogspot.com/feeds/8264687515499171652/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5070255803043802824&amp;postID=8264687515499171652' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/8264687515499171652'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/8264687515499171652'/><link rel='alternate' type='text/html' href='http://qlikviewnotes.blogspot.com/2012/01/easy-period-analysis-using-qlikview.html' title='Easy Period Analysis using Qlikview Components'/><author><name>Rob Wunderlich</name><uri>http://www.blogger.com/profile/13048694338956825695</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://3.bp.blogspot.com/_IhQc1-zXHmU/SwH7Z2D8lUI/AAAAAAAAADo/UY17XpuzKLw/S220/avatar.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-b-bF_nAYLlQ/TwZSVzGVVuI/AAAAAAAAALs/2R0nAFA687c/s72-c/PITchart.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5070255803043802824.post-8350100258038987488</id><published>2012-01-02T17:39:00.000-08:00</published><updated>2012-01-02T22:28:49.292-08:00</updated><title type='text'>Introducing Qlikview Components</title><content type='html'>&lt;span style="font-family: Verdana, sans-serif;"&gt;Qlikview Components is a set of Qlikview scripting subroutines. I started this project to address two problems.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;As a Consultant, I've written and left behind QV script for many different customers. I frequently use script subroutines for common tasks to simplify implementation and maintenance. As &amp;nbsp;Qlikview (and me) grows and matures, better scripting approaches and product features become available. What's missing is an effective way to feed those improvements back in to the various versions of code I've spawned in the world.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;Another problem is that the flexibility of scripting is also a curse. There are &lt;i&gt;many&lt;/i&gt;&amp;nbsp;ways to do the same thing. What's the "best" way? Do we all need to learn that variable loop and load thing? Many script tasks are like plumbing in a building. They are not that interesting (my apologies to Plumbers) but it is essential that they work correctly. We want to get them done quickly and move on to the interesting bits.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;How to address these problems? Enter "Qlikview Components" (Qvc), an open source (free) project. Here's the mission statement from the project home page:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="background-color: white; font-family: arial, sans-serif; font-size: 14px; line-height: 1.25em; max-width: 64em;"&gt;&lt;b&gt;The mission of Qlikview Components is:&lt;/b&gt;&lt;/div&gt;&lt;ul style="background-color: white; font-family: arial, sans-serif; font-size: 14px; max-width: 62em; padding-left: 25px;"&gt;&lt;li style="margin-bottom: 0.3em;"&gt;&lt;b&gt;Implement scripting best practices encapsulated by a simple and stable API.&lt;/b&gt;&lt;/li&gt;&lt;li style="margin-bottom: 0.3em;"&gt;&lt;b&gt;Improve the speed and quality of script development.&lt;/b&gt;&lt;/li&gt;&lt;li style="margin-bottom: 0.3em;"&gt;&lt;b&gt;Create common ground between script developers.&lt;/b&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;span style="background-color: white; font-family: arial, sans-serif; font-size: 14px; line-height: 16px;"&gt;&lt;b&gt;QVC aims to serve the needs of the "big middle" of script tasks. Not the simple tasks, not the very complex tasks, but the garden variety common needs found in many scripts.&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="background-color: white; font-family: arial, sans-serif; font-size: 14px; line-height: 16px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: 15px;"&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;As an open source (OS) project, we have the opportunity to capture and redistribute the broad knowledge of the Qlikview Community. What do I see as the strengths of this project?&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;&lt;span style="font-size: 15px;"&gt;The broadest possible input for design, validation and improvement of code. The project is hosted on google-code and allows for multiple developers around the world to contribute to the project.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;&lt;span style="font-size: 15px;"&gt;A stable API. We're committed to&amp;nbsp;continuous&amp;nbsp;improvement &lt;b&gt;and&lt;/b&gt;&amp;nbsp;compatibility.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;&lt;span style="font-size: 15px;"&gt;A unit testing regime that ensures quality.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;&lt;span style="font-size: 15px;"&gt;All the supporting pieces one would expect in a serious project -- documentation, examples, localization, issue tracking, discussion groups, formal testing and build systems.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;&lt;span style="font-size: 15px;"&gt;Qlikview Components is currently in a "Preview" stage with a target for first production release on Feb 1, 2012. You can find the project at&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;&lt;span style="font-size: 15px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;&lt;span style="font-size: 15px;"&gt;&amp;nbsp; &lt;a href="http://qlikviewcomponents.org/"&gt;http://QlikviewComponents.org&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;&lt;span style="font-size: 15px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;&lt;span style="font-size: 15px;"&gt;That address will redirect to the hosting site on google-code where you'll find downloads and links to discussions.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;&lt;span style="font-size: 15px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;&lt;span style="font-size: 15px;"&gt;I'll be blogging more on Qvc in the coming weeks. In the meantime, here's a taste of what it takes to build a typical master calendar using Qvc.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;&lt;span style="font-size: 15px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: 15px;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;$(Include=..\qvc_runtime\qvc.qvs);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: 15px;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;// Load fact tables, etc.....&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 15px;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: 15px;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;CALL Qvc.CalendarFromField('ClosingDate');&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;&lt;span style="font-size: 15px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;&lt;span style="font-size: 15px;"&gt;I hope you'll find Qvc useful and look forward to hearing your ideas for improvement in the discussion groups!&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;&lt;span style="font-size: 15px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;&lt;span style="font-size: 15px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;&lt;span style="font-size: 15px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;&lt;span style="font-size: 15px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;&lt;span style="font-size: 15px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: 15px;"&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-size: 15px;"&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5070255803043802824-8350100258038987488?l=qlikviewnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qlikviewnotes.blogspot.com/feeds/8350100258038987488/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5070255803043802824&amp;postID=8350100258038987488' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/8350100258038987488'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/8350100258038987488'/><link rel='alternate' type='text/html' href='http://qlikviewnotes.blogspot.com/2012/01/introducing-qlikview-components.html' title='Introducing Qlikview Components'/><author><name>Rob Wunderlich</name><uri>http://www.blogger.com/profile/13048694338956825695</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://3.bp.blogspot.com/_IhQc1-zXHmU/SwH7Z2D8lUI/AAAAAAAAADo/UY17XpuzKLw/S220/avatar.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5070255803043802824.post-4097232810431768424</id><published>2011-12-28T20:08:00.000-08:00</published><updated>2011-12-28T21:03:51.346-08:00</updated><title type='text'>Initial Selections and Current Selections</title><content type='html'>&lt;span style="font-family: Verdana, sans-serif;"&gt;I've posted in the past about setting "dynamic" (based on date) initial selections. The easiest method from the Developer perspective is to apply search expressions, save them in a bookmark, and apply the bookmark as an OnOpen action.&amp;nbsp;The bookmark may also be selected by the user at any time to return to initial selections.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;For example, to select the current year and month:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;=Year=year(today(1))&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;=Month=month(today(1))&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;This selects the correct Year and Month. However, the current selections display is poor. &amp;nbsp;The search expression, rather than results, is displayed in the Current Selections box.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-2ntbw8_BNE4/TvvwfHSms2I/AAAAAAAAALI/ESMmEuwRyn4/s1600/Ugly+Selections.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="102" src="http://3.bp.blogspot.com/-2ntbw8_BNE4/TvvwfHSms2I/AAAAAAAAALI/ESMmEuwRyn4/s400/Ugly+Selections.PNG" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;Alternatively, those same dynamic selections can be&amp;nbsp;achieved&amp;nbsp;via Actions assigned to the Document OnOpen Trigger. Using Actions will present a cleaner current selections view. Here are the two Actions we should assign to OnOpen to achieve the same selections -- but with a better looking current selections display at the end.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-lUXwMQB6WRg/Tvvpu8dMIeI/AAAAAAAAAKY/c-3_raLX0T4/s1600/Action+Year.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="68" src="http://2.bp.blogspot.com/-lUXwMQB6WRg/Tvvpu8dMIeI/AAAAAAAAAKY/c-3_raLX0T4/s400/Action+Year.PNG" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-lWqZnFt2neM/Tvvw8_JmGjI/AAAAAAAAALU/XPhXRhw_dFs/s1600/Action+Month.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="66" src="http://2.bp.blogspot.com/-lWqZnFt2neM/Tvvw8_JmGjI/AAAAAAAAALU/XPhXRhw_dFs/s400/Action+Month.PNG" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;The Current Selections Display will now be much more comprehensible to the user.&lt;/span&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-nL--vW5l1ns/Tvvxd1B5o4I/AAAAAAAAALg/7FcYz_Zp6Ck/s1600/Nice+Selections.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="61" src="http://3.bp.blogspot.com/-nL--vW5l1ns/Tvvxd1B5o4I/AAAAAAAAALg/7FcYz_Zp6Ck/s400/Nice+Selections.PNG" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;Can we provide a way for the user to return to the dynamic initial selections by utilizing a bookmark? Yes we can. Create a new bookmark, assign it an appropriate name (like "Current Period") and note its ID (for example "BM02" -- from the Bookmark, More menu). Add one more action to the OnOpen trigger.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/-gX9_Ot3l-58/TvvvFd5MbrI/AAAAAAAAAK8/41sad8BMuco/s1600/Action+Bookmark.PNG" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="50" src="http://3.bp.blogspot.com/-gX9_Ot3l-58/TvvvFd5MbrI/AAAAAAAAAK8/41sad8BMuco/s400/Action+Bookmark.PNG" width="400" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;The selection values will be calculated and the bookmark updated with the new values each time the document is opened.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;-Rob&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5070255803043802824-4097232810431768424?l=qlikviewnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qlikviewnotes.blogspot.com/feeds/4097232810431768424/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5070255803043802824&amp;postID=4097232810431768424' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/4097232810431768424'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/4097232810431768424'/><link rel='alternate' type='text/html' href='http://qlikviewnotes.blogspot.com/2011/12/initial-selections-and-current.html' title='Initial Selections and Current Selections'/><author><name>Rob Wunderlich</name><uri>http://www.blogger.com/profile/13048694338956825695</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://3.bp.blogspot.com/_IhQc1-zXHmU/SwH7Z2D8lUI/AAAAAAAAADo/UY17XpuzKLw/S220/avatar.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-2ntbw8_BNE4/TvvwfHSms2I/AAAAAAAAALI/ESMmEuwRyn4/s72-c/Ugly+Selections.PNG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5070255803043802824.post-3799197303526223061</id><published>2011-10-05T20:21:00.000-07:00</published><updated>2011-10-05T20:26:16.964-07:00</updated><title type='text'>Correct Time Arithmetic</title><content type='html'>&lt;div&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;Each time value in Qlikview has &amp;nbsp;both an external display string value and an internal numeric value. The numeric value ranges from 0 to 1 and is calculated as time/24 hours. &amp;nbsp;For example, 12 noon is represented as 0.50.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;span class="Apple-style-span"&gt;Rounding during arithmetic can yield time values that share the same same external string but have a different underlying numeric value.&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span"&gt;The numeric value is used to group values in listboxes and chart dimensions. This is why you can sometimes see the time "01:00" display twice in a listbox or chart dimension!&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;Both of the time values below will display as "8:00:00 AM". But they will not group together in the same dimension bucket on a chart.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;8/24 =&amp;nbsp;0.33333333333333&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;MakeTime(8) =&amp;nbsp;0.33333333334303&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;I've seen a number of methods to do time and interval calculation. Some methods will have problems with certain time values.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;Look at some examples below and how they would match up with QV times, such as those read from databases or created by QV time functions.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;table bgcolor="#ffffff" border="1" bordercolor="white" cellpadding="0" cellspacing="0" style="font-size: 9pt;"&gt;&lt;tbody&gt;&lt;tr align="LEFT" bgcolor="#ffffff"&gt; &lt;td bgcolor="#ffffff"&gt;&lt;span style="color: #363636;"&gt;MakeTime(8)&lt;/span&gt; &lt;/td&gt;&lt;td align="CENTER" bgcolor="#ffffff"&gt;&lt;span style="color: #363636;"&gt;  = &amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;/td&gt;&lt;td bgcolor="#ffffff"&gt;&lt;span style="color: #363636;"&gt;time#('08', 'hh') &amp;nbsp; &amp;nbsp;&lt;/span&gt; &lt;/td&gt;&lt;td bgcolor="#ffffff"&gt;&lt;span style="color: #363636;"&gt;True&lt;/span&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr align="LEFT" bgcolor="#ffffff"&gt; &lt;td bgcolor="#ffffff"&gt;&lt;span style="color: #363636;"&gt;MakeTime(8)&lt;/span&gt; &lt;/td&gt;&lt;td align="CENTER" bgcolor="#ffffff"&gt;&lt;span style="color: #363636;"&gt;  =  &lt;/span&gt; &lt;/td&gt;&lt;td bgcolor="#ffffff"&gt;&lt;span style="color: #363636;"&gt;8/24&lt;/span&gt; &lt;/td&gt;&lt;td bgcolor="#ffffff"&gt;&lt;span style="color: #363636;"&gt;False&lt;/span&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr align="LEFT" bgcolor="#ffffff"&gt; &lt;td bgcolor="#ffffff"&gt;&lt;span style="color: #363636;"&gt;MakeTime(8) - MakeTime(1)&lt;/span&gt; &lt;/td&gt;&lt;td align="CENTER" bgcolor="#ffffff"&gt;&lt;span style="color: #363636;"&gt;  =  &lt;/span&gt; &lt;/td&gt;&lt;td bgcolor="#ffffff"&gt;&lt;span style="color: #363636;"&gt;MakeTime(7)&lt;/span&gt; &lt;/td&gt;&lt;td bgcolor="#ffffff"&gt;&lt;span style="color: #363636;"&gt;False&lt;/span&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr align="LEFT" bgcolor="#ffffff"&gt; &lt;td bgcolor="#ffffff"&gt;&lt;span style="color: #363636;"&gt;MakeTime(4) - MakeTime(1)&lt;/span&gt; &lt;/td&gt;&lt;td align="CENTER" bgcolor="#ffffff"&gt;&lt;span style="color: #363636;"&gt;  =  &lt;/span&gt; &lt;/td&gt;&lt;td bgcolor="#ffffff"&gt;&lt;span style="color: #363636;"&gt;MakeTime(3)&lt;/span&gt; &lt;/td&gt;&lt;td bgcolor="#ffffff"&gt;&lt;span style="color: #363636;"&gt;True&lt;/span&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr align="LEFT" bgcolor="#ffffff"&gt; &lt;td bgcolor="#ffffff"&gt;&lt;span style="color: #363636;"&gt;time#('08','hh') - 1/24&lt;/span&gt; &lt;/td&gt;&lt;td align="CENTER" bgcolor="#ffffff"&gt;&lt;span style="color: #363636;"&gt;  =  &lt;/span&gt; &lt;/td&gt;&lt;td bgcolor="#ffffff"&gt;&lt;span style="color: #363636;"&gt;time#('07','hh')&lt;/span&gt; &lt;/td&gt;&lt;td bgcolor="#ffffff"&gt;&lt;span style="color: #363636;"&gt;False&lt;/span&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr align="LEFT" bgcolor="#ffffff"&gt; &lt;td bgcolor="#ffffff"&gt;&lt;span style="color: #363636;"&gt;time#('04','hh') - 1/24&lt;/span&gt; &lt;/td&gt;&lt;td align="CENTER" bgcolor="#ffffff"&gt;&lt;span style="color: #363636;"&gt;  =  &lt;/span&gt; &lt;/td&gt;&lt;td bgcolor="#ffffff"&gt;&lt;span style="color: #363636;"&gt;time#('03','hh')&lt;/span&gt; &lt;/td&gt;&lt;td bgcolor="#ffffff"&gt;&lt;span style="color: #363636;"&gt;False&lt;/span&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr align="LEFT" bgcolor="#ffffff"&gt; &lt;td bgcolor="#ffffff"&gt;&lt;span style="color: #363636;"&gt;time#('08','hh') - time#('01','hh')&lt;/span&gt; &lt;/td&gt;&lt;td align="CENTER" bgcolor="#ffffff"&gt;&lt;span style="color: #363636;"&gt;  =  &lt;/span&gt; &lt;/td&gt;&lt;td bgcolor="#ffffff"&gt;&lt;span style="color: #363636;"&gt;time#('03','hh')&lt;/span&gt; &lt;/td&gt;&lt;td bgcolor="#ffffff"&gt;&lt;span style="color: #363636;"&gt;False&lt;/span&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr align="LEFT" bgcolor="#ffffff"&gt; &lt;td bgcolor="#ffffff"&gt;&lt;span style="color: #363636;"&gt;time#('12','hh') - MakeTime(3)&lt;/span&gt; &lt;/td&gt;&lt;td align="CENTER" bgcolor="#ffffff"&gt;&lt;span style="color: #363636;"&gt;  =  &lt;/span&gt; &lt;/td&gt;&lt;td bgcolor="#ffffff"&gt;&lt;span style="color: #363636;"&gt;time#('09','hh')&lt;/span&gt; &lt;/td&gt;&lt;td bgcolor="#ffffff"&gt;&lt;span style="color: #363636;"&gt;True&lt;/span&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr align="LEFT" bgcolor="#ffffff"&gt; &lt;td bgcolor="#ffffff"&gt;&lt;span style="color: #363636;"&gt;time#('08','hh') - MakeTime(1)&lt;/span&gt; &lt;/td&gt;&lt;td align="CENTER" bgcolor="#ffffff"&gt;&lt;span style="color: #363636;"&gt;  =  &lt;/span&gt; &lt;/td&gt;&lt;td bgcolor="#ffffff"&gt;&lt;span style="color: #363636;"&gt;time#('09','hh')&lt;/span&gt; &lt;/td&gt;&lt;td bgcolor="#ffffff"&gt;&lt;span style="color: #363636;"&gt;False&lt;/span&gt; &lt;/td&gt;&lt;/tr&gt;&lt;tr align="LEFT" bgcolor="#ffffff"&gt; &lt;td bgcolor="#ffffff"&gt;&lt;span style="color: #363636;"&gt;time#(time(MakeTime(8) - MakeTime(1)))&lt;/span&gt; &lt;/td&gt;&lt;td align="CENTER" bgcolor="#ffffff"&gt;&lt;span style="color: #363636;"&gt;  =  &lt;/span&gt; &lt;/td&gt;&lt;td bgcolor="#ffffff"&gt;&lt;span style="color: #363636;"&gt;MakeTime(7)&lt;/span&gt; &lt;/td&gt;&lt;td bgcolor="#ffffff"&gt;&lt;span style="color: #363636;"&gt;True&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;The only reliable and 100% consistent method is the last line. The method is: use Qlikview functions to represent times and convert the result of calculations to time strings and back to time numbers again.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;Breaking down the &amp;nbsp;example:&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;b&gt;1&lt;/b&gt;.&lt;b&gt; &lt;/b&gt;MakeTime(8) - MakeTime(1) give us a display value of &amp;nbsp;7:00:00 AM. But as you can see previously in the table, it's internal value is not exactly equal to MakeTime(7) -- the value Qlikview considers to be 7 AM.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;b&gt;2&lt;/b&gt;. Convert the value of the calculation to a string using the time() function. The result is "7:00:00 AM".&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;b&gt;3&lt;/b&gt;. Convert the string into a numeric time using the time#() function. We now have the QV value for 7 AM which is equal to 7 AM read from a database or generated from any QV time function.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;The same problem and solution applies to Timestamps and Intervals.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;What we really need is a new "AddTime()" function, similar to the AddMonths() function. I sometimes create a variable function in my script to perform this function.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;SET AddTime=time#(time($1 + $2));&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;Then I can use it in script or charts as:&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;$(AddTime(mytime,-MakeTime(1)))&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;-Rob&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span"&gt;&lt;span class="Apple-style-span" style="font-family: Verdana, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5070255803043802824-3799197303526223061?l=qlikviewnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qlikviewnotes.blogspot.com/feeds/3799197303526223061/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5070255803043802824&amp;postID=3799197303526223061' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/3799197303526223061'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/3799197303526223061'/><link rel='alternate' type='text/html' href='http://qlikviewnotes.blogspot.com/2011/10/correct-time-arithmetic.html' title='Correct Time Arithmetic'/><author><name>Rob Wunderlich</name><uri>http://www.blogger.com/profile/13048694338956825695</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://3.bp.blogspot.com/_IhQc1-zXHmU/SwH7Z2D8lUI/AAAAAAAAADo/UY17XpuzKLw/S220/avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5070255803043802824.post-2269981582205316416</id><published>2011-06-05T16:59:00.000-07:00</published><updated>2011-07-26T21:52:17.537-07:00</updated><title type='text'>The Case Against Caption Icons</title><content type='html'>I avoid using Caption Icons in sheet Objects. I prefer to teach users to right-click to access the same functionality. In V10, there is also the option to use a &amp;nbsp;"Menu" caption icon that provides the same options as right-click.&lt;br /&gt;&lt;br /&gt;Here are my arguments for not using caption icons that duplicate the functionality available in right-click.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Note: I realize there are some limitations in the Ajax client prior to V9 that may require icons. My comments are directed at V9+.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;The redundancy and visual clutter waste screen space and distract from the data. If you are a fan of Edward Tufte's work, you'll recognize this as "low Data-ink ratio" and "Chartjunk".&lt;br /&gt;&lt;/li&gt;&lt;li&gt;They deemphasize icons that may be unique and important to a specific chart. These are things you want the user to notice, for example Help or Fast Change.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;They force the designer to display a Caption even when a Caption is not desirable for the layout.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;They keep users ignorant of the full power available, leading them to believe that they are limited to the functions offered by the displayed icons. Have you ever received a change request like "Please add the export to Excel function to chart X so we can export it."?&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Also on the ignorance theme, users don't become aware of new functionality if you don't add the new icons.&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;Comments and counter arguments welcome.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;-Rob&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5070255803043802824-2269981582205316416?l=qlikviewnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qlikviewnotes.blogspot.com/feeds/2269981582205316416/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5070255803043802824&amp;postID=2269981582205316416' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/2269981582205316416'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/2269981582205316416'/><link rel='alternate' type='text/html' href='http://qlikviewnotes.blogspot.com/2011/06/case-against-caption-icons.html' title='The Case Against Caption Icons'/><author><name>Rob Wunderlich</name><uri>http://www.blogger.com/profile/13048694338956825695</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://3.bp.blogspot.com/_IhQc1-zXHmU/SwH7Z2D8lUI/AAAAAAAAADo/UY17XpuzKLw/S220/avatar.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5070255803043802824.post-2198404129424495111</id><published>2011-05-11T18:22:00.000-07:00</published><updated>2011-05-13T13:33:56.535-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='qlikview'/><category scheme='http://www.blogger.com/atom/ns#' term='features'/><title type='text'>My Top Two Feature Requests</title><content type='html'>&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;There are a couple of missing features in QV that cause me to often bump my head against the ceiling. I have a great idea but then ouch -- can't make QV do that. Below are my top two feature requests. With all the cool, advanced, sophisticated ideas floating around out there, you may be surprised that my requests appear so basic.&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;b&gt;#1&lt;/b&gt;. An escaping or alternate syntax for string literals that contain single quotes. I frequently use script subroutines and variables with parameters to bring discipline to my QV projects. Parameters are passed as strings and variables are sometimes themselves function calls that contain quoted parameters. Nested routines make the problem even more complex.&lt;br /&gt;&lt;br /&gt;There is also a problem using SET and LET in script to define reusable expressions. The defined values often contain quotes.&lt;br /&gt;&lt;br /&gt;Quoted strings cannot contain quotes, so I resort to all kinds of workarounds -- &amp;amp; chr(39),&amp;nbsp;&amp;nbsp;proxy characters for quotes and using fields when I would really prefer variables. All of these are complex workarounds that make my code resemble the &lt;a href="http://www.hasbro.com/games/en_US/twister/"&gt;Twister&lt;/a&gt; game.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;#2&lt;/b&gt; Grouped Objects. So many great screen objects available. Wouldn't it be wonderful have a couple of charts, a listbox and an explanatory text box minimize &amp;amp; restore as a group? I've &lt;a href="http://qlikviewnotes.blogspot.com/2008/12/design-of-grouped-objects.html"&gt;blogged &lt;/a&gt;about this in the past if you want to read more on the topic. So much could be done in the UI with the addition of object groups.&lt;br /&gt;&lt;br /&gt;I've dropped both of these feature requests in various Qliktech "suggestion boxes" over the years. I have no idea if they will ever &amp;nbsp;be implemented or not. I frequently hear other users asking for #2, and I occasionally meet someone who shares my&amp;nbsp;desire&amp;nbsp;for #1.&lt;br /&gt;&lt;br /&gt;What are your top two feature wishes?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5070255803043802824-2198404129424495111?l=qlikviewnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qlikviewnotes.blogspot.com/feeds/2198404129424495111/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5070255803043802824&amp;postID=2198404129424495111' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/2198404129424495111'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/2198404129424495111'/><link rel='alternate' type='text/html' href='http://qlikviewnotes.blogspot.com/2011/05/my-top-two-qv-feature-requests.html' title='My Top Two Feature Requests'/><author><name>Rob Wunderlich</name><uri>http://www.blogger.com/profile/13048694338956825695</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://3.bp.blogspot.com/_IhQc1-zXHmU/SwH7Z2D8lUI/AAAAAAAAADo/UY17XpuzKLw/S220/avatar.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5070255803043802824.post-8939186855112421726</id><published>2011-05-02T15:29:00.000-07:00</published><updated>2011-05-02T15:29:47.894-07:00</updated><title type='text'>New Metadata in QV10</title><content type='html'>Qliktech is rolling out some exciting new metadata in Version 10 SR2.I've started poking around at the new data along with a new metadata scanner application that should be available to the Community next week.&lt;br /&gt;&lt;br /&gt;The most intriguing new feature is that certain information, such as source tables used in load statements, will now be available as XML data within each QVW. Object definitions, expressions and dimensions will also be available through the same XML mechanism.&lt;br /&gt;&lt;br /&gt;Qliktech will be providing a scanner application that will read the new XML data. In addition, the scanner will load information on existing QVDs, Server and Publisher logs and server tasks. The loaded tables form a single metadata model that can be used to feed reporting and analysis such as Ops Monitor.&lt;br /&gt;&lt;br /&gt;I'm excited about these changes on two fronts:&lt;br /&gt;&lt;br /&gt;1. The "missing" metadata -- data lineage -- is now starting to appear in the product. Up to this point, customers and consultants have created various schemes to track data lineage.&lt;br /&gt;&lt;br /&gt;2. I see the formal Qliktech metadata model, begun in V9, maturing to the point where it will become&amp;nbsp;accepted&amp;nbsp;as the standard.&lt;br /&gt;&lt;br /&gt;I'm looking forward to creating applications with the new data and will blog again as I learn more.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5070255803043802824-8939186855112421726?l=qlikviewnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qlikviewnotes.blogspot.com/feeds/8939186855112421726/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5070255803043802824&amp;postID=8939186855112421726' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/8939186855112421726'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/8939186855112421726'/><link rel='alternate' type='text/html' href='http://qlikviewnotes.blogspot.com/2011/05/new-metadata-in-qv10.html' title='New Metadata in QV10'/><author><name>Rob Wunderlich</name><uri>http://www.blogger.com/profile/13048694338956825695</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://3.bp.blogspot.com/_IhQc1-zXHmU/SwH7Z2D8lUI/AAAAAAAAADo/UY17XpuzKLw/S220/avatar.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5070255803043802824.post-8775988011846309270</id><published>2011-03-28T10:03:00.000-07:00</published><updated>2011-03-28T10:04:30.716-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Qlikview qvw'/><title type='text'>Document Compression</title><content type='html'>&lt;div class="MsoNormal"&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;Today I offer up a discussion of Qlikview “compression”. That is, the Qlikview features that make overall data get smaller, and in some cases, larger. &lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;Should you care? In most cases no. But understanding what “knobs you can turn” can be a useful tool for capacity planning and application tuning. Let’s look at the practices and parameters that affect data size.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;b style="mso-bidi-font-weight: normal;"&gt;&amp;nbsp;Script Execution:&lt;/b&gt;&amp;nbsp; Data read from sources – such as database tables – are read in to memory (RAM) by the script execution (reload) process. Duplicate values are reduced to the unique set of values for each column. A “Gender” column has only two values – “Female” and “Male”, so the storage required for this column is minimal compared to a column that has a wide range (cardinality) of values such as a timestamp.&amp;nbsp; This is not really “compression” but rather what I call “de-duplication”. &lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;The ratio of database storage to document storage is dependent on the data content as well as the use of common script techniques like separating timestamps into date and time fields. A typical database to document ratio is 10:1. For example, 2GB of database tables might require 200MB of document RAM. &lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;b style="mso-bidi-font-weight: normal;"&gt;QVW write to Disk:&lt;/b&gt; After reload, the Qlikview document (data tables and screen objects) is written from RAM to Disk as a *.qvw file. If compression is set on (default) for the document, the qvw will be compressed as it is written to disk. The compression results will vary depending on data content, but is typically in the range of 2-5 times. For example, a document that requires 200MB of RAM will require somewhere between 40MB and 100MB of Disk storage.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;If compression is set to “None”, the document will be written to disk in the same format it existed in RAM and will occupy the same storage on disk as it utilized in RAM. &lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;The Compression option for each Document is set in the Document Properties, General tab. The default compression for new documents is defined the User Settings, Save tab. &lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;The compression option will of course impact the amount of disk storage used. But it also affects the amount of time it takes to read or write a qvw. I find that for most documents, an uncompressed document will write and read significantly faster than a compressed document. Some documents, especially large ones with high compression ratios, will read faster if compressed. The other factor is speed of the disk being used – local disk or network disk. &lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;I typically do my development with compression off and then do a timing test with both options before migrating to the server. &lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;b style="mso-bidi-font-weight: normal;"&gt;QVW read from Disk: &lt;/b&gt;The *.qvw is loaded to RAM by a developer or on the Server by a user session. The amount of RAM required is the uncompressed size, regardless if compression was used to write the *.qvw to disk.&amp;nbsp; As discussed in the previous section, my experience is that uncompressed documents read from a local disk typically load up faster, but this is not always true and is worth testing on large documents. &lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;b style="mso-bidi-font-weight: normal;"&gt;­What is the compression factor for QVD files?&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;b style="mso-bidi-font-weight: normal;"&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;Zero. &lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;A &lt;b style="mso-bidi-font-weight: normal;"&gt;QVD&lt;/b&gt; file contains the physical representation of an in-memory Qlikview Table. This “RAM image” format is what allows an optimized QVD load to be so quick. The physical blocks of disk are read directly into Qlikview RAM, “ready to go”. Because QVD is the RAM image, there is no compression. &lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;A QVD read with an optimized load will require the same RAM size as its size on disk (1:1). A QVD read with an un-optimized load will usually require significantly more RAM, due to some numeric fields being converted to strings. The expansion is typically about 2:1 but varies considerably.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;Here is a summary of the various “compression points” and typical results. &lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;table border="1" cellpadding="0" cellspacing="0" class="MsoTableGrid" style="border-collapse: collapse; border: none; mso-border-alt: solid windowtext .5pt; mso-padding-alt: 0in 5.4pt 0in 5.4pt; mso-yfti-tbllook: 1184;"&gt;&lt;tbody&gt;&lt;tr style="mso-yfti-firstrow: yes; mso-yfti-irow: 0;"&gt;   &lt;td style="border: solid windowtext 1.0pt; mso-border-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;"&gt;&lt;b style="mso-bidi-font-weight: normal;"&gt;Source&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-left: none; border: solid windowtext 1.0pt; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;"&gt;&lt;b style="mso-bidi-font-weight: normal;"&gt;Destination&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-left: none; border: solid windowtext 1.0pt; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;"&gt;&lt;b style="mso-bidi-font-weight: normal;"&gt;Ratio&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-left: none; border: solid windowtext 1.0pt; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;"&gt;&lt;b style="mso-bidi-font-weight: normal;"&gt;Example&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;"&gt;&lt;b style="mso-bidi-font-weight: normal;"&gt;Result&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-left: none; border: solid windowtext 1.0pt; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;"&gt;&lt;b style="mso-bidi-font-weight: normal;"&gt;Notes&lt;o:p&gt;&lt;/o:p&gt;&lt;/b&gt;&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr style="mso-yfti-irow: 1;"&gt;   &lt;td style="border-top: none; border: solid windowtext 1.0pt; mso-border-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;"&gt;Source DB&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-bottom: solid windowtext 1.0pt; border-left: none; border-right: solid windowtext 1.0pt; border-top: none; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;"&gt;-&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-bottom: solid windowtext 1.0pt; border-left: none; border-right: solid windowtext 1.0pt; border-top: none; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-bottom: solid windowtext 1.0pt; border-left: none; border-right: solid windowtext 1.0pt; border-top: none; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;"&gt;2GB&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-bottom: solid windowtext 1.0pt; border-left: none; border-right: solid windowtext 1.0pt; border-top: none; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;"&gt;Raw Data&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr style="mso-yfti-irow: 2;"&gt;   &lt;td style="border-top: none; border: solid windowtext 1.0pt; mso-border-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;"&gt;Source DB&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-bottom: solid windowtext 1.0pt; border-left: none; border-right: solid windowtext 1.0pt; border-top: none; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;"&gt;Document RAM&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-bottom: solid windowtext 1.0pt; border-left: none; border-right: solid windowtext 1.0pt; border-top: none; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;"&gt;10:1&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-bottom: solid windowtext 1.0pt; border-left: none; border-right: solid windowtext 1.0pt; border-top: none; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;"&gt;200MB&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-bottom: solid windowtext 1.0pt; border-left: none; border-right: solid windowtext 1.0pt; border-top: none; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;"&gt;Data de-duplication&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr style="mso-yfti-irow: 3;"&gt;   &lt;td style="background: #EEECE1; border-top: none; border: solid windowtext 1.0pt; mso-background-themecolor: background2; mso-border-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;"&gt;Document RAM&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="background: #EEECE1; border-bottom: solid windowtext 1.0pt; border-left: none; border-right: solid windowtext 1.0pt; border-top: none; mso-background-themecolor: background2; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;"&gt;QVW Disk&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="background: #EEECE1; border-bottom: solid windowtext 1.0pt; border-left: none; border-right: solid windowtext 1.0pt; border-top: none; mso-background-themecolor: background2; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;"&gt;3:1&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="background: #EEECE1; border-bottom: solid windowtext 1.0pt; border-left: none; border-right: solid windowtext 1.0pt; border-top: none; mso-background-themecolor: background2; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;"&gt;67MB&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="background: #EEECE1; border-bottom: solid windowtext 1.0pt; border-left: none; border-right: solid windowtext 1.0pt; border-top: none; mso-background-themecolor: background2; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;"&gt;Save Compression=High&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr style="mso-yfti-irow: 4;"&gt;   &lt;td style="border-top: none; border: solid windowtext 1.0pt; mso-border-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;"&gt;Document RAM&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-bottom: solid windowtext 1.0pt; border-left: none; border-right: solid windowtext 1.0pt; border-top: none; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;"&gt;QVW Disk&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-bottom: solid windowtext 1.0pt; border-left: none; border-right: solid windowtext 1.0pt; border-top: none; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;"&gt;1:1&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-bottom: solid windowtext 1.0pt; border-left: none; border-right: solid windowtext 1.0pt; border-top: none; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;"&gt;200MB&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-bottom: solid windowtext 1.0pt; border-left: none; border-right: solid windowtext 1.0pt; border-top: none; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;"&gt;Save Compression=None&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr style="mso-yfti-irow: 5;"&gt;   &lt;td style="background: #EEECE1; border-top: none; border: solid windowtext 1.0pt; mso-background-themecolor: background2; mso-border-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;"&gt;QVW Disk&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="background: #EEECE1; border-bottom: solid windowtext 1.0pt; border-left: none; border-right: solid windowtext 1.0pt; border-top: none; mso-background-themecolor: background2; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;"&gt;Document RAM&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="background: #EEECE1; border-bottom: solid windowtext 1.0pt; border-left: none; border-right: solid windowtext 1.0pt; border-top: none; mso-background-themecolor: background2; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;"&gt;1:3&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="background: #EEECE1; border-bottom: solid windowtext 1.0pt; border-left: none; border-right: solid windowtext 1.0pt; border-top: none; mso-background-themecolor: background2; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;"&gt;200MB&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="background: #EEECE1; border-bottom: solid windowtext 1.0pt; border-left: none; border-right: solid windowtext 1.0pt; border-top: none; mso-background-themecolor: background2; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;"&gt;Save Compression=High&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr style="mso-yfti-irow: 6;"&gt;   &lt;td style="border-top: none; border: solid windowtext 1.0pt; mso-border-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;"&gt;QVW Disk&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-bottom: solid windowtext 1.0pt; border-left: none; border-right: solid windowtext 1.0pt; border-top: none; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;"&gt;Document RAM&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-bottom: solid windowtext 1.0pt; border-left: none; border-right: solid windowtext 1.0pt; border-top: none; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;"&gt;1:1&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-bottom: solid windowtext 1.0pt; border-left: none; border-right: solid windowtext 1.0pt; border-top: none; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;"&gt;200MB&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-bottom: solid windowtext 1.0pt; border-left: none; border-right: solid windowtext 1.0pt; border-top: none; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;"&gt;Save Compression=None&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr style="mso-yfti-irow: 7;"&gt;   &lt;td style="border-top: none; border: solid windowtext 1.0pt; mso-border-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;"&gt;Document RAM&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-bottom: solid windowtext 1.0pt; border-left: none; border-right: solid windowtext 1.0pt; border-top: none; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;"&gt;QVD Disk&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-bottom: solid windowtext 1.0pt; border-left: none; border-right: solid windowtext 1.0pt; border-top: none; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;"&gt;1:1&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-bottom: solid windowtext 1.0pt; border-left: none; border-right: solid windowtext 1.0pt; border-top: none; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;"&gt;200MB&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-bottom: solid windowtext 1.0pt; border-left: none; border-right: solid windowtext 1.0pt; border-top: none; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;"&gt;QVD always uncompressed&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr style="mso-yfti-irow: 8;"&gt;   &lt;td style="border-top: none; border: solid windowtext 1.0pt; mso-border-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;"&gt;QVD Disk&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-bottom: solid windowtext 1.0pt; border-left: none; border-right: solid windowtext 1.0pt; border-top: none; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;"&gt;Document RAM&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-bottom: solid windowtext 1.0pt; border-left: none; border-right: solid windowtext 1.0pt; border-top: none; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;"&gt;1:1&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-bottom: solid windowtext 1.0pt; border-left: none; border-right: solid windowtext 1.0pt; border-top: none; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;"&gt;200MB&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-bottom: solid windowtext 1.0pt; border-left: none; border-right: solid windowtext 1.0pt; border-top: none; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;"&gt;Optimized load&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;tr style="mso-yfti-irow: 9; mso-yfti-lastrow: yes;"&gt;   &lt;td style="border-top: none; border: solid windowtext 1.0pt; mso-border-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;"&gt;QVD Disk&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-bottom: solid windowtext 1.0pt; border-left: none; border-right: solid windowtext 1.0pt; border-top: none; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;"&gt;Document RAM&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-bottom: solid windowtext 1.0pt; border-left: none; border-right: solid windowtext 1.0pt; border-top: none; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;"&gt;1:2&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-bottom: solid windowtext 1.0pt; border-left: none; border-right: solid windowtext 1.0pt; border-top: none; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;"&gt;400MB&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;/td&gt;   &lt;td style="border-bottom: solid windowtext 1.0pt; border-left: none; border-right: solid windowtext 1.0pt; border-top: none; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt; padding: 0in 5.4pt 0in 5.4pt;" valign="top"&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: .0001pt; margin-bottom: 0in;"&gt;Non-Optimized load&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;/td&gt;  &lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;If your documents are small and you are not experiencing performance issues, worry about none of this.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;Compressed documents occupy less disk space and their smaller size makes them easier to manage for moving, backup, etc. &lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;If you are trying to get a document to load faster, try turning off document compression and benchmark your results. Consider the type of disk when making this decision. Compression may more important in a network storage environment where reducing the amount of data transferred is a significant performance factor. &lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;It’s important to understand that the document compression option has no impact on RAM usage. It only impacts the amount of data read and written to disk.&lt;o:p&gt;&lt;/o:p&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5070255803043802824-8775988011846309270?l=qlikviewnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qlikviewnotes.blogspot.com/feeds/8775988011846309270/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5070255803043802824&amp;postID=8775988011846309270' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/8775988011846309270'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/8775988011846309270'/><link rel='alternate' type='text/html' href='http://qlikviewnotes.blogspot.com/2011/03/qlikview-compression.html' title='Document Compression'/><author><name>Rob Wunderlich</name><uri>http://www.blogger.com/profile/13048694338956825695</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://3.bp.blogspot.com/_IhQc1-zXHmU/SwH7Z2D8lUI/AAAAAAAAADo/UY17XpuzKLw/S220/avatar.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5070255803043802824.post-6094768263962954878</id><published>2011-02-16T22:06:00.000-08:00</published><updated>2011-02-16T22:22:34.671-08:00</updated><title type='text'>QVD Questions and Answers</title><content type='html'>&lt;div class="MsoNormal"&gt;&lt;span class="Apple-style-span" style="color: #4f81bd; font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: #181818;"&gt;On Feb 2 I presented a live webinar titled "Understanding &amp;amp; Best Practices with &amp;nbsp;QVD Files". You can&amp;nbsp;&lt;a href="https://qliktech.webex.com/qliktech/lsr.php?AT=pb&amp;amp;SP=EC&amp;amp;rID=35273157&amp;amp;rKey=D604BD05D24E4FB7&amp;amp;sourceid=FactoryIMS"&gt;view a full 36 minute recording&lt;/a&gt;&amp;nbsp;of the presentation or&amp;nbsp;&lt;a href="http://global.qlikview.com/uploadedimages/QlikLearn_UnderstandingQVD.pdf"&gt;download the slides&lt;/a&gt;&amp;nbsp;as a pdf.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span class="Apple-style-span" style="color: #4f81bd; font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: #181818;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span class="Apple-style-span" style="color: #4f81bd; font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="color: #181818;"&gt;Many questions were submitted during the presentation, too many to answer at that time. I've tried to answer those questions and others below. If you have further questions about QVDs, post a comment here or &amp;nbsp;in the QlikCommunity Forum.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="color: #4f81bd; mso-themecolor: accent1;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="color: #4f81bd; mso-themecolor: accent1;"&gt;Q: ­&lt;i style="mso-bidi-font-style: normal;"&gt;Does the QVD data get stored in an RDBMS like Oracle, or is it in a file system? ­&lt;/i&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;QVD files are stored in the file system.&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;i style="mso-bidi-font-style: normal;"&gt;&lt;span style="color: #4f81bd; mso-themecolor: accent1;"&gt;Q: ­what is the compression factor for QVD's­?&lt;/span&gt;&lt;/i&gt;&lt;span style="color: #4f81bd; mso-themecolor: accent1;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;QVD files are stored uncompressed. A QVD contains the physical representation of an in-memory Qlikview Table. This “RAM image” format is what allows an optimized QVD load to be so quick. The physical blocks of disk are read directly into RAM, “ready to go”. Because QVD is the RAM image, there is no compression.&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;i style="mso-bidi-font-style: normal;"&gt;&lt;span style="color: #4f81bd; mso-themecolor: accent1;"&gt;Q: ­Can we trace back QVD to its source? &lt;/span&gt;&lt;/i&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;There is nothing inherent in a QVD that would provide source lineage. &lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;i style="mso-bidi-font-style: normal;"&gt;&lt;span style="color: #4f81bd; mso-themecolor: accent1;"&gt;Q: ­Why is sorting not possible while loading QVD?­&lt;/span&gt;&lt;/i&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;Sorting (ORDER BY) is only possible with Resident (already in memory) files. Sorting is not possible when reading from files.&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="color: #4f81bd; mso-themecolor: accent1;"&gt;Q: ­Could you go over again the concept of "forcing" un-optimized load for the MAPPING function, respective to the qvd?­&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;MAPPING tables may be loaded from a QVD, but it &lt;i style="mso-bidi-font-style: normal;"&gt;must be an un-optimized load&lt;/i&gt; (this is sometimes called “unwrapping”). &lt;/div&gt;&lt;div class="MsoNormal" style="line-height: normal; margin: 0in 0in 0in 0.5in; mso-layout-grid-align: none;"&gt;&lt;span style="color: black; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;MyMap:&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="line-height: normal; margin: 0in 0in 0in 0.5in; mso-layout-grid-align: none;"&gt;&lt;span style="color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;MAPPING&lt;/span&gt;&lt;span style="color: black; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;LOAD&lt;/span&gt;&lt;/b&gt;&lt;span style="color: black; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt; &lt;/span&gt;&lt;span style="color: maroon; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;F1&lt;/span&gt;&lt;span style="color: black; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;, &lt;/span&gt;&lt;span style="color: maroon; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;F2&lt;/span&gt;&lt;span style="color: black; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt; &lt;/span&gt;&lt;span style="color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;FROM&lt;/span&gt;&lt;span style="color: black; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt; sometable.qvd (&lt;/span&gt;&lt;span style="color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;qvd&lt;/span&gt;&lt;span style="color: black; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;); &lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0in; mso-layout-grid-align: none;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0in; mso-layout-grid-align: none;"&gt;&lt;span style="color: black; mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin;"&gt;The above mapping table will be created but it will appear to be empty when used in MAP USING or ApplyMap().&lt;span style="mso-spacerun: yes;"&gt;&amp;nbsp; &lt;/span&gt;No error, just no resulting mapping.&lt;span style="mso-spacerun: yes;"&gt;&amp;nbsp; &lt;/span&gt;One workaround is to create a condition that will cause an un-optimized load.&lt;span style="mso-spacerun: yes;"&gt;&amp;nbsp; &lt;/span&gt;We want all the rows, so we create an always-true condition that will return all rows. &lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0in; mso-layout-grid-align: none;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="line-height: normal; margin: 0in 0in 0in 0.5in; mso-layout-grid-align: none;"&gt;&lt;span style="color: black; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;MyMap:&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="line-height: normal; margin: 0in 0in 0in 0.5in; mso-layout-grid-align: none;"&gt;&lt;span style="color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;MAPPING&lt;/span&gt;&lt;span style="color: black; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;LOAD&lt;/span&gt;&lt;/b&gt;&lt;span style="color: black; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt; &lt;/span&gt;&lt;span style="color: maroon; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;F1&lt;/span&gt;&lt;span style="color: black; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;, &lt;/span&gt;&lt;span style="color: maroon; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;F2&lt;/span&gt;&lt;span style="color: black; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt; &lt;/span&gt;&lt;span style="color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;FROM&lt;/span&gt;&lt;span style="color: black; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt; sometable.qvd (&lt;/span&gt;&lt;span style="color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;qvd&lt;/span&gt;&lt;span style="color: black; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;)&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="line-height: normal; margin: 0in 0in 0in 0.5in; mso-layout-grid-align: none;"&gt;&lt;span style="color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;WHERE&lt;/span&gt;&lt;span style="color: black; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt; 1=1; &lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0in; mso-layout-grid-align: none;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0in; mso-layout-grid-align: none;"&gt;&lt;span style="color: black; mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin;"&gt;A corollary to this is that the target of a mapping operation cannot be an optimized QVD. &lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0in; mso-layout-grid-align: none;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="line-height: normal; margin: 0in 0in 0in 0.5in; mso-layout-grid-align: none;"&gt;&lt;b&gt;&lt;span style="color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;MAP&lt;/span&gt;&lt;/b&gt;&lt;span style="color: black; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt; Country &lt;/span&gt;&lt;span style="color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;USING&lt;/span&gt;&lt;span style="color: black; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt; MyMap;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="line-height: normal; margin: 0in 0in 0in 0.5in; mso-layout-grid-align: none;"&gt;&lt;span style="color: green; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;// Optimized load, Country will not get mapped.&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="line-height: normal; margin: 0in 0in 0in 0.5in; mso-layout-grid-align: none;"&gt;&lt;b&gt;&lt;span style="color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;LOAD&lt;/span&gt;&lt;/b&gt;&lt;span style="color: black; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt; &lt;/span&gt;&lt;span style="color: maroon; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;Customer&lt;/span&gt;&lt;span style="color: black; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;, &lt;/span&gt;&lt;span style="color: maroon; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;Country&lt;/span&gt;&lt;span style="color: black; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt; &lt;/span&gt;&lt;span style="color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;FROM&lt;/span&gt;&lt;span style="color: black; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt; customer.qvd (&lt;/span&gt;&lt;span style="color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;qvd&lt;/span&gt;&lt;span style="color: black; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;); &lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0in; mso-layout-grid-align: none;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0in; mso-layout-grid-align: none;"&gt;&lt;span style="color: black; mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin;"&gt;&lt;/span&gt;(Note: In QV10, MAPPING LOAD appears to trigger an un-optimized load, rendering the WHERE 1=1 unnecessary. I have not finished verifying this). &lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0in; mso-layout-grid-align: none;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;i style="mso-bidi-font-style: normal;"&gt;&lt;span style="color: #4f81bd; mso-themecolor: accent1;"&gt;Q: ­The use of the Where 1=1 is something that will be good for mapping fields in the future or is possible that qlikview will determine that where 1=1 will allow optimization?­&lt;/span&gt;&lt;/i&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;Good question. We use WHERE 1=1 to force the un-optimized load required by MAPPING LOAD. I’m hopeful that if Qlikview were changed to consider 1=1 as an optimized load, they will also recognize that MAPPING LOAD should be non-optimized.&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;(Note: In QV10, MAPPING LOAD appears to trigger an un-optimized load, rendering the WHERE 1=1 unnecessary. I have not finished verifying this).&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;i style="mso-bidi-font-style: normal;"&gt;&lt;span style="color: #4f81bd; mso-themecolor: accent1;"&gt;Q: ­How would you handle the need to load multiple models (ie multiple qvws)?? I don't think you can do multiple binary loads, so what do you recommend.­&lt;/span&gt;&lt;/i&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;You can generate QVDs from each model and then load all the QVDs to form the larger model.&lt;span style="mso-spacerun: yes;"&gt;&amp;nbsp; &lt;/span&gt;You can generate all QVDs from a qvw with a simple loop. You can add this code to each of your model qvws.&lt;/div&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0in; mso-layout-grid-align: none;"&gt;&lt;b&gt;&lt;span style="color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;FOR&lt;/span&gt;&lt;/b&gt;&lt;span style="color: black; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;i&lt;/span&gt;&lt;/b&gt;&lt;span style="color: black; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt; = 1 &lt;/span&gt;&lt;span style="color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;to&lt;/span&gt;&lt;span style="color: black; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt; &lt;/span&gt;&lt;span style="color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;NoOfTables&lt;/span&gt;&lt;span style="color: black; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;()&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0in; mso-layout-grid-align: none;"&gt;&lt;b&gt;&lt;span style="color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;&lt;span style="mso-spacerun: yes;"&gt;&amp;nbsp; &lt;/span&gt;LET&lt;/span&gt;&lt;/b&gt;&lt;span style="color: black; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt; &lt;/span&gt;&lt;b&gt;&lt;i&gt;&lt;span style="color: grey; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;vTableName&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;span style="color: black; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt; = &lt;/span&gt;&lt;span style="color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;TableName&lt;/span&gt;&lt;span style="color: black; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;(&lt;/span&gt;&lt;b&gt;&lt;i&gt;&lt;span style="color: grey; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;$(i)&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;span style="color: black; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;-1);&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0in; mso-layout-grid-align: none;"&gt;&lt;b&gt;&lt;span style="color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;&lt;span style="mso-spacerun: yes;"&gt;&amp;nbsp; &lt;/span&gt;LET&lt;/span&gt;&lt;/b&gt;&lt;span style="color: black; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt; &lt;/span&gt;&lt;b&gt;&lt;i&gt;&lt;span style="color: grey; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;vOutfile&lt;/span&gt;&lt;/i&gt;&lt;/b&gt;&lt;span style="color: black; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt; = '$(vTableName).qvd';&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0in; mso-layout-grid-align: none;"&gt;&lt;b&gt;&lt;span style="color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;&lt;span style="mso-spacerun: yes;"&gt;&amp;nbsp; &lt;/span&gt;STORE&lt;/span&gt;&lt;/b&gt;&lt;span style="color: black; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt; [$(vTableName)] &lt;/span&gt;&lt;span style="color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;INTO&lt;/span&gt;&lt;span style="color: black; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt; [$(vOutfile)] (&lt;/span&gt;&lt;span style="color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;qvd&lt;/span&gt;&lt;span style="color: black; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;);&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0in; mso-layout-grid-align: none;"&gt;&lt;b&gt;&lt;span style="color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;NEXT&lt;/span&gt;&lt;/b&gt;&lt;span style="color: black; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt; &lt;/span&gt;&lt;b&gt;&lt;span style="color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;i &lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;i style="mso-bidi-font-style: normal;"&gt;&lt;span style="color: #4f81bd; mso-themecolor: accent1;"&gt;Q: ­How are QVD refresh scheduled?­&lt;/span&gt;&lt;/i&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;QVDs are created by script in a QVW executed by the reload process. Schedule the reload as you would the reload of a user facing qvw, using the Qlikview Enterprise Management Console (QEMC) or a batch file.&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;i style="mso-bidi-font-style: normal;"&gt;&lt;span style="color: #4f81bd; mso-themecolor: accent1;"&gt;Q: ­Is QVD Optimized load really worthwhile since it is fairly limited? In other words, should we load data to the memory striving for QVD optimized and then work with the memory tables within the script?­&lt;/span&gt;&lt;/i&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;Optimized vs non-optimized load has two impacts: Load duration and Server RAM usage. If your application is relatively small or you do not have concerns about the impact, don’t spend time trying to maintain an optimized load. Some of the script techniques used to maintain optimized can make your script harder to follow. &lt;/div&gt;&lt;div class="MsoNormal"&gt;If, for a given document, you have concerns about load duration or RAM usage, then making the effort to maintain an optimized load would be worthwhile.&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;i style="mso-bidi-font-style: normal;"&gt;&lt;span style="color: #4f81bd; mso-themecolor: accent1;"&gt;Q: ­Can a QVD be accessed from a AS400 DB2 database to get some data?­&lt;/span&gt;&lt;/i&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="color: black; mso-themecolor: text1;"&gt;Nothing but Qlikview can read from QVDs, so no, DB2 cannot read directly from a QVD.&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="color: black; mso-themecolor: text1;"&gt;In the same script that creates the QVD with the store statement:&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0in; mso-layout-grid-align: none; text-indent: 0.5in;"&gt;&lt;b&gt;&lt;span style="color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;STORE&lt;/span&gt;&lt;/b&gt;&lt;span style="color: black; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt; mytable &lt;/span&gt;&lt;span style="color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;INTO&lt;/span&gt;&lt;span style="color: black; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt; mytable.qvd (&lt;/span&gt;&lt;span style="color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;qvd&lt;/span&gt;&lt;span style="color: black; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;); &lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="color: black; mso-themecolor: text1;"&gt;You can also create a CSV copy for other consumers:&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0in; mso-layout-grid-align: none; text-indent: 0.5in;"&gt;&lt;b&gt;&lt;span style="color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;STORE&lt;/span&gt;&lt;/b&gt;&lt;span style="color: black; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt; mytable &lt;/span&gt;&lt;span style="color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;INTO&lt;/span&gt;&lt;span style="color: black; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt; mytable.csv (&lt;/span&gt;&lt;span style="color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;txt&lt;/span&gt;&lt;span style="color: black; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;);&lt;span style="mso-spacerun: yes;"&gt;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0in; mso-layout-grid-align: none;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;span style="color: black; mso-themecolor: text1;"&gt;The csv file can be read by any number of programs, including an ODBC text driver or a bulk database loader. You can use QV to do the ETL and then push csv files back into a Data Warehouse, using something like SQL Server DTS or other data pump.&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;i style="mso-bidi-font-style: normal;"&gt;&lt;span style="color: #4f81bd; mso-themecolor: accent1;"&gt;Q: ­I'm pulling data from a database over a slow WAN link.&lt;span style="mso-spacerun: yes;"&gt;&amp;nbsp; &lt;/span&gt;Would using a qvd speed this up?&lt;span style="mso-spacerun: yes;"&gt;&amp;nbsp; &lt;/span&gt;If so, would the qvd file reside on the same side as the database or at the end of WAN Link (client side)?­&lt;/span&gt;&lt;/i&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;Using QVDs could speed up your overall process by allowing multiple reloads to load from the qvd instead of going to the database over the slow WAN link. The QVD should live at the client end of the link – where the qvw is reloading.&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;i style="mso-bidi-font-style: normal;"&gt;&lt;span style="color: #4f81bd; mso-themecolor: accent1;"&gt;Q:&lt;span style="mso-spacerun: yes;"&gt;&amp;nbsp; &lt;/span&gt;If the data source is constantly changing (such as portfolio management software) can we refresh qvds frequently? Will this overburden the process?&lt;/span&gt;&lt;/i&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;QVDs may be refreshed frequently. Exactly how frequently depends on your data volumes and architecture. Refreshing every 30 minutes is common, and I have seen intervals of 5 minutes.&lt;span style="mso-spacerun: yes;"&gt;&amp;nbsp; &lt;/span&gt;Frequent refresh of large volumes usually requires incremental load, which is covered in the Reference Guide and the Forums. &lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;i style="mso-bidi-font-style: normal;"&gt;&lt;span style="color: #4f81bd; mso-themecolor: accent1;"&gt;Q: ­If add the BUFFER command before each load statement pulling from DBMS, the first execution pulls from the DB but all after are incremental loads pulling from a file system created batch of QVDs?­&lt;/span&gt;&lt;/i&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;The BUFFER prefix does &lt;b style="mso-bidi-font-weight: normal;"&gt;not&lt;/b&gt; provide incremental load when loading from a DBMS.&lt;span style="mso-spacerun: yes;"&gt;&amp;nbsp; &lt;/span&gt;Subsequent reloads will load from the buffered file system QVD, but new rows will not be fetched from the database. &lt;/div&gt;&lt;div class="MsoNormal"&gt;When used with a load from txt files, BUFFER will provide automatic incremental load. Subsequent reloads will add new data from the file to the buffered QVD.&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="mso-margin-bottom-alt: auto; mso-margin-top-alt: auto;"&gt;&lt;i style="mso-bidi-font-style: normal;"&gt;&lt;span style="color: #4f81bd; mso-themecolor: accent1;"&gt;Q: I am running SBE Server so documents are reloaded right from the Documents folder.&amp;nbsp; What is your recommendation for location of the QVD generator documents?&amp;nbsp; In other words, do you place them in the Documents folder alongside your production QVW’s?&amp;nbsp; &lt;/span&gt;&lt;/i&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;I recommend putting the QVD generators in a separate "Loaders" folder. Make this a mounted folder in QVS and schedule reloads as needed. Use NTFS permissions to hide the folder from standard AP users&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;A number of questions were asked about the QVX format. I haven’t had much experience with QVX yet. Rob Patterson has indicated he will schedule a QlikLearn webinar specifically on the topic of QVX.&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;i style="mso-bidi-font-style: normal;"&gt;&lt;span style="color: #4f81bd; mso-themecolor: accent1;"&gt;Q: Does ­QVX also have two types of load, optimized and not optimized?­&lt;/span&gt;&lt;/i&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;No optimized load only applies to QVD.&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;i style="mso-bidi-font-style: normal;"&gt;&lt;span style="color: #4f81bd; mso-themecolor: accent1;"&gt;Q: ­What are the other differences between QVD and QVX?­&lt;/span&gt;&lt;/i&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0in;"&gt;&lt;span style="color: black; mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin; mso-fareast-font-family: &amp;quot;Times New Roman&amp;quot;;"&gt;QVD is a proprietary file format provided by QlikView for storage. Only QlikView software can read and write to QVD files.&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0in;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0in;"&gt;&lt;span style="color: black; mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin; mso-fareast-font-family: &amp;quot;Times New Roman&amp;quot;;"&gt;The QVX is in an open format performance file for storage of QlikView data. A customer or third party can create QVX files on any platform, without needing Qlikview software. &lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0in;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0in;"&gt;&lt;span style="color: black; mso-bidi-font-family: Calibri; mso-bidi-theme-font: minor-latin; mso-fareast-font-family: &amp;quot;Times New Roman&amp;quot;;"&gt;QVD files will typically load faster than a QVX file.&lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0in;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0in;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;i style="mso-bidi-font-style: normal;"&gt;&lt;span style="color: #4f81bd; mso-themecolor: accent1;"&gt;Q: ­Is QVX used as a source to other source systems or is it used to pull the data from source systems which has no ODBC provider?­&lt;/span&gt;&lt;/i&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;The use cases for QVX are still being discovered, and I’m sure we’ll see some interesting uses.&lt;span style="mso-spacerun: yes;"&gt;&amp;nbsp; &lt;/span&gt;The scenario I currently understand is to provide data to Qlikview when there is no ODBC provider.&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;i style="mso-bidi-font-style: normal;"&gt;&lt;span style="color: #4f81bd; mso-themecolor: accent1;"&gt;Q: ­How can I create a QVX?&lt;br /&gt;Q: ­How do you write out to a QVX?­&lt;br /&gt;Q ­How can you read QVX from other software than Qlikview .­&lt;/span&gt;&lt;/i&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;Documentation of the internal QVX format is available in the Qlikview SDK. The SDK can be installed from the Qlikview Server installation package. Also look for examples in the “Share Qlikviews” section of QlikCommunity.&lt;/div&gt;&lt;div class="MsoNormal"&gt;You can also create a QVX with a script STORE statement:&lt;/div&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0in; mso-layout-grid-align: none;"&gt;&lt;span style="mso-tab-count: 1;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;b&gt;&lt;span style="color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;STORE&lt;/span&gt;&lt;/b&gt;&lt;span style="color: black; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt; mytable &lt;/span&gt;&lt;span style="color: blue; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt;INTO&lt;/span&gt;&lt;span style="color: black; font-family: &amp;quot;Courier New&amp;quot;; font-size: 10pt;"&gt; mytable.qvx (qvx); &lt;/span&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0in; mso-layout-grid-align: none;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0in; mso-layout-grid-align: none;"&gt;This is useful to generate a sample QVX for examination or testing.&lt;/div&gt;&lt;div class="MsoNormal" style="line-height: normal; margin-bottom: 0in;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;-Rob&amp;nbsp;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;a href="http://robwunderlich.com/"&gt;http://robwunderlich.com/&lt;/a&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="MsoNormal"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5070255803043802824-6094768263962954878?l=qlikviewnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qlikviewnotes.blogspot.com/feeds/6094768263962954878/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5070255803043802824&amp;postID=6094768263962954878' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/6094768263962954878'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/6094768263962954878'/><link rel='alternate' type='text/html' href='http://qlikviewnotes.blogspot.com/2011/02/qvd-questions-and-answers.html' title='QVD Questions and Answers'/><author><name>Rob Wunderlich</name><uri>http://www.blogger.com/profile/13048694338956825695</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://3.bp.blogspot.com/_IhQc1-zXHmU/SwH7Z2D8lUI/AAAAAAAAADo/UY17XpuzKLw/S220/avatar.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5070255803043802824.post-6721085357386406199</id><published>2011-01-14T16:39:00.000-08:00</published><updated>2011-01-17T17:16:10.202-08:00</updated><title type='text'>Incremental Load using SQL Server "timestamp" Data Type</title><content type='html'>&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;Incremental Load (extracting only new or changed rows from the database) requires a table column that identifies when a row has been updated. This is usually a datetime column like "LastUpdate". The script extracts the max timestamp from the existing QVD and uses it to create a select predicate like:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;WHERE LastUpdate &amp;gt;= '01-20-2010 13:55:01'&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;If the database is Microsoft SQL Server, you may have another option for identifying updated rows. A table column of type "timestamp" is incremented whenever a row is changed. The name "timestamp" in somewhat confusing, as this column does not contain time values. Here is the description from the 2005 Reference:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;strong&gt;"timestamp &lt;/strong&gt;is a data type that exposes automatically generated, unique binary numbers within a database.&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;strong&gt;timestamp&lt;/strong&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;is generally used as a mechanism for version-stamping table rows. The storage size is 8 bytes. The&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;strong&gt;timestamp&lt;/strong&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;data type is just an incrementing number and does not preserve a date or a time. To record a date or time, use a&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;strong&gt;datetime&lt;/strong&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;data type."&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Segoe UI', Verdana, Arial; font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;In Sql&amp;nbsp;&amp;nbsp;Server &amp;nbsp;2008, the type "rowversion" was introduced as an alias for "timestamp". Rowversion is&amp;nbsp;preferred&amp;nbsp;for 2008 and forward.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;If your table does not already have a timestamp column, you can add one with an ALTER DDL statement, For example, to add a timestamp column named "Revision" to a table named "Orders":&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Times, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;alter table Orders ADD&amp;nbsp;[Revision] [timestamp] NOT NULL;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Times, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;The Revision column will be returned by default as a&amp;nbsp;hexadecimal&amp;nbsp;string, so it's easiest to convert to an integer before storing in QV.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Times, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;SQL SELECT&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;OrderID, etc,&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;cast(Revision as bigint) as Revision&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;FROM Orders ...&lt;/span&gt;&lt;br /&gt;&lt;div style="font-family: Times, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="font-family: Times, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;In subsequent incremental loads, add a predicate to select only rows greater than the last revision.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;div style="font-family: Times, 'Times New Roman', serif;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;// Select the max value from the qvd&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;tempmax:&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;LOAD max(Revision) as Revision FROM myqvd.qvd (qvd);&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;LET vMaxRevision = PEEK('Revision');&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;DROP TABLE tempmax:&lt;br /&gt;&lt;br /&gt;SQL SELECT&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;OrderID, etc,&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;cast(Revision as bigint) as Revision&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;FROM Orders&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;b&gt;WHERE Revision &amp;gt; $(vMaxRevision)&lt;/b&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: Times, 'Times New Roman', serif; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;I find the timestamp value, when available, to be easier to use than a datetime column. It's just a numeric, so no literal formatting is required.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;Because it's a precise and unique value, you avoid the "always one row" problem. When selecting from a datetime, you usually have to&amp;nbsp;specify&amp;nbsp;"&amp;gt;=" because a datetime is not a unique value. This means that a select will return at least one row, even if there were no real updates.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;With timestamp, you can specfy "&amp;gt;" which will return zero rows if there were no updates. Knowing that you had no updates can be useful in controlling the execution of further processing steps.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div style="font-family: Times, 'Times New Roman', serif; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: Times, 'Times New Roman', serif;"&gt;-&lt;/span&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"&gt;Rob&amp;nbsp;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5070255803043802824-6721085357386406199?l=qlikviewnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qlikviewnotes.blogspot.com/feeds/6721085357386406199/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5070255803043802824&amp;postID=6721085357386406199' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/6721085357386406199'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/6721085357386406199'/><link rel='alternate' type='text/html' href='http://qlikviewnotes.blogspot.com/2011/01/incremental-load-using-sql-server.html' title='Incremental Load using SQL Server &quot;timestamp&quot; Data Type'/><author><name>Rob Wunderlich</name><uri>http://www.blogger.com/profile/13048694338956825695</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://3.bp.blogspot.com/_IhQc1-zXHmU/SwH7Z2D8lUI/AAAAAAAAADo/UY17XpuzKLw/S220/avatar.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5070255803043802824.post-2464573636352271645</id><published>2010-12-09T11:30:00.000-08:00</published><updated>2010-12-09T12:31:57.309-08:00</updated><title type='text'>Deconstructing Chart Design</title><content type='html'>In Qlikview training we survey chart types and visualization principles.&amp;nbsp;In this post&amp;nbsp;I'll walk through a recent Qlikview assignment and&amp;nbsp;how I applied&amp;nbsp;those&amp;nbsp;design&amp;nbsp;principles.&lt;br /&gt;&lt;br /&gt;The problem statement is this. System A sends many thousand transactions daily to System B and requires a reasonable response time to support the business process involved. Occasionally, the response times are atypically high and this causes problems in the downstream processes. The high response times do not always appear in clumps. Engineers require identification of the specific problem periods and feedback on the success of their tuning efforts.&lt;br /&gt;&lt;br /&gt;Qlikview's aggregation and drill down capabilities seem ideally suited&amp;nbsp;for this problem.&amp;nbsp;What metric will support the monitoring and analysis goal? &lt;br /&gt;&lt;br /&gt;Due to the large transaction count, looking at average response time is ineffective.&amp;nbsp;Two hundred 50 second responses averaged with 10,000 1-3 second transactions will not stand out enough&amp;nbsp;in an average. The customer also&amp;nbsp;stated that&amp;nbsp;having several outliers of 200 or 300 seconds were normal and could be explained by workloads or scheduled maintenance on System B. &lt;br /&gt;&lt;br /&gt;While there may be other statistical measures that would work, we determined that tracking the 99% percentile would&amp;nbsp;identify the problem periods. Other supporting measures&amp;nbsp;will be displayed to provide context for the primary measure. &lt;br /&gt;&lt;br /&gt;The primary measure is 99% Percentile (99% of the transactions response fall at or below this value). Supporting measures will be Transaction count, Average Response Time and Max Response Time. &lt;br /&gt;&lt;br /&gt;When I&amp;nbsp;approach a new chart I&amp;nbsp;try to begin with &lt;a href="http://www.edwardtufte.com/tufte/books_vdqi"&gt;Edward Tufte's&lt;/a&gt; advice to&amp;nbsp; "always know what story you are trying to tell before you design the graphic". This&amp;nbsp;story&amp;nbsp;is the trend of the 99% Percentile.&lt;br /&gt;&lt;br /&gt;Here's my first attempt at a chart using mostly defaults. When plotting values of different magnitudes (Transaction Count and Transaction Responses) I like to use the Combo chart type.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_IhQc1-zXHmU/TQExhhtSl8I/AAAAAAAAAJI/1y3U8lJgcKY/s1600/Chart1.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="225" n4="true" src="http://2.bp.blogspot.com/_IhQc1-zXHmU/TQExhhtSl8I/AAAAAAAAAJI/1y3U8lJgcKY/s400/Chart1.PNG" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Automatic scaling causes the red "Avg Response" line&amp;nbsp;to have no meaningful shape. Further, the Transaction bars have too much prominence. They are supposed to be a supporting measure to the main story.&lt;br /&gt;&lt;br /&gt;I change the Response&amp;nbsp;values to a Logarithmic scale (Properties, Axes, Log Scale) and de-emphasize the Transaction bars by making them white (Properties, Color) and with borders (Properties, Expressions, Bar Border Width=1), Here's the result. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_IhQc1-zXHmU/TQExmSvItiI/AAAAAAAAAJM/sinx6uU9ATw/s1600/Chart2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="226" n4="true" src="http://4.bp.blogspot.com/_IhQc1-zXHmU/TQExmSvItiI/AAAAAAAAAJM/sinx6uU9ATw/s400/Chart2.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;The Response line now has&amp;nbsp;meaningful shape, but the Transaction bars are still too prominent.&lt;br /&gt;&lt;br /&gt;For my next revision I split the axis vertically 75/25&amp;nbsp;(Properties, Axes, Split Axes, Primary=75%). This allows the top 75% of the chart space to represent the Response lines. The remaining 25% of the chart will host the Transaction bars. I change the bar colors to a muted gray (Properties, Colors) and remove the borders.&amp;nbsp; Here's the result. &lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_IhQc1-zXHmU/TQExvLH48_I/AAAAAAAAAJU/CnyEFazLtf0/s1600/Chart3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="226" n4="true" src="http://2.bp.blogspot.com/_IhQc1-zXHmU/TQExvLH48_I/AAAAAAAAAJU/CnyEFazLtf0/s400/Chart3.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;The only prominence granted to the 99% is it's being first in the legend, which is not enough.&lt;br /&gt;&lt;br /&gt;For my final revision I apply &lt;a href="http://www.perceptualedge.com/"&gt;Stephen Few's&lt;/a&gt; principle of color and hue to&amp;nbsp;emphasize&amp;nbsp;the key measure. I assign the 99% Response the red color to make it stand out. I de-emphasize the supporting measures by removing the lines and using only symbols (Properties, Expression, Display Options, uncheck Line, check Symbol). I leave Symbol on for 99% to make it easier for the user to get the hover popup and drill down.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Guided by&amp;nbsp;Tufte's &lt;a href="http://www.infovis-wiki.net/index.php/Data-Ink_Ratio"&gt;"Data-Ink Ratio"&lt;/a&gt; principle, I&amp;nbsp;remove axis numbers for the Transaction bars (Properties, Axes, Hide Axis) to make the chart less busy. The significance of Transactions is trend and it's relationship to 99%, not the absolute value. Driven by the same principle, I remove the grid lines as they are unnecessary. The story and the objective is to identify spikes, not absolute values. Here's my final chart.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_IhQc1-zXHmU/TQExw6lXM-I/AAAAAAAAAJY/qTNYkWWz460/s1600/Chart4.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="221" n4="true" src="http://4.bp.blogspot.com/_IhQc1-zXHmU/TQExw6lXM-I/AAAAAAAAAJY/qTNYkWWz460/s400/Chart4.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5070255803043802824-2464573636352271645?l=qlikviewnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qlikviewnotes.blogspot.com/feeds/2464573636352271645/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5070255803043802824&amp;postID=2464573636352271645' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/2464573636352271645'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/2464573636352271645'/><link rel='alternate' type='text/html' href='http://qlikviewnotes.blogspot.com/2010/12/deconstructing-chart-design.html' title='Deconstructing Chart Design'/><author><name>Rob Wunderlich</name><uri>http://www.blogger.com/profile/13048694338956825695</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://3.bp.blogspot.com/_IhQc1-zXHmU/SwH7Z2D8lUI/AAAAAAAAADo/UY17XpuzKLw/S220/avatar.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_IhQc1-zXHmU/TQExhhtSl8I/AAAAAAAAAJI/1y3U8lJgcKY/s72-c/Chart1.PNG' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5070255803043802824.post-8208561576847726952</id><published>2010-12-06T22:35:00.000-08:00</published><updated>2010-12-06T22:35:57.322-08:00</updated><title type='text'>Alert Questions &amp; Answers</title><content type='html'>I received several questions regarding my post &lt;a href="http://qlikviewnotes.blogspot.com/2010/09/monitoring-reload-schedule.html"&gt;Monitoring the Reload Schedule&lt;/a&gt;. Surprisingly the questions were not about the monitoring solution, but rather using Alerts. I'll summarize the questions and answers here.&lt;br /&gt;&lt;br /&gt;&lt;em&gt;Can I loop through field values in an Alert?&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;Not directly. But you can create multiple alerts that use either bookmarks or set analysis in the Condition to handle a known set of field values. For example&amp;nbsp;create one alert for Region=US and a second for&amp;nbsp;Region=Europe and&amp;nbsp;each sends&amp;nbsp;an&amp;nbsp;email to the associated Regional Manager.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;em&gt;Can I use an alert to always send an email?&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;Yes. Just set the Condition to "-1" (without quotes). This is always true and can be used to send text "mini-reports" to your email recipients. Your email text might be something simple like:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace; font-size: x-small;"&gt;='Currently open tickets: ' &amp;amp; sum(OpenTicketCounter)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Or something more complex like:&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace; font-size: x-small;"&gt;='YTD Sales are ' &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace; font-size: x-small;"&gt;&amp;amp; money(&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace; font-size: x-small;"&gt;sum({1 &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace; font-size: x-small;"&gt;&amp;lt;[Invoice Year]={$(=year(today(2)))}&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace; font-size: x-small;"&gt;} &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace; font-size: x-small;"&gt;Quantity * Price &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace; font-size: x-small;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace; font-size: x-small;"&gt;, '$#,##0;($#,##0)'&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace; font-size: x-small;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace; font-size: x-small;"&gt;&amp;amp; '&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace; font-size: x-small;"&gt;YTD Orders are '&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace; font-size: x-small;"&gt;&amp;amp; num(&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace; font-size: x-small;"&gt;sum({1 &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace; font-size: x-small;"&gt;&amp;lt;[Order Year]={$(=year(today(2)))}&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace; font-size: x-small;"&gt;} &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace; font-size: x-small;"&gt;Quantity &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace; font-size: x-small;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace; font-size: x-small;"&gt;, '#,##0'&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace; font-size: x-small;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This will generate an email body that looks like:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;YTD Sales are $12,014,788&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;YTD Orders are 167,580&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;You can build up complex expressions in a Text Object to get them correct and then paste to the Alert.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;em&gt;Can I include a chart image in an alert email?&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;No. If you know of a method, please leave a comment. &lt;br /&gt;&lt;br /&gt;It may be helpful to include a url in the email that opens the Qlikview document for further analysis.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;If you have Alert questions or tips, please leave a comment.&lt;br /&gt;&lt;br /&gt;-Rob&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5070255803043802824-8208561576847726952?l=qlikviewnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qlikviewnotes.blogspot.com/feeds/8208561576847726952/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5070255803043802824&amp;postID=8208561576847726952' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/8208561576847726952'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/8208561576847726952'/><link rel='alternate' type='text/html' href='http://qlikviewnotes.blogspot.com/2010/12/alert-questions-answers.html' title='Alert Questions &amp; Answers'/><author><name>Rob Wunderlich</name><uri>http://www.blogger.com/profile/13048694338956825695</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://3.bp.blogspot.com/_IhQc1-zXHmU/SwH7Z2D8lUI/AAAAAAAAADo/UY17XpuzKLw/S220/avatar.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5070255803043802824.post-8678268174578498824</id><published>2010-09-14T17:16:00.000-07:00</published><updated>2010-09-15T20:17:39.707-07:00</updated><title type='text'>Monitoring the Reload Schedule</title><content type='html'>Monitoring successful operation is an important aspect of any IT system. &amp;nbsp;What kind of monitoring is useful for Qlikview? I've found the following monitoring&amp;nbsp;important in a Qlikview Server installation:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Notification of individual reload failures. This capability, sending an email on reload failure,&amp;nbsp; is included in all editions of Qlikview Server. &lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Status of Qlikview&amp;nbsp;services. Most shops have&amp;nbsp;a&amp;nbsp;network monitor such as&amp;nbsp;&lt;a href="http://www.woodstone.nu/salive/"&gt;Servers Alive&lt;/a&gt; to monitor and&amp;nbsp;send alerts about status of Windows services.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;A particularly effective style of monitoring&amp;nbsp;is "goal" monitoring. That is, instead of monitoring the resources required to achieve a goal, monitor the goal itself. In Qlikview terms, this means&amp;nbsp;confirming that&amp;nbsp;a set of Qlikview documents has been updated as scheduled.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;In this post I'll look at using a Qlikview document to monitor the&amp;nbsp;filetimes of Qlikview Server documents.&amp;nbsp;An&amp;nbsp;"old" filetime is an indication that a reload&amp;nbsp;or distribution has been missed. An email&amp;nbsp;notification will be sent when we are off schedule.The mail body will look something like this:&lt;br /&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;&lt;span style="font-family: Verdana, sans-serif;"&gt;4 documents overdue: Expenses_Joe.qvw, Expenses_Rob.qvw, Expenses_Sally.qvw, fieldIndex.qvw&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;The code used in this post can be downloaded at &lt;a href="http://robwunderlich.com/downloads/FileAgeMonitor.zip"&gt;File Age Monitor&lt;/a&gt;. Download and extract the three files:&lt;br /&gt;&lt;strong&gt;FileAgeMonitor.qvw&lt;/strong&gt;&amp;nbsp; -- monitoring document.&lt;br /&gt;&lt;strong&gt;FileAgeMonitor_Rules.txt&lt;/strong&gt; -- Filename masks and maximum expected age.&lt;br /&gt;&lt;strong&gt;FileAgeMonitor_Email.txt&lt;/strong&gt; -- Address(s) to send alert about overdue documents.&lt;br /&gt;&lt;br /&gt;To use FileAgeMonitor in your shop you'll need to make the&amp;nbsp;following changes:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;On the "Configuration" script tab, specify the directories you want to scan for qvw files. &lt;/li&gt;&lt;li&gt;Modify FileAgeMonitor_Rules.txt to specify rules meaningful to your installation, Instructions are in the file.&lt;/li&gt;&lt;li&gt;Modify FileAgeMonitor_Email.txt for your email address. Instructions are in the file.&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;FileAgeMonitor_Rules.txt consists of two fields:&lt;br /&gt;&amp;nbsp; &amp;nbsp; - a filename mask (Key)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; - a maximum allowable age in hours (MaxAge). &lt;br /&gt;Lines beginning with "#" are comments. Example:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace; font-size: x-small;"&gt;Key, MaxAge&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace; font-size: x-small;"&gt;# Rules file for FileAgeMonitor.qvw. First match wins.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace; font-size: x-small;"&gt;# "Filename Mask", "Max allowable age in hours"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace; font-size: x-small;"&gt;# All of the Expenses* docs should be no more than&amp;nbsp;25 hours old&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace; font-size: x-small;"&gt;Expenses*.qvw, 25&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace; font-size: x-small;"&gt;#Films can be 90 days old &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace; font-size: x-small;"&gt;Films.qvw, 90*24&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace; font-size: x-small;"&gt;# Everything else - catch all default - 7 days&lt;/span&gt; &lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace; font-size: x-small;"&gt;*, 7*24&lt;/span&gt; &lt;br /&gt;&amp;nbsp; &lt;br /&gt;The first field, "Key" is a filename mask that may use the standard Qlikview wild card characters of "*" to match any number of characters and "?" to match a single character. &lt;br /&gt;&amp;nbsp; &lt;br /&gt;The second field, "MaxAge", is the threshold age&amp;nbsp;at which a file is considered "overdue". MaxAge may contain any expression that evaluates to a numeric value. The value is hours. &lt;br /&gt;&amp;nbsp; &lt;br /&gt;The last entry in the Rules files, "*" will match&amp;nbsp;all files. &lt;br /&gt;&amp;nbsp; &lt;br /&gt;The script&amp;nbsp;builds a list of qvw files and matches each filename against the entries in the Rules file. The first match wins.&amp;nbsp; The age of each file is tested against it's matching rule and the flag field "Is Overdue?" is set to Y or N. The flag field is defined as a dual: &lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace; font-size: x-small;"&gt;&amp;nbsp; if(FileAge &amp;gt; MaxAge, dual('Y',1), dual('N',0) )&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;as "Is Overdue?".&lt;/span&gt;&lt;br /&gt;Y has the dual value 1, N the value 0. This allows the flag to be summed. &lt;br /&gt;&amp;nbsp; &lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_IhQc1-zXHmU/TI_HQFmndFI/AAAAAAAAAIo/aenyAh9I_nA/s1600/Chart.png" imageanchor="1" style="clear: left; cssfloat: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="169" qx="true" src="http://1.bp.blogspot.com/_IhQc1-zXHmU/TI_HQFmndFI/AAAAAAAAAIo/aenyAh9I_nA/s400/Chart.png" width="400" /&gt;&lt;/a&gt; &lt;br /&gt;So now we have a chart that displays what's overdue, but how about automatic notifications? For that we'll use a Document Alert. Alerts are created from the Tools menu. Here's the alert defined used to send the email. Refer to the notes that follow the picture. &lt;br /&gt;&amp;nbsp; &lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_IhQc1-zXHmU/TI_QMDikFuI/AAAAAAAAAIw/oe1u_SDYx34/s1600/Alert.png" imageanchor="1" style="clear: left; cssfloat: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="326" qx="true" src="http://2.bp.blogspot.com/_IhQc1-zXHmU/TI_QMDikFuI/AAAAAAAAAIw/oe1u_SDYx34/s400/Alert.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&amp;nbsp; &lt;strong&gt;&lt;br /&gt;1&lt;/strong&gt;. Before the condition is evaluated,&amp;nbsp;apply the bookmark that selects&amp;nbsp;"Is Overdue?"=Y. &lt;br /&gt;&lt;strong&gt;2&lt;/strong&gt;. The alert condition is specified as: &lt;br /&gt;&amp;nbsp; =sum([Is Overdue?])&amp;nbsp; &amp;gt; 0 &lt;br /&gt;Recall that "Is Overdue?" was defined as a dual so it may be summed. If there are any overdue documents, the condition will be true and the alert will "fire". &lt;br /&gt;&lt;strong&gt;3&lt;/strong&gt;. Both the Mail subject and&amp;nbsp;mail body contain the count of overdue documents. The body contains the document names as well. The body expression is: &lt;br /&gt;=sum([Is Overdue?]) &amp;amp; ' documents overdue: ' &amp;amp; concat(FileName, ', ') &lt;br /&gt;&lt;strong&gt;4&lt;/strong&gt;. The email will be sent to the addresses that were loaded into field "AlertTo".&amp;nbsp; The script loaded this field from the file FileAgeMonitor_Email.txt.&lt;br /&gt;&lt;strong&gt;5&lt;/strong&gt;. Batch Mode limits this alert to server based reload only. If Interactive were checked, the alert&amp;nbsp;may fire when we are reloading during Development. &lt;br /&gt;&lt;strong&gt;6&lt;/strong&gt;. The Alert will be tested at the end of each reload. &lt;br /&gt;&lt;strong&gt;7&lt;/strong&gt;. The trigger level is set to "Message Changes". This means a new email will be sent only when the count of overdue documents changes. So we will not get an hourly email telling us that "10 docs are overdue", but will receive a new email if the next reload produces an overdue count of 8 or 12 -- something different than 10.&lt;br /&gt;&lt;br /&gt;FileAgeMonitor itself needs to be scheduled to reload periodically. I schedule it to run towards the end of interval reload cycles. For example, if there are hourly reloads at the top of the hour, I schedule FileAgeMonitor at 45 minutes after the hour.&lt;br /&gt;&lt;br /&gt;If FileAgeMonitor relies on Server scheduling, and the entire scheduling process fails, how will FileAgeMonitor be able to tell us that reloads are not running? This is the&amp;nbsp;"monitoring the monitor" problem that inevitably occurs with system monitoring. I address this&amp;nbsp;issue by monitoring the Filetime of FileAgeMonitor.qvw using an external monitor like &lt;a href="http://www.woodstone.nu/salive/"&gt;Servers Alive&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Qlikview reloading can get "off schedule" for any number of reasons;&amp;nbsp;Database errors, Administrator errors. bugs in the scheduling software. &amp;nbsp;It's important for the Administrator to know of exceptions and their scope as quickly as possible. &lt;br /&gt;&lt;br /&gt;-Rob&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5070255803043802824-8678268174578498824?l=qlikviewnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qlikviewnotes.blogspot.com/feeds/8678268174578498824/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5070255803043802824&amp;postID=8678268174578498824' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/8678268174578498824'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/8678268174578498824'/><link rel='alternate' type='text/html' href='http://qlikviewnotes.blogspot.com/2010/09/monitoring-reload-schedule.html' title='Monitoring the Reload Schedule'/><author><name>Rob Wunderlich</name><uri>http://www.blogger.com/profile/13048694338956825695</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://3.bp.blogspot.com/_IhQc1-zXHmU/SwH7Z2D8lUI/AAAAAAAAADo/UY17XpuzKLw/S220/avatar.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_IhQc1-zXHmU/TI_HQFmndFI/AAAAAAAAAIo/aenyAh9I_nA/s72-c/Chart.png' height='72' width='72'/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5070255803043802824.post-5166664857156127725</id><published>2010-07-08T09:18:00.000-07:00</published><updated>2010-07-08T09:20:19.437-07:00</updated><title type='text'>The Now() Trap</title><content type='html'>The Now() function operates differently in script and charts. This post will highlight one difference that&amp;nbsp;has tripped up&amp;nbsp;even experienced developers.&lt;br /&gt;&lt;br /&gt;Our example script requirement is to&amp;nbsp;extract rows of data where the "&lt;span class="goog-spellcheck-word"&gt;TransactionDatetime&lt;/span&gt;" field value is within the last 24 hours.&amp;nbsp;We'll use the "Now()" function to establish the current time.&amp;nbsp;Here's the doc from the &lt;span class="goog-spellcheck-word"&gt;QV&lt;/span&gt; Ref Guide.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-family: Verdana, sans-serif; font-size: x-small;"&gt;now( [ timer_mode ] )&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: Verdana, sans-serif; font-size: x-small;"&gt;Returns a timestamp from the system clock. The timer_mode may&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Verdana, sans-serif; font-size: x-small;"&gt;have the following values:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Verdana; font-size: x-small;"&gt;&amp;nbsp; 0 Time at script run&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Verdana, sans-serif; font-size: x-small;"&gt;&amp;nbsp; 1 Time at function call&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Verdana, sans-serif; font-size: x-small;"&gt;&amp;nbsp; 2 Time when the document was opened&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: Verdana, sans-serif; font-size: x-small;"&gt;Default timer_mode is 1. The timer_mode=1 should be used with&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Verdana, sans-serif; font-size: x-small;"&gt;caution, since it polls the operating system every second and hence&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Verdana, sans-serif; font-size: x-small;"&gt;could slow down the system.&lt;/span&gt; &lt;br /&gt;&amp;nbsp; &lt;br /&gt;Which timer_mode&amp;nbsp;option do you choose? &lt;span class="goog-spellcheck-word"&gt;Hmm&lt;/span&gt;... you want 24 hours prior to the script execution so it seems like "0" is the best option. Plus there is that scary warning about&amp;nbsp;"1" slowing down the system.&lt;br /&gt;&lt;br /&gt;The integer 1 represents a day -- 24 hours -- so you code a where clause in your LOAD like: &lt;br /&gt;&amp;nbsp; &lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;WHERE &lt;span class="goog-spellcheck-word"&gt;TransactionDatetime&lt;/span&gt; &amp;gt;= now(0) -1&lt;/span&gt; &lt;br /&gt;&amp;nbsp; &lt;br /&gt;During development, you reload several times. You examine the data selected and it seems to be working -- you are getting data from the last 24 hours.&amp;nbsp;It's&amp;nbsp;4:00pm&amp;nbsp;Tuesday&amp;nbsp;afternoon&amp;nbsp;and you promote this to&amp;nbsp;the server and set a reload schedule of daily at 8:00am. A test run on the server shows the data selection is working as planned. &lt;br /&gt;&amp;nbsp; &lt;br /&gt;The document reloads on schedule at Wednesday&amp;nbsp;8:00am. A&amp;nbsp;review of the app&amp;nbsp;shows data going back to &lt;em&gt;Monday at 4:00pm&lt;/em&gt;.&amp;nbsp; After Thursday morning's reload the data range is &lt;em&gt;Tuesday 8:00am to Wednesday 8:00am&lt;/em&gt;. What happened to the rest of Wednesday and all of Thursday? &lt;br /&gt;&amp;nbsp; &lt;br /&gt;The value for Now(0) is set at the &lt;em&gt;end&lt;/em&gt; of script execution. When used in script, Now(0) returns the end time of the&amp;nbsp;&lt;em&gt;previous&lt;/em&gt; script execution, not the time of the &lt;em&gt;current&lt;/em&gt; script execution. &lt;br /&gt;&amp;nbsp; &lt;br /&gt;So on Thursday morning Now(0) returns Wednesday 8:00am -- the end of the last execution.&amp;nbsp;That is not what we were looking for. &amp;nbsp; &lt;br /&gt;&amp;nbsp; &lt;br /&gt;In&amp;nbsp;&lt;em&gt;Charts&lt;/em&gt;, Now(0) returns&amp;nbsp;the end of the latest&amp;nbsp;script execution, which&amp;nbsp;would be Thursday 8:00am.&lt;br /&gt;&amp;nbsp; &lt;br /&gt;Now(1) always returns the time when the function is executed -- the "current" time. During development when reloads are frequent, script Now(0) is usually pretty close to Now(1) and you may not notice the difference. But when a document goes on a daily reload schedule, Now(0) is usually an entire day behind what you want! &lt;br /&gt;&amp;nbsp; &lt;br /&gt;The correct choice in script is generally Now(1), which returns the time when the function is actually executed, not a&amp;nbsp;time related to&amp;nbsp;previous reload. &lt;br /&gt;&amp;nbsp; &lt;br /&gt;To Summarize, use Now(1) in script,&amp;nbsp; Now(0) in charts. &lt;br /&gt;&lt;br /&gt;If you need to establish a deterministic (consistent throughout the entire script)&amp;nbsp;value for "Now" in script, set a variable at the beginning: &lt;br /&gt;&amp;nbsp; &lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;LET &lt;span class="goog-spellcheck-word"&gt;vScriptStart&lt;/span&gt; - Now(1);&lt;/span&gt; &lt;br /&gt;&amp;nbsp; &lt;br /&gt;Then&amp;nbsp;use &lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&lt;span class="goog-spellcheck-word"&gt;vScriptStart&lt;/span&gt;&lt;/span&gt; as the reference point in your script. It may also be used in charts as well. &lt;br /&gt;&lt;br /&gt;-Rob&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5070255803043802824-5166664857156127725?l=qlikviewnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qlikviewnotes.blogspot.com/feeds/5166664857156127725/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5070255803043802824&amp;postID=5166664857156127725' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/5166664857156127725'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/5166664857156127725'/><link rel='alternate' type='text/html' href='http://qlikviewnotes.blogspot.com/2010/07/now-trap.html' title='The Now() Trap'/><author><name>Rob Wunderlich</name><uri>http://www.blogger.com/profile/13048694338956825695</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://3.bp.blogspot.com/_IhQc1-zXHmU/SwH7Z2D8lUI/AAAAAAAAADo/UY17XpuzKLw/S220/avatar.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5070255803043802824.post-1000395603910379082</id><published>2010-05-21T17:24:00.000-07:00</published><updated>2010-05-21T17:32:25.154-07:00</updated><title type='text'>Use cases for Generic Load</title><content type='html'>&lt;div style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none;"&gt;The &lt;span class="goog-spellcheck-word"&gt;Qlikview&lt;/span&gt;&amp;nbsp; "Generic Load" is not frequently&amp;nbsp;used and is therefore&amp;nbsp;sometimes forgotten. Generic Load has&amp;nbsp;some interesting&amp;nbsp;applications and can be a useful item in your script toolbag. &lt;/div&gt;&lt;div style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none;"&gt;&lt;br /&gt;&lt;/div&gt;Generic Load &amp;nbsp;is the complement of&amp;nbsp;"&lt;span class="goog-spellcheck-word"&gt;Crosstable&lt;/span&gt; Load". In a loose sense, you could say that a &lt;span class="goog-spellcheck-word"&gt;Crosstable&lt;/span&gt; Load creates&amp;nbsp;a Generic table and&amp;nbsp; Generic Load creates a Cross table.&lt;br /&gt;&lt;div style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none;"&gt;&lt;br /&gt;&lt;/div&gt;Consider this table&amp;nbsp;which contains a separate row for each Phase of a Project.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_IhQc1-zXHmU/S_cEW-e7ZgI/AAAAAAAAAH4/J-bOlvGVn2c/s1600/ProjectGeneric.gif" imageanchor="1" style="clear: left; cssfloat: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" gu="true" src="http://4.bp.blogspot.com/_IhQc1-zXHmU/S_cEW-e7ZgI/AAAAAAAAAH4/J-bOlvGVn2c/s320/ProjectGeneric.gif" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none; clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div align="left" class="separator" style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none; clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none; clear: both; text-align: justify;"&gt;Now suppose you want to flatten this table to a single row per Project.&amp;nbsp;You have&amp;nbsp;a variable number of Phases per Project. The resulting data model should look like this:&lt;/div&gt;&lt;div class="separator" style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none; clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none; clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none; clear: both; text-align: justify;"&gt;&lt;a href="http://2.bp.blogspot.com/_IhQc1-zXHmU/S_cC_MMcEKI/AAAAAAAAAHw/cIMXn0VOLj8/s1600/ProjectFlattened.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" gu="true" height="31" src="http://2.bp.blogspot.com/_IhQc1-zXHmU/S_cC_MMcEKI/AAAAAAAAAHw/cIMXn0VOLj8/s400/ProjectFlattened.gif" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div align="left" class="separator" style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none; clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none; clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none; clear: both; text-align: left;"&gt;The model above can be accomplished with a&amp;nbsp;two GENERIC &lt;span class="goog-spellcheck-word"&gt;LOADs&lt;/span&gt; against the &lt;span class="goog-spellcheck-word"&gt;ProjectTable&lt;/span&gt;:&amp;nbsp;&lt;/div&gt;&lt;div class="separator" style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none; clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none; clear: both; text-align: left;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;GENERIC LOAD Project, 'Start Phase ' &amp;amp; Phase, &lt;span class="goog-spellcheck-word"&gt;StartDate&lt;/span&gt; &lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&lt;br /&gt;RESIDENT &lt;span class="goog-spellcheck-word"&gt;ProjectTable&lt;/span&gt;;&lt;/span&gt;&lt;/div&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;GENERIC LOAD Project, 'End Phase ' &amp;amp; Phase, &lt;span class="goog-spellcheck-word"&gt;EndDate&lt;/span&gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;RESIDENT &lt;span class="goog-spellcheck-word"&gt;ProjectTable&lt;/span&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Generic Load creates additional &lt;span class="goog-spellcheck-word"&gt;Qlikview&lt;/span&gt; tables. The additional tables &lt;strong&gt;cannot&lt;/strong&gt; be avoided by combining a CONCATENATE or JOIN prefix. In the next example I'll offer a technique to consolidate the tables. &lt;br /&gt;&lt;br /&gt;Here's another application of Generic. Consider this example table. &lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_IhQc1-zXHmU/S_cU-0fsZ8I/AAAAAAAAAIA/BZ26ma-guzM/s1600/OrdersTable.gif" imageanchor="1" style="clear: left; cssfloat: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" gu="true" src="http://1.bp.blogspot.com/_IhQc1-zXHmU/S_cU-0fsZ8I/AAAAAAAAAIA/BZ26ma-guzM/s320/OrdersTable.gif" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Suppose you want to generate flag fields for each of the possible order statuses? The flags could be created with a single Generic Load.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;Flags:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;GENERIC LOAD Order, 'Status_' &amp;amp; Status, 1 &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;RESIDENT &lt;span class="goog-spellcheck-word"&gt;OrdersTable&lt;/span&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: inherit;"&gt;The resulting data model&lt;/span&gt; now contains flags for each Order.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_IhQc1-zXHmU/S_cXto3PffI/AAAAAAAAAII/3W3UKCyFilk/s1600/OrdersFlags.gif" imageanchor="1" style="clear: left; cssfloat: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" gu="true" height="66" src="http://3.bp.blogspot.com/_IhQc1-zXHmU/S_cXto3PffI/AAAAAAAAAII/3W3UKCyFilk/s400/OrdersFlags.gif" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;As mentioned previously, Generic Load creates additional tables. The table view after the above Generic Load is:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_IhQc1-zXHmU/S_cY_eT4WFI/AAAAAAAAAIQ/9C8g3wIs1YM/s1600/TableView.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" gu="true" src="http://3.bp.blogspot.com/_IhQc1-zXHmU/S_cY_eT4WFI/AAAAAAAAAIQ/9C8g3wIs1YM/s320/TableView.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;You can see Generic makes a new table for each new field it creates. That's fine if it doesn't cause synthetic keys or other problems. If you want to merge the Flag fields into the fact&amp;nbsp;table (&lt;span class="goog-spellcheck-word"&gt;OrdersTable&lt;/span&gt;), you can do it after the Generic Load with a bit of code like this:&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: justify;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;FOR i = 0 to &lt;span class="goog-spellcheck-word"&gt;NoOfTables&lt;/span&gt;()&lt;/span&gt;&lt;/div&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp; &lt;span class="goog-spellcheck-word"&gt;TableList&lt;/span&gt;:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp; LOAD &lt;span class="goog-spellcheck-word"&gt;TableName&lt;/span&gt;($(i)) as &lt;span class="goog-spellcheck-word"&gt;Tablename&lt;/span&gt; &lt;span class="goog-spellcheck-word"&gt;AUTOGENERATE&lt;/span&gt; 1&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp; WHERE &lt;span class="goog-spellcheck-word"&gt;WildMatch&lt;/span&gt;(&lt;span class="goog-spellcheck-word"&gt;TableName&lt;/span&gt;($(i)), 'Flags.*');&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;NEXT i&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;FOR i = 1 to &lt;span class="goog-spellcheck-word"&gt;FieldValueCount&lt;/span&gt;('Tablename')&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp; LET &lt;span class="goog-spellcheck-word"&gt;vTable&lt;/span&gt; = &lt;span class="goog-spellcheck-word"&gt;FieldValue&lt;/span&gt;('Tablename', $(i));&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp; LEFT JOIN (&lt;span class="goog-spellcheck-word"&gt;OrdersTable&lt;/span&gt;) LOAD * RESIDENT $(&lt;span class="goog-spellcheck-word"&gt;vTable&lt;/span&gt;);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp; DROP TABLE $(&lt;span class="goog-spellcheck-word"&gt;vTable&lt;/span&gt;);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;NEXT i&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;DROP TABLE &lt;span class="goog-spellcheck-word"&gt;TableList&lt;/span&gt;;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Here's the table view after the Joins.&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_IhQc1-zXHmU/S_cc1MjCMbI/AAAAAAAAAIY/_Gx8GXDBf1c/s1600/TableViewJoin.png" imageanchor="1" style="clear: left; cssfloat: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" gu="true" src="http://4.bp.blogspot.com/_IhQc1-zXHmU/S_cc1MjCMbI/AAAAAAAAAIY/_Gx8GXDBf1c/s320/TableViewJoin.png" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="text-align: left;"&gt;Generic load is not an everyday tool, but can prove&amp;nbsp;useful in specific situations.&lt;/div&gt;&lt;br /&gt;The &lt;span class="goog-spellcheck-word"&gt;qvw&lt;/span&gt; examples used in this post may be downloaded from&amp;nbsp;&lt;a href="http://robwunderlich.com/downloads/GenericLoadExamples.zip"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;div class="separator" style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none; clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none; clear: both; text-align: left;"&gt;-Rob&amp;nbsp;&lt;span class="goog-spellcheck-word"&gt;Wunderlich&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5070255803043802824-1000395603910379082?l=qlikviewnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qlikviewnotes.blogspot.com/feeds/1000395603910379082/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5070255803043802824&amp;postID=1000395603910379082' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/1000395603910379082'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/1000395603910379082'/><link rel='alternate' type='text/html' href='http://qlikviewnotes.blogspot.com/2010/05/use-cases-for-generic-load.html' title='Use cases for Generic Load'/><author><name>Rob Wunderlich</name><uri>http://www.blogger.com/profile/13048694338956825695</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://3.bp.blogspot.com/_IhQc1-zXHmU/SwH7Z2D8lUI/AAAAAAAAADo/UY17XpuzKLw/S220/avatar.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_IhQc1-zXHmU/S_cEW-e7ZgI/AAAAAAAAAH4/J-bOlvGVn2c/s72-c/ProjectGeneric.gif' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5070255803043802824.post-754241660925116262</id><published>2010-02-20T11:42:00.000-08:00</published><updated>2010-02-20T11:46:36.268-08:00</updated><title type='text'>Reusing expressions -- chart column references</title><content type='html'>&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;It's often useful to avoid&amp;nbsp;repeating lengthy expressions. Here's one technique for reusing expressions.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none;"&gt;&lt;span style="font-family: Arial;"&gt;Consider the chart below.&amp;nbsp; The Expression for the column labeled "Net" is:&lt;/span&gt;&lt;span style="font-family: Arial;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none;"&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp; =sum(Quantity * Price) * (1-Discount)&lt;/span&gt;&lt;/div&gt;&lt;div style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none;"&gt;&lt;a href="http://2.bp.blogspot.com/_IhQc1-zXHmU/S4Aq6wd0RrI/AAAAAAAAAG4/BMYfFScC9w4/s1600-h/net.jpg" imageanchor="1" style="clear: left; cssfloat: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" ct="true" src="http://2.bp.blogspot.com/_IhQc1-zXHmU/S4Aq6wd0RrI/AAAAAAAAAG4/BMYfFScC9w4/s320/net.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;Let's add another column for "Commission", defined&amp;nbsp; as 10% of Net. Instead of repeating the Net calculation,&amp;nbsp;use the expression:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp; =Net * .1&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="border-bottom: medium none; border-left: medium none; border-right: medium none; border-top: medium none; clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_IhQc1-zXHmU/S4AtU90HlCI/AAAAAAAAAHA/KUtdTovkGq8/s1600-h/Commission.jpg" imageanchor="1" style="clear: left; cssfloat: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" ct="true" src="http://1.bp.blogspot.com/_IhQc1-zXHmU/S4AtU90HlCI/AAAAAAAAAHA/KUtdTovkGq8/s320/Commission.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;Qlikview allows referencing the value of another column in the same chart by name. The&amp;nbsp;name is the value&amp;nbsp;assigned to the column label. "Net" in this case is not a Field. It is a symbolic reference to an expression. It may be used in other&amp;nbsp;expressions in the same chart, but not in&amp;nbsp;places where a Field name is expected. &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp; =Net / 2&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Allowed&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp; =above(Net)&lt;/span&gt;&amp;nbsp;&amp;nbsp; Allowed&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp; =Sum(Net)&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Not allowed&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;Column references can be&amp;nbsp;very useful&amp;nbsp;in Expression attributes. Let's&amp;nbsp;&lt;strong&gt;bold &lt;/strong&gt;any Commission value over $200. We'll&amp;nbsp;use a Text Format expression of:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;=if(Commission &amp;gt; 200, '&amp;lt;B&amp;gt;')&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_IhQc1-zXHmU/S4A4M98HSpI/AAAAAAAAAHQ/i5yPTV5JF0U/s1600-h/properties.jpg" imageanchor="1" style="clear: left; cssfloat: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" ct="true" height="177" src="http://1.bp.blogspot.com/_IhQc1-zXHmU/S4A4M98HSpI/AAAAAAAAAHQ/i5yPTV5JF0U/s400/properties.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;giving this result:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_IhQc1-zXHmU/S4AtYCEMYZI/AAAAAAAAAHI/xhRLFV2UHbc/s1600-h/bold.jpg" imageanchor="1" style="clear: left; cssfloat: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" ct="true" src="http://3.bp.blogspot.com/_IhQc1-zXHmU/S4AtYCEMYZI/AAAAAAAAAHI/xhRLFV2UHbc/s320/bold.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;-Rob&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5070255803043802824-754241660925116262?l=qlikviewnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qlikviewnotes.blogspot.com/feeds/754241660925116262/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5070255803043802824&amp;postID=754241660925116262' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/754241660925116262'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/754241660925116262'/><link rel='alternate' type='text/html' href='http://qlikviewnotes.blogspot.com/2010/02/reusing-expressions-chart-column.html' title='Reusing expressions -- chart column references'/><author><name>Rob Wunderlich</name><uri>http://www.blogger.com/profile/13048694338956825695</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://3.bp.blogspot.com/_IhQc1-zXHmU/SwH7Z2D8lUI/AAAAAAAAADo/UY17XpuzKLw/S220/avatar.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_IhQc1-zXHmU/S4Aq6wd0RrI/AAAAAAAAAG4/BMYfFScC9w4/s72-c/net.jpg' height='72' width='72'/><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5070255803043802824.post-6179874500334020579</id><published>2010-02-08T10:05:00.000-08:00</published><updated>2011-03-08T20:50:14.748-08:00</updated><title type='text'>Setting Initial Selections in Version 9</title><content type='html'>&lt;div style="text-align: left;"&gt;&lt;/div&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;A common Qlikview requirement is that when a user opens a document, some type of dynamic selection -- like current date -- should be made. &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;In QV 8 this&amp;nbsp;entailed assigning a macro to the Document OnOpen event and using macro statements similar to&amp;nbsp;this:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;ActiveDocument.GetField("Year").Select ActiveDocument.Evaluate("year(today(1))")&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;The Actions feature of QV 9 has eliminated the need to use macros for initial selections. In V9, one or more Actions can be assigned to the Document OnOpen trigger. The actions may be "Select In Field" using a expression like =&lt;/span&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;"&gt;year(today(1)).&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;A very modular way to make Initial Selections in V9 is to make all the selections you require using search expressions and then save those as a Bookmark. The Bookmark can then be applied as the OnOpen Action.&amp;nbsp; For example, here are selections reflecting current Year, Month and Weekday using search expressions. &lt;/span&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_IhQc1-zXHmU/S3BP2imYb1I/AAAAAAAAAGo/73gvyHRR5no/s1600-h/SearchSelections.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;img border="0" kt="true" src="http://1.bp.blogspot.com/_IhQc1-zXHmU/S3BP2imYb1I/AAAAAAAAAGo/73gvyHRR5no/s320/SearchSelections.jpg" /&gt;&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;Example qvws that demonstrate initial selections in both V8 and V9 can be downloaded here &lt;/span&gt;&lt;a href="http://robwunderlich.com/downloads"&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;http://robwunderlich.com/downloads&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;-Rob&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5070255803043802824-6179874500334020579?l=qlikviewnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qlikviewnotes.blogspot.com/feeds/6179874500334020579/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5070255803043802824&amp;postID=6179874500334020579' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/6179874500334020579'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/6179874500334020579'/><link rel='alternate' type='text/html' href='http://qlikviewnotes.blogspot.com/2010/02/setting-initial-selections-in-version-9.html' title='Setting Initial Selections in Version 9'/><author><name>Rob Wunderlich</name><uri>http://www.blogger.com/profile/13048694338956825695</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://3.bp.blogspot.com/_IhQc1-zXHmU/SwH7Z2D8lUI/AAAAAAAAADo/UY17XpuzKLw/S220/avatar.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_IhQc1-zXHmU/S3BP2imYb1I/AAAAAAAAAGo/73gvyHRR5no/s72-c/SearchSelections.jpg' height='72' width='72'/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5070255803043802824.post-1629396208900451042</id><published>2010-01-12T15:54:00.000-08:00</published><updated>2010-01-13T18:20:40.410-08:00</updated><title type='text'>Best way to count keys? Don't.</title><content type='html'>&lt;span style="font-family:arial;"&gt;I was recently reviewing a problem where a chart Count() function produced differing results between QV 8.5 and 9. The field being counted was a key field. Counting a key field without using DISTINCT, especially a one-to-many key, can produce ambiguous results and should be avoided. &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;The recommended approach is add a counter field and sum() that field. For example, in an Orders table, add the field:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;1 as OrderCounter&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;and then count Orders with:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;sum(OrderCounter)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Yes, &lt;span style="font-family:courier new;"&gt;count(OrderCounter)&lt;/span&gt; will work as well. The Qlikview literature still states that &lt;span style="font-family:courier new;"&gt;sum()&lt;/span&gt; is faster and preferable to &lt;span style="font-family:courier new;"&gt;count().&lt;/span&gt; John Witherspoon recently showed me some tests that demonstrate count() being faster than sum() in Version 9, so it's possible that recommendation should be examined if you are working on a very large application.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;-Rob&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5070255803043802824-1629396208900451042?l=qlikviewnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qlikviewnotes.blogspot.com/feeds/1629396208900451042/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5070255803043802824&amp;postID=1629396208900451042' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/1629396208900451042'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/1629396208900451042'/><link rel='alternate' type='text/html' href='http://qlikviewnotes.blogspot.com/2010/01/best-way-to-count-keys-dont.html' title='Best way to count keys? Don&apos;t.'/><author><name>Rob Wunderlich</name><uri>http://www.blogger.com/profile/13048694338956825695</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://3.bp.blogspot.com/_IhQc1-zXHmU/SwH7Z2D8lUI/AAAAAAAAADo/UY17XpuzKLw/S220/avatar.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5070255803043802824.post-7070173640849160148</id><published>2009-12-04T16:21:00.000-08:00</published><updated>2009-12-21T11:35:48.376-08:00</updated><title type='text'>Simplify with Preceding Load</title><content type='html'>&lt;span style="font-family:arial;"&gt;Most QV script developers are introduced to "preceding load" as a LOAD that precedes an SQL SELECT. But a LOAD may also precede another LOAD, which can be a very useful tool.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;Let's review a typical preceding load.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Table1:&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;LOAD Customer, Sales, today(1) as LoadDate ;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;SQL SELECT Customer, Country, Sales FROM SalesResults ;&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;The absence of a "FROM" or "RESIDENT" clause in the LOAD is what makes this a "preceding load".&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;The SQL SELECT will be executed first. The results of the SELECT will be used as input to the LOAD statement.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;Table1 will have three fields -- Customer, Sale, LoadDate.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:arial;"&gt;The Field "Country" will not be present in Table1 because "Country" is not repeated on the LOAD statement.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;The field "LoadDate" does not exist in the SQL SELECT and is added by the LOAD. &lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;Let's look at an example of where preceding load can be useful. When loading data, you may need to use expressions to parse or cleanse data. For example, extracting a timestamp from a string in a text file.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;Table1:&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Arial;"&gt;LOAD&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Arial;"&gt;&lt;strong&gt;timestamp(timestamp#(mid(@1:n,3,12), 'MMDDYYhhmmss')) as EventTime&lt;/strong&gt;,&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Arial;"&gt;mid(@1:n, 17) as Event&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Arial;"&gt;FROM &lt;/span&gt;&lt;span style="font-family:Arial;"&gt;myfile.txt (fix, codepage is 1252);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;What if you want additional time dimensions from the data? You could add expressions like:&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;date(date#(mid(@1:n, 3, 6)) as EventDate&lt;br /&gt;month(date(date#(mid(@1:n, 3, 6))) as EventMonth&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;The script would soon get messy with "paren-disease" and become harder to maintain. Preceding Load to the rescue.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Table2:&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;&lt;strong&gt;LOAD *,&lt;br /&gt;&lt;/strong&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;&lt;strong&gt;floor(EventTime) as EventDate,&lt;br /&gt;&lt;/strong&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;&lt;strong&gt;month(EventTime) as EventMonth,&lt;br /&gt;&lt;/strong&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;&lt;strong&gt;year(EventTime) as EventYear,&lt;br /&gt;&lt;/strong&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;&lt;strong&gt;hour(EventTime) as EventHour&lt;br /&gt;&lt;/strong&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;&lt;strong&gt;;&lt;/strong&gt;&lt;br /&gt;LOAD&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;timestamp(timestamp#(mid(@1:n,3,12), 'MMDDYYhhmmss')) as EventTime, mid(@1:n, 17) as Event&lt;br /&gt;FROM myfile.txt (fix, codepage is 1252);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;The syntax is greatly simplified by reusing the "parsed once" EventTime.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;Table2 will contain six fields: Event, EventTime, EventDate, EventMonth, EventYear, EventHour.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;The "*" in the top load includes the fields emitted by the bottom load -- EventTime &amp;amp; EventTime.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;span style="font-family:Arial;"&gt;Preceding Loads may also be stacked more than two deep as in this example.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:courier new;"&gt;Table2:&lt;br /&gt;&lt;strong&gt;LOAD *,&lt;br /&gt;if(match(EventMonth, 'Aug', 'Dec') OR weekday(EventDate) &gt; 5, 'Holiday', 'Standard') as Rate;&lt;br /&gt;&lt;/strong&gt;&lt;br /&gt;LOAD *,date(floor(EventTime)) as EventDate,&lt;br /&gt;month(EventTime) as EventMonth,&lt;br /&gt;year(EventTime) as EventYear,&lt;br /&gt;hour(EventTime) as EventHour;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:courier new;"&gt;LOAD timestamp(timestamp#(mid(@1:n,3,12), 'MMDDYYhhmmss')) as EventTime,&lt;br /&gt;mid(@1:n, 17) as Event&lt;br /&gt;FROM myfile.txt (fix, codepage is 1252);&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:arial;"&gt;Preceding load is a useful tool to simplify the syntax of your script and make it easier to maintain.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Arial;"&gt;-Rob&lt;/span&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5070255803043802824-7070173640849160148?l=qlikviewnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qlikviewnotes.blogspot.com/feeds/7070173640849160148/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5070255803043802824&amp;postID=7070173640849160148' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/7070173640849160148'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/7070173640849160148'/><link rel='alternate' type='text/html' href='http://qlikviewnotes.blogspot.com/2009/12/simplify-with-preceeding-load.html' title='Simplify with Preceding Load'/><author><name>Rob Wunderlich</name><uri>http://www.blogger.com/profile/13048694338956825695</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://3.bp.blogspot.com/_IhQc1-zXHmU/SwH7Z2D8lUI/AAAAAAAAADo/UY17XpuzKLw/S220/avatar.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5070255803043802824.post-1136607933999646890</id><published>2009-11-19T15:39:00.000-08:00</published><updated>2009-11-19T20:44:21.108-08:00</updated><title type='text'>Understanding Join and Concatenate</title><content type='html'>&lt;span style="font-family:arial;"&gt;The Qlikview script functions JOIN and CONCATENATE can sometimes be used to tackle the same problem, but there are important differences that should be understood. &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Examine the sample tables below. Note that they share one common field name, "Key". Also note that Table1 has a Key value "3" that is not present in Table2.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;img id="BLOGGER_PHOTO_ID_5405968028123867762" style="DISPLAY: block; MARGIN: 0px auto 10px; WIDTH: 320px; CURSOR: hand; HEIGHT: 77px; TEXT-ALIGN: center" alt="" src="http://4.bp.blogspot.com/_IhQc1-zXHmU/SwXbR49xKnI/AAAAAAAAAEI/uAqaPGNFyQc/s320/sampleData.jpg" border="0" /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-family:arial;"&gt;JOIN will combine rows where the Key value matches. The keyword OUTER will also retain rows that do not match rows in the other table. Here's what the merged table will look like after an outer join.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:courier new;"&gt;OUTER JOIN (Table1) LOAD * RESIDENT Table2;&lt;/span&gt;&lt;/p&gt;&lt;a href="http://2.bp.blogspot.com/_IhQc1-zXHmU/SwXe2Mtq1iI/AAAAAAAAAEQ/bUi0JS9Y3Oc/s1600/JoinResult.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5405971950435227170" style="FLOAT: left; MARGIN: 0px 10px 10px 0px; WIDTH: 255px; CURSOR: hand; HEIGHT: 100px" alt="" src="http://2.bp.blogspot.com/_IhQc1-zXHmU/SwXe2Mtq1iI/AAAAAAAAAEQ/bUi0JS9Y3Oc/s320/JoinResult.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Values A1 and C1, which were in different tables, now occupy the same row in the result table. The row with Key 3 has missing values for C &amp;amp; D, because there was no matching Key in Table2.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;Creating a chart that uses "Key" for dimension will produce results similar to the Table Box above.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;img id="BLOGGER_PHOTO_ID_5406004412041755954" style="DISPLAY: block; MARGIN: 0px auto 10px; WIDTH: 320px; CURSOR: hand; HEIGHT: 90px; TEXT-ALIGN: center" alt="" src="http://3.bp.blogspot.com/_IhQc1-zXHmU/SwX8XtnxfTI/AAAAAAAAAE4/dJJjelTYlBU/s320/JoinChart.jpg" border="0" /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;The important point is that values with the same Key value have been merged together into a single row. If value A1 is selected, note that values C1 &amp;amp; D1 remain associated (white). The set A1,B1,C1,D1 is indivisible. &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;img id="BLOGGER_PHOTO_ID_5406007098086774370" style="DISPLAY: block; MARGIN: 0px auto 10px; WIDTH: 320px; CURSOR: hand; HEIGHT: 124px; TEXT-ALIGN: center" alt="" src="http://3.bp.blogspot.com/_IhQc1-zXHmU/SwX-0D6z1mI/AAAAAAAAAFA/r--unqfrnUI/s320/JoinSelection.jpg" border="0" /&gt; &lt;/p&gt;&lt;p&gt;&lt;span style="font-family:arial;"&gt;Now let's look at Concatenate. Concatenate appends the rows of one table to another. Concatenate never merges any rows. The number of rows in a concatenated table is always the sum of the rows from the two input tables. Here's what our sample data will look like after Concatenate.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;CONCATENATE (Table1) LOAD * RESIDENT Table2;&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;a href="http://2.bp.blogspot.com/_IhQc1-zXHmU/SwXv9-873uI/AAAAAAAAAEg/0MaT2YIqUUo/s1600/ConcatenateResult.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5405990775877787362" style="FLOAT: left; MARGIN: 0px 10px 10px 0px; WIDTH: 253px; CURSOR: hand; HEIGHT: 140px" alt="" src="http://2.bp.blogspot.com/_IhQc1-zXHmU/SwXv9-873uI/AAAAAAAAAEg/0MaT2YIqUUo/s320/ConcatenateResult.jpg" border="0" /&gt;&lt;/a&gt;&lt;span style="font-family:arial;"&gt;Rows with like Key values are &lt;strong&gt;not &lt;/strong&gt;merged together.&lt;/span&gt; &lt;span style="font-family:arial;"&gt;The rows from Table2 are simply appended to Table1. Because the tables have different fields, rows will have null values for the fields from the "other" table.&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;span style="font-family:arial;"&gt;If the data is used to build a chart that utilizes the common field "Key" as dimension, the chart looks just like the JOINed table.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Arial;"&gt;&lt;img id="BLOGGER_PHOTO_ID_5405997508186073314" style="DISPLAY: block; MARGIN: 0px auto 10px; WIDTH: 320px; CURSOR: hand; HEIGHT: 90px; TEXT-ALIGN: center" alt="" src="http://2.bp.blogspot.com/_IhQc1-zXHmU/SwX2F2wT6OI/AAAAAAAAAEo/JOW93VI1uTA/s320/ConcatenatedChart.jpg" border="0" /&gt;&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-family:arial;"&gt;Let's make the selection "A1" in Field A and see it's impact on our visible charts and tables.&lt;/span&gt;&lt;/p&gt;&lt;img id="BLOGGER_PHOTO_ID_5406001643871283586" style="DISPLAY: block; MARGIN: 0px auto 10px; WIDTH: 320px; CURSOR: hand; HEIGHT: 109px; TEXT-ALIGN: center" alt="" src="http://2.bp.blogspot.com/_IhQc1-zXHmU/SwX52lYgKYI/AAAAAAAAAEw/_v4UfNnoWbI/s320/ConcatenateSelection.jpg" border="0" /&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-family:arial;"&gt;When A1 is selected, the association to C1 &amp;amp; D1 is lost and C/D values become null in both the Chart and Tablebox. We cannot select both A1 and C1. This is a different result than the JOINed example. &lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-family:Arial;"&gt;Let's consider a more realistic example where we may choose between JOIN and CONCATENATE. Consider the two tables below. Note that only one BudgetAmount row is present for each Region-Year combination. In the Sales table, the SalesAmount is broken down by Department within Region.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;img id="BLOGGER_PHOTO_ID_5406019712398120130" style="DISPLAY: block; MARGIN: 0px auto 10px; WIDTH: 320px; CURSOR: hand; HEIGHT: 127px; TEXT-ALIGN: center" alt="" src="http://1.bp.blogspot.com/_IhQc1-zXHmU/SwYKST4_1MI/AAAAAAAAAFg/DvwF48aaxCY/s320/BudgetSalesData.jpg" border="0" /&gt;&lt;span style="font-family:arial;"&gt;If we load both tables we can produce a chart using expressions like =Sum(BudgetAmount).&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;a href="http://1.bp.blogspot.com/_IhQc1-zXHmU/SwYMutiG7mI/AAAAAAAAAFo/yNnRRo6g2Yg/s1600/BudgetSalesChartLinked.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5406022399341031010" style="FLOAT: left; MARGIN: 0px 10px 10px 0px; WIDTH: 320px; CURSOR: hand; HEIGHT: 93px" alt="" src="http://1.bp.blogspot.com/_IhQc1-zXHmU/SwYMutiG7mI/AAAAAAAAAFo/yNnRRo6g2Yg/s320/BudgetSalesChartLinked.jpg" border="0" /&gt;&lt;/a&gt;&lt;span style="font-family:arial;"&gt;The Budget and Sales values have been summed correctly. &lt;/span&gt;&lt;/p&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt; &lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;br /&gt; &lt;/p&gt;&lt;p&gt;&lt;a href="http://3.bp.blogspot.com/_IhQc1-zXHmU/SwYYvWFNfSI/AAAAAAAAAGQ/rv2R--o8pzw/s1600/SynKey.jpg"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;&lt;a href="http://4.bp.blogspot.com/_IhQc1-zXHmU/SwYaNcwCKuI/AAAAAAAAAGg/_6s_J2aPgOA/s1600/SynKey.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5406037221063142114" style="FLOAT: right; MARGIN: 0px 0px 10px 10px; WIDTH: 195px; CURSOR: hand; HEIGHT: 171px" alt="" src="http://4.bp.blogspot.com/_IhQc1-zXHmU/SwYaNcwCKuI/AAAAAAAAAGg/_6s_J2aPgOA/s320/SynKey.jpg" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;We then notice that we have an undesirable synthetic key, created by the Budget and Sales tables sharing the Year and Region fields. One approach to eliminate the synthetic key would be &lt;a href="http://4.bp.blogspot.com/_IhQc1-zXHmU/SwYZ0bB6adI/AAAAAAAAAGY/FK4lnYG5hBE/s1600/SynKey.jpg"&gt;&lt;/a&gt;JOIN or CONCATENATE. But which one in this case?&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-family:arial;"&gt;Let's try JOIN and see what the Chart looks like. &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:courier new;"&gt;OUTER JOIN (Budget) LOAD * RESIDENT SALES&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_IhQc1-zXHmU/SwYObvrT7dI/AAAAAAAAAFw/bETUTdpuS4A/s1600/BudgetSalesChartJoin.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5406024272522243538" style="FLOAT: left; MARGIN: 0px 10px 10px 0px; WIDTH: 320px; CURSOR: hand; HEIGHT: 93px" alt="" src="http://2.bp.blogspot.com/_IhQc1-zXHmU/SwYObvrT7dI/AAAAAAAAAFw/bETUTdpuS4A/s320/BudgetSalesChartJoin.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;The summed Budget numbers are incorrect!&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt; &lt;/p&gt;&lt;p&gt;&lt;span style="font-family:arial;"&gt;A look at raw data of the joined table will identify the problem. The JOIN repeated the BudgetAmount value on each Department row&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;img id="BLOGGER_PHOTO_ID_5406025520779355730" style="DISPLAY: block; MARGIN: 0px auto 10px; WIDTH: 320px; CURSOR: hand; HEIGHT: 157px; TEXT-ALIGN: center" alt="" src="http://1.bp.blogspot.com/_IhQc1-zXHmU/SwYPkZy_5lI/AAAAAAAAAF4/plYlAcGFEdw/s320/BudgetSalesJoinedData.jpg" border="0" /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Let's try with CONCATENATE.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;CONCATENATE (Budget) LOAD * RESIDENT Sales;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_IhQc1-zXHmU/SwYQYGwaAVI/AAAAAAAAAGA/Dag0pXl_-bs/s1600/BudgetSalesChartConcatenate.jpg"&gt;&lt;img id="BLOGGER_PHOTO_ID_5406026409021407570" style="FLOAT: left; MARGIN: 0px 10px 10px 0px; WIDTH: 320px; CURSOR: hand; HEIGHT: 93px" alt="" src="http://3.bp.blogspot.com/_IhQc1-zXHmU/SwYQYGwaAVI/AAAAAAAAAGA/Dag0pXl_-bs/s320/BudgetSalesChartConcatenate.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;The numbers are now correct and we've accomplished the goal of eliminating the synthetic key.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;A peek at the data in the Concatenated table will make it clear why the chart is now correct. There is only BudgetAmount value or each Year-Region.&lt;/span&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;img id="BLOGGER_PHOTO_ID_5406027311982752930" style="DISPLAY: block; MARGIN: 0px auto 10px; WIDTH: 320px; CURSOR: hand; HEIGHT: 214px; TEXT-ALIGN: center" alt="" src="http://1.bp.blogspot.com/_IhQc1-zXHmU/SwYRMqjKtKI/AAAAAAAAAGI/UpGsbwnlBb8/s320/BudgetSalesConcatenatedData.jpg" border="0" /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-family:arial;"&gt;JOIN and CONCATENATE are both very useful and frequently used functions in Qlikview. It's important to understand the differences between them.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:arial;"&gt;-Rob&lt;/span&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5070255803043802824-1136607933999646890?l=qlikviewnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qlikviewnotes.blogspot.com/feeds/1136607933999646890/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5070255803043802824&amp;postID=1136607933999646890' title='14 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/1136607933999646890'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/1136607933999646890'/><link rel='alternate' type='text/html' href='http://qlikviewnotes.blogspot.com/2009/11/understanding-join-and-concatenate.html' title='Understanding Join and Concatenate'/><author><name>Rob Wunderlich</name><uri>http://www.blogger.com/profile/13048694338956825695</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://3.bp.blogspot.com/_IhQc1-zXHmU/SwH7Z2D8lUI/AAAAAAAAADo/UY17XpuzKLw/S220/avatar.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_IhQc1-zXHmU/SwXbR49xKnI/AAAAAAAAAEI/uAqaPGNFyQc/s72-c/sampleData.jpg' height='72' width='72'/><thr:total>14</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5070255803043802824.post-4221083100707989089</id><published>2009-11-15T11:02:00.000-08:00</published><updated>2009-11-15T11:44:55.466-08:00</updated><title type='text'>Customer Portal Delivers</title><content type='html'>&lt;span style="font-family:arial;"&gt;I've blogged in the past and buttonholed Qliktech employees about the &lt;/span&gt;&lt;a href="http://qlikviewnotes.blogspot.com/2008/09/gripe-re-bug-reporting-research.html"&gt;&lt;span style="font-family:arial;"&gt;need for greater visibility of bug tracking and enhancement requests&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;"&gt;. The new Customer Portal delivers just what I was looking for and more. &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;The Customer Portal is available from a tab on the &lt;/span&gt;&lt;a href="http://www.qliktech.com/"&gt;&lt;span style="font-family:arial;"&gt;www.qliktech.com&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;"&gt; or QlikCommunity web sites. The Portal uses your existing Qlikview userid (SSO) and provides a link to register if you are new. &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;In addition to online support case submission and tracking, the Portal offers:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-family:arial;"&gt;Searchable database of issues and solutions reported by other customers.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:arial;"&gt;Submission of "ideas" (enhancement requests). You can also vote and comment on ideas.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:arial;"&gt;Technical papers and how-to videos.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:arial;"&gt;License inventory for your site.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;span style="font-family:arial;"&gt;I've found the Portal to be easy to navigate and the response good. It's so easy I don't have any tips to offer. I like the PDF viewing feature in the Content section and wish we could do the same for videos. &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Arial;"&gt;I encountered one small glitch in my initial login to the Portal. I was already logged in to QlikCommunity and entered the Portal from the tab. The Portal declared that my password was expired and required me to change it. The result was that my QlikCommunity and Customer Portal passwords were no longer synchronized. I rectified the problem by changing my password in QlikComuunity to match.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:arial;"&gt;Content is still being moved in from the old locations. It may be a few more days before all the content is there. As is frequently the case in migrations, some text formatting and history is lost when content is moved from old system to the new. For example, most of the "ideas" look like they were submitted by a single user. I'm guessing this is the user assigned to copy the entries over from the existing "Enhancement Requests" database.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:arial;"&gt;All in all, an exceptional resource for Customers. Thanks to the Qliktech team for getting this in place.&lt;/span&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5070255803043802824-4221083100707989089?l=qlikviewnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qlikviewnotes.blogspot.com/feeds/4221083100707989089/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5070255803043802824&amp;postID=4221083100707989089' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/4221083100707989089'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/4221083100707989089'/><link rel='alternate' type='text/html' href='http://qlikviewnotes.blogspot.com/2009/11/customer-portal-delivers.html' title='Customer Portal Delivers'/><author><name>Rob Wunderlich</name><uri>http://www.blogger.com/profile/13048694338956825695</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://3.bp.blogspot.com/_IhQc1-zXHmU/SwH7Z2D8lUI/AAAAAAAAADo/UY17XpuzKLw/S220/avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5070255803043802824.post-995084298675245478</id><published>2009-05-12T23:13:00.000-07:00</published><updated>2009-05-13T07:37:41.954-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='qlikview'/><title type='text'>BOQC: Flexible Interval Classification</title><content type='html'>&lt;span style="font-family:arial;"&gt;Another post in the "Best of QlikCommunity" series.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;In this &lt;a href="http://community.qlikview.com/forums/t/16454.aspx"&gt;QlikCommunity Forum thread &lt;/a&gt;the poster asked about using the class() function to create a dynamic dimension of 30 minute intervals in a chart. He wanted to format the class values as display friendly time ranges. &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;My solution would have been to use mapping to format the classes to the desired display format. However, this would have been a lot of data entry for 48 intervals in a day.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;John Witherspoon posted a more elegant solution utilizing a simple expression. &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;dual(time(floor(timestamp, 1/48),'h:mm TT') &amp;amp; ' - ' &amp;amp;&lt;br /&gt;time(ceil (timestamp, 1/48),'h:mm TT')&lt;br /&gt;,floor(frac(timestamp),1/48))&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;Using John's example, I was able to extend the idea to easily provide for a user selectable interval size.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;Read the thread for details.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;-Rob&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5070255803043802824-995084298675245478?l=qlikviewnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qlikviewnotes.blogspot.com/feeds/995084298675245478/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5070255803043802824&amp;postID=995084298675245478' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/995084298675245478'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/995084298675245478'/><link rel='alternate' type='text/html' href='http://qlikviewnotes.blogspot.com/2009/05/boqc-flexible-interval-classification.html' title='BOQC: Flexible Interval Classification'/><author><name>Rob Wunderlich</name><uri>http://www.blogger.com/profile/13048694338956825695</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://3.bp.blogspot.com/_IhQc1-zXHmU/SwH7Z2D8lUI/AAAAAAAAADo/UY17XpuzKLw/S220/avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5070255803043802824.post-4337864289966854617</id><published>2009-04-22T17:53:00.000-07:00</published><updated>2010-12-07T22:32:31.078-08:00</updated><title type='text'>Analyzing Field Usage in a QVW</title><content type='html'>W&lt;span style="font-family: arial;"&gt;ouldn't it be nice to know what fields are "unreferenced" in your document? By unreferenced, I mean fields that are not used in Expressions, Dimensions or Keys. These are fields that if removed from your document, would have no impact on the visible elements of the application. &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: Arial;"&gt;Removing unused fields is sometimes important in addressing performance issues and generally makes your application easier to maintain and understand. &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: Arial;"&gt;The Expression Overview dialog is great for finding where a field is used, but what about the unused fields? I don't know of any QV supplied tool that can identify unused fields, so I created one myself. &lt;/span&gt;&lt;span style="font-family: Arial;"&gt;My tool is a QVW named "DocumentAnalyzer" and it's available for download from:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://robwunderlich.com/Download.html"&gt;http://robwunderlich.com/Download.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: arial;"&gt;First off, let me make it clear that this tool is imperfect. It's difficult to do a precise field usage analysis from "outside" of the product. I hope that this work of mine will encourage (goad?) Qliktech into writing a field usage analysis tool within the QV product. I'll be happy if my work becomes obsolete&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: arial;"&gt;I'll explain the usage and limitations of DocumentAnalyzer as well identify some interesting code tidbits for anyone who may want to enhance or borrow from this app. &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial;"&gt;The app code itself consists of two pieces. 1) A Macro Module that extracts meta information from the document to be analyzed (the "target" document) 2) A load script that processes the extracted meta data.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: arial;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;The Macro does a lot of filesystem access and requires System Access module security. If you have not allowed System Access, the macro will warn you and provide instructions for setting it.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: arial;"&gt;Using DocumentAnalyzer is a two step process, driven by buttons in the Main sheet. The first step is to choose a target document. Pressing the button will bring up a standard windows file chooser dialog. If a file chooser dialog cannot be created, the user is instructed to type a filename directly in the input box. &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: Arial;"&gt;Once a target document is selected, press the "Process Document" button. The Macro module will be invoked and extract the metatdata to a series of files in your temp directory. After extraction the load script will read the extracted files. At the end of the load script, the metadata files will be deleted.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_IhQc1-zXHmU/SfIwUo2j0yI/AAAAAAAAADA/mKILCDqIFUQ/s1600-h/AnalysisComplete.png"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5328374440254493474" src="http://2.bp.blogspot.com/_IhQc1-zXHmU/SfIwUo2j0yI/AAAAAAAAADA/mKILCDqIFUQ/s320/AnalysisComplete.png" style="cursor: hand; float: right; height: 107px; margin: 0px 0px 10px 10px; width: 164px;" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: Arial;"&gt;The tool will open the target document and navigate through the screens. Keep your hands off the keyboard while this process runs. When the load script is complete, you'll receive a msgbox like this. Press OK.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: Arial;"&gt;The first chart of interest can be found on the "Fields" sheet. The Field References chart lists each FieldName and indicates whether the FieldName was used as a Key, Dimension, In an Expression, Macro or Variable. FieldNames not referenced anywhere are highlighted in yellow. These are fields you might consider dropping from the document. &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_IhQc1-zXHmU/SfIue1j_DdI/AAAAAAAAAC4/gOhJP21i3cQ/s1600-h/FieldReferences.png"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5328372416441683410" src="http://3.bp.blogspot.com/_IhQc1-zXHmU/SfIue1j_DdI/AAAAAAAAAC4/gOhJP21i3cQ/s320/FieldReferences.png" style="cursor: hand; height: 103px; width: 320px;" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: Arial;"&gt;FieldNames that contain special characters are flagged in red. The usage of these fields cannot be accurately determined due to limitations of the parsing method I'm using.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: Arial;"&gt;The Exception sheet displays you may consider warnings about the data presented. Of particular interest is the "Unmatched Fields" listbox. Check out the Help in this listbox to understand it's contents. &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: arial;"&gt;&lt;strong&gt;The Parsing Algorithm&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: arial;"&gt;The identification of field rerefences is performed by the load script. The parsing is rather primitive so I'll provide some explanation here so you can understand it's limitations. You can also find this information on the "About" sheet of DocumentAnalyzer.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: Arial;"&gt;Field names are discovered in expressions by replacing "special" characters with a delimiter and then parsing into words using the subfield() function. For example, the expression:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;"Avg(Price * Quantity) * 1.05"&lt;/span&gt;is delimited to: &lt;/span&gt;&lt;span style="font-family: Arial;"&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;"Avg\Price \ Quantity\ \ 1.05"&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: Arial;"&gt;which is then parsed into four words -- &lt;span style="font-family: courier new;"&gt;Avg, Price, Qty, 1.05&lt;/span&gt; . The words are then matched against fieldnames. You will get a false match if a function name such as "Avg" is also used as a field name. &lt;span style="font-family: Arial;"&gt;If you just want use DocumentAnalyzer, no need to read further. If you want to learn something about the code, read on.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: arial;"&gt;&lt;strong&gt;The Code&lt;br /&gt;&lt;/strong&gt;&lt;/span&gt;&lt;span style="font-family: arial;"&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/span&gt;&lt;span style="font-family: Arial;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;The Macro writes the metadata to a series of files. The files are normally deleted at the end of the script. &lt;br /&gt;&lt;span style="font-family: Arial;"&gt;If you want to keep the metadata files, comment out this line in the script (on the Cleanup tab):&lt;/span&gt; &lt;br /&gt;&lt;span style="font-family: courier new;"&gt;LET x = DeleteFolder('$(f)'); // Delete the data files&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: arial;"&gt;The Macro Module is of a fair size -- about 500 lines. If you examine the code, you'll find some conditional code (&lt;span style="font-family: courier new;"&gt;IsInternal()&lt;/span&gt;) devoted to allowing the macro to run internally in a qvw or externally from cscript.exe. The entire macro module can be copied to an external file and run with cscript. I coded for "dual" execution environments because I get a better editor and debugger in the external environment. I do the development running externally and then paste the script into the QVW for final testing. &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Meta information (Field names, Dimensions, Expressions, etc) are extracted from the target document using the QV API. Getting Dimension values was fairly easy, they are only a few API paths for the various object types.&lt;br /&gt;&lt;br /&gt;Finding all the expressions was the most challenging part and took the most time to solve. There are many different properties where expressions may be used in sheet objects. They may also differ by release. I could not see discovering and writing all the API calls to extract every possible expression. I experimented with a number of approaches, including generating code from the API doc -- never got this to work correctly. The most promising approach was using the file export from the Expression Overview dialog. This gave me a complete list of expressions, but the exported file was not consistently usable. The export file is a tab delimited file. If an expression uses tabs or newlines it can make file impossible to navigate. &lt;br /&gt;My eventual solution was to export the objects into XML using the&lt;br /&gt;WriteXmlPropertiesFile outputFile API method and then extract the expressions from the XML files. I first tried to get the expressions using load script, but found this too cumbersome. I settled on using XPath to extract the data I needed from the XML files. XPath is a sort of "query language" for XML. Where SQL returns a set of rows, XPath returns a set of XML elements. This required only a few XPath expressions to cover all the possible expressions. &lt;br /&gt;Once I perfected the XPath method, I switched to doing the Dimension extraction this way as well. &lt;br /&gt;&lt;span style="font-family: arial;"&gt;In QV 8.5, Sheets do not have an XML representation. So Sheet expressions (background color, conditional show, etc) are extracted indivdually.&lt;/span&gt;&lt;br /&gt;The Document Variables. Macro Module and Script are written to files as well. The Script is not currently processed by the load.&lt;br /&gt;Contact me if you have any problems or questions on using the app. Contact information is on the "About" sheet. &lt;br /&gt;Happy analyzing!&lt;br /&gt;-Rob&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5070255803043802824-4337864289966854617?l=qlikviewnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qlikviewnotes.blogspot.com/feeds/4337864289966854617/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5070255803043802824&amp;postID=4337864289966854617' title='12 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/4337864289966854617'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/4337864289966854617'/><link rel='alternate' type='text/html' href='http://qlikviewnotes.blogspot.com/2009/04/analyzing-field-usage-in-qvw.html' title='Analyzing Field Usage in a QVW'/><author><name>Rob Wunderlich</name><uri>http://www.blogger.com/profile/13048694338956825695</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://3.bp.blogspot.com/_IhQc1-zXHmU/SwH7Z2D8lUI/AAAAAAAAADo/UY17XpuzKLw/S220/avatar.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_IhQc1-zXHmU/SfIwUo2j0yI/AAAAAAAAADA/mKILCDqIFUQ/s72-c/AnalysisComplete.png' height='72' width='72'/><thr:total>12</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5070255803043802824.post-7150672679967578135</id><published>2009-04-22T17:23:00.000-07:00</published><updated>2009-04-22T17:48:36.458-07:00</updated><title type='text'>BOQC: ApplyMap instead of Join</title><content type='html'>Today marks my first blogging of "Best Of QlikCommunity" (BOQC) where I plan to highlight what I find to be particularly useful or interesting posts on the QlikCommunity Forums.&lt;br /&gt;&lt;br /&gt;There are cases when the ApplyMap() function is a very useful alternative to Join. For some time I have noticed both Oleg Troyansky and Michael Nordstrom dropping this hint on QlikCommunity but I never quite understood the power of the technique until a post Oleg made today:&lt;br /&gt;&lt;a href="http://community.qlikview.com/forums/p/16017/62222.aspx#62222"&gt;http://community.qlikview.com/forums/p/16017/62222.aspx#62222&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The original forum question was how to multiply two fields from different tables to derive a new calculated field. The tables share a common key field.&lt;br /&gt;&lt;br /&gt;I usually would have approached this with two Joins. That approach works, but sometimes I don't really want my data model to reflect Joined tables. I just want to do the calculation.&lt;br /&gt;&lt;br /&gt;If you want to see the ApplyMap() solution, read the post linked to above. The thread explains it better than me repeating it here.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5070255803043802824-7150672679967578135?l=qlikviewnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qlikviewnotes.blogspot.com/feeds/7150672679967578135/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5070255803043802824&amp;postID=7150672679967578135' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/7150672679967578135'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/7150672679967578135'/><link rel='alternate' type='text/html' href='http://qlikviewnotes.blogspot.com/2009/04/boqc-applymap-instead-of-join.html' title='BOQC: ApplyMap instead of Join'/><author><name>Rob Wunderlich</name><uri>http://www.blogger.com/profile/13048694338956825695</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://3.bp.blogspot.com/_IhQc1-zXHmU/SwH7Z2D8lUI/AAAAAAAAADo/UY17XpuzKLw/S220/avatar.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5070255803043802824.post-6788490529964547121</id><published>2009-04-20T20:35:00.000-07:00</published><updated>2009-04-22T10:35:50.356-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tufte'/><category scheme='http://www.blogger.com/atom/ns#' term='qlikview'/><category scheme='http://www.blogger.com/atom/ns#' term='Few'/><title type='text'>Effective Visual Communication</title><content type='html'>&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;span style="font-family:arial;"&gt;Now you own a brand new power saw (Qlikview). But do you know how to build a house?&lt;/span&gt; &lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;span style="font-family:arial;"&gt;A key feature of Qlikview is graphical representation of data. Do you have the skills to use that capability effectively? The challenges of effective visual communication are not unique to Qlikview. The principles of visual communication can be learned and there are many resources available to learn from. &lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;div&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;div&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;An important and useful work to me has been the book "The Visual Display of Quantitative Information" by Edward R. Tutfe (ISBN-0961392142). In this book, Tufte defines and articulates many important principles of statistical graphical representation, including the "Lie Factor" "Chartjunk", and the "Data-Ink ratio". The principles of Chartjunk and the Data-Ink ratio ask us to consider which of t&lt;/span&gt;&lt;span style="font-family:Arial;"&gt;hese two charts communicate more effectively.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;a href="http://1.bp.blogspot.com/_IhQc1-zXHmU/Se1Mqa9ErFI/AAAAAAAAACg/u3_T-_FJ_k8/s1600-h/MinimalChart.png"&gt;&lt;img id="BLOGGER_PHOTO_ID_5326998225922862162" style="WIDTH: 196px; CURSOR: hand; HEIGHT: 177px" alt="" src="http://1.bp.blogspot.com/_IhQc1-zXHmU/Se1Mqa9ErFI/AAAAAAAAACg/u3_T-_FJ_k8/s320/MinimalChart.png" border="0" /&gt;&lt;/a&gt;&lt;a href="http://2.bp.blogspot.com/_IhQc1-zXHmU/Se1HrPByCnI/AAAAAAAAACI/_scHRqaQ79c/s1600-h/JunkChart.png"&gt;&lt;img id="BLOGGER_PHOTO_ID_5326992742343117426" style="WIDTH: 242px; CURSOR: hand; HEIGHT: 177px" alt="" src="http://2.bp.blogspot.com/_IhQc1-zXHmU/Se1HrPByCnI/AAAAAAAAACI/_scHRqaQ79c/s320/JunkChart.png" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Tufte has authored several more books that expand and illuminate these themes of quality and effectiveness in graphical communication. All of the books are beautifully printed. Tufte also teaches seminars and maintains a web site at: &lt;a href="http://www.edwardtufte.com/tufte/"&gt;http://www.edwardtufte.com/tufte/&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;p&gt;&lt;/p&gt;Another work I have found very useful is "Information Dashboard Design" by Stephen Few (ISBN-0596100167). This book applies visual communication principles from Few, Tufte and other researchers to the practical application of "dashboard design" . Few's book analyzes the shortcomings of some poor designs and then goes on to enumerate a number of elements for effective designs. He closes the book with some examples of optimal designs.&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;p&gt;&lt;/p&gt;Stephen Few also teaches public workshops. His schedule and blog can be found at &lt;a href="http://www.perceptualedge.com/"&gt;http://www.perceptualedge.com/&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;p&gt;&lt;/p&gt;Lastly, the IBM Many Eyes project &lt;a href="http://manyeyes.alphaworks.ibm.com/"&gt;http://manyeyes.alphaworks.ibm.com/&lt;/a&gt; is an ongoing source of inspiration and amusement. &lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;-Rob&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;/div&gt;&lt;a href="http://4.bp.blogspot.com/_IhQc1-zXHmU/Se1HPpzK90I/AAAAAAAAACA/x_THyiHcjgM/s1600-h/JunkChart.png"&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5070255803043802824-6788490529964547121?l=qlikviewnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qlikviewnotes.blogspot.com/feeds/6788490529964547121/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5070255803043802824&amp;postID=6788490529964547121' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/6788490529964547121'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/6788490529964547121'/><link rel='alternate' type='text/html' href='http://qlikviewnotes.blogspot.com/2009/04/effective-visual-communication.html' title='Effective Visual Communication'/><author><name>Rob Wunderlich</name><uri>http://www.blogger.com/profile/13048694338956825695</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://3.bp.blogspot.com/_IhQc1-zXHmU/SwH7Z2D8lUI/AAAAAAAAADo/UY17XpuzKLw/S220/avatar.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_IhQc1-zXHmU/Se1Mqa9ErFI/AAAAAAAAACg/u3_T-_FJ_k8/s72-c/MinimalChart.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5070255803043802824.post-6836295566931994621</id><published>2009-01-09T00:45:00.000-08:00</published><updated>2009-01-09T08:34:48.862-08:00</updated><title type='text'>Using MapSubstring() to edit strings</title><content type='html'>&lt;span style="font-family:arial;"&gt;The &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;MapSubstring&lt;/span&gt;() function is a powerful alternative to using nested Replace() or &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;PurgeChar&lt;/span&gt;() functions.&lt;br /&gt;&lt;br /&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;MapSubstring&lt;/span&gt;(), unlike it's siblings &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;ApplyMap&lt;/span&gt;() and Map, will apply multiple mappings from the mapping table. Here's an example.&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;ReplaceMap&lt;/span&gt;:&lt;br /&gt;MAPPING LOAD * &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;INLINE&lt;/span&gt; [ &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;char replace&lt;br /&gt;) \&lt;br /&gt;) \&lt;br /&gt;" \&lt;br /&gt;, \&lt;br /&gt;/ \&lt;br /&gt;- \&lt;br /&gt;] (delimiter is ' ')&lt;br /&gt;; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;TestData&lt;/span&gt;:&lt;br /&gt;LOAD&lt;br /&gt;*,&lt;br /&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;MapSubString&lt;/span&gt;('&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;ReplaceMap&lt;/span&gt;', data) as &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;ReplacedString&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;;&lt;br /&gt;LOAD * &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;INLINE&lt;/span&gt; [&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;(415)555-1234&lt;br /&gt;(415)543,4321&lt;br /&gt;"510"123-4567&lt;br /&gt;/925/999/4567&lt;br /&gt;] (delimiter is ' ')&lt;br /&gt;; &lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;In field "&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;ReplacedString&lt;/span&gt;", all the characters matching the first field of the map ("char") are replaced with a backslash as shown in this table. This makes it ready for parsing with a function like SubField().&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_IhQc1-zXHmU/SWcdhW4kzLI/AAAAAAAAABo/lcX47TGVpTo/s1600-h/replacedString.png"&gt;&lt;img id="BLOGGER_PHOTO_ID_5289228746285698226" style="WIDTH: 189px; CURSOR: hand; HEIGHT: 75px" alt="" src="http://3.bp.blogspot.com/_IhQc1-zXHmU/SWcdhW4kzLI/AAAAAAAAABo/lcX47TGVpTo/s320/replacedString.png" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Another usage is an alternative to nested &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_13"&gt;PurgeChar&lt;/span&gt;() to remove multiple characters. A blank is used as the mapping character. For example:&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_14"&gt;PurgeMap&lt;/span&gt;:&lt;br /&gt;MAPPING LOAD * &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_15"&gt;INLINE&lt;/span&gt; [ &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;char replace&lt;br /&gt;)&lt;br /&gt;)&lt;br /&gt;"&lt;br /&gt;,&lt;br /&gt;/&lt;br /&gt;-&lt;br /&gt;] (delimiter is ' ')&lt;br /&gt;; &lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;MapSubString('PurgeMap', Data) &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:arial;"&gt;will produce results like this:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_IhQc1-zXHmU/SWcf92_t55I/AAAAAAAAABw/IG2v0Iy2tyQ/s1600-h/PurgedString.png"&gt;&lt;img id="BLOGGER_PHOTO_ID_5289231434965182354" style="WIDTH: 181px; CURSOR: hand; HEIGHT: 75px" alt="" src="http://2.bp.blogspot.com/_IhQc1-zXHmU/SWcf92_t55I/AAAAAAAAABw/IG2v0Iy2tyQ/s320/PurgedString.png" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:times new roman;"&gt;-Rob&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5070255803043802824-6836295566931994621?l=qlikviewnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qlikviewnotes.blogspot.com/feeds/6836295566931994621/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5070255803043802824&amp;postID=6836295566931994621' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/6836295566931994621'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/6836295566931994621'/><link rel='alternate' type='text/html' href='http://qlikviewnotes.blogspot.com/2009/01/using-mapsubstring-to-edit-strings.html' title='Using MapSubstring() to edit strings'/><author><name>Rob Wunderlich</name><uri>http://www.blogger.com/profile/13048694338956825695</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://3.bp.blogspot.com/_IhQc1-zXHmU/SwH7Z2D8lUI/AAAAAAAAADo/UY17XpuzKLw/S220/avatar.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_IhQc1-zXHmU/SWcdhW4kzLI/AAAAAAAAABo/lcX47TGVpTo/s72-c/replacedString.png' height='72' width='72'/><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5070255803043802824.post-8889603191711689721</id><published>2009-01-05T11:32:00.000-08:00</published><updated>2009-01-09T08:44:11.676-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='qlikview'/><category scheme='http://www.blogger.com/atom/ns#' term='layout'/><category scheme='http://www.blogger.com/atom/ns#' term='group'/><title type='text'>The design of grouped objects</title><content type='html'>&lt;span style="font-family:arial;"&gt;I recently submitted a feature request to Qliktech requesting "grouped objects". There are a number of issues to consider when thinking about how grouped objects should be implemented in QV.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;You are probably familiar with the idea of grouped objects. It's a feature commonly available in graphics authoring programs Select a set of objects and mark them as "grouped". Operations such as Move or Resize then apply to the group.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-family:Arial;"&gt;The problems I'm trying to address by asking for grouped objects:&lt;/span&gt; &lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;When two or more objects are logically related, it's would be useful if they could be minimized or restored together. &lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;It's a common practice to layer objects upon one another to produce an effect that is not available with a single object. For example, Stephen Few's &lt;a href="http://www.perceptualedge.com/blog/?p=217"&gt;Bullet Graph &lt;/a&gt;is commonly implemented in QV as a chart upon a chart. The Qliktech demo "Finance Controlling" uses this technique. Another common use case is placing a transparent text box on a chart to provide helptext, or a button to provide action.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Arial;"&gt;Currently, if you layer objects, you also have to prohibit the user from moving or resizing the objects. If not, user move or resize operations may cause the objects to be misaligned.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;span style="font-family:Arial;"&gt;If QV would let me select a set of objects and mark them as a "group", how should the group of objects respond to various user actions?&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:arial;"&gt;Let's first consider a group of two objects that are related, but do not overlap on the screen. For example, a straight table and text box. The text box contains some summary data from the table. Here's are some possible behaviors:&lt;/span&gt; &lt;/p&gt;&lt;ol&gt;&lt;li&gt;If the user moved any object, all objects would move as a group, maintaining relative position to one another.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;If the user resizes one object, all objects will resize proportionally and maintain position relative one another.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;If the user maximizes one object, the group will enlarge proportionally to fill the screen.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;span style="font-family:arial;"&gt;Let's consider another case. Two overlayed bar charts are used to create a Bullet Graph. One chart also contains a button in the caption area. It's critical that the overlayed charts maintain position and size relative to one another. The button is a fixed artifact that should not resize but must remain in the "correct" position. How should the behavior differ from the example above?&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:arial;"&gt;If one of the charts is resized or maximized, both charts must resize. The button should not resize. This could be controlled by use of the "allow move/resize" property of each object. If the property is checked, the object will participate in a group resize. If unchecked, the object will not resize with the group. However, all objects will maintain relative position.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Arial;"&gt;What specifically, is "relative position"? I define it as the "x,y pixel distance from the nearest corner of a parent object. The parent is the object in the same group who's corner is closest to the child object". An object can only be relative to one parent object. The parent may change after a resize operation.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Arial;"&gt;It would simplify the grouping process if the "Allow Move/Size" property were split into two separate properties -- "Allow Move" and "Allow Size". In the chart &amp;amp; button example, all objects would "Allow Move" but only the charts would "Allow Size".&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Arial;"&gt;Your comments and improvements on this proposal are welcome. &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Arial;"&gt;-Rob&lt;/span&gt;&lt;/p&gt;&lt;span style="font-family:arial;"&gt;&lt;em&gt;Update 01/09/2009&lt;/em&gt;: What about Object "Print" and "Copy To Clipboard -&gt; Image" functions? My proposal would be to include all objects that share a pixel with the right-clicked object. &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5070255803043802824-8889603191711689721?l=qlikviewnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qlikviewnotes.blogspot.com/feeds/8889603191711689721/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5070255803043802824&amp;postID=8889603191711689721' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/8889603191711689721'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/8889603191711689721'/><link rel='alternate' type='text/html' href='http://qlikviewnotes.blogspot.com/2008/12/design-of-grouped-objects.html' title='The design of grouped objects'/><author><name>Rob Wunderlich</name><uri>http://www.blogger.com/profile/13048694338956825695</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://3.bp.blogspot.com/_IhQc1-zXHmU/SwH7Z2D8lUI/AAAAAAAAADo/UY17XpuzKLw/S220/avatar.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5070255803043802824.post-7741231046187367624</id><published>2008-12-11T10:29:00.000-08:00</published><updated>2008-12-12T22:28:18.342-08:00</updated><title type='text'>Extracting data using Microsoft Logparser</title><content type='html'>&lt;span style="font-family:arial;"&gt;I've fielded several questions lately about loading Group membership information from Active Directory. The Active Directory sample in the Qlikview Cookbook uses AdsDSO and can load "single-valued" fields such as Name and Mail. AdsDSO will not load "multi-valued" fields such as "memberOf" or "member" -- fields that define group members.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;p&gt;&lt;span style="font-family:arial;"&gt;To read multi-valued fields, you'll have to install some sort of tool to extract the data into a format QV can load. There are a number of free and commercial utilities available that will extract AD information into a text file. &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:arial;"&gt;My favorite tool for AD extracts is the free &lt;strong&gt;Microsoft Logparser&lt;/strong&gt;. Google for it, you'll find lots of information as well as the download link. There is also a Logparser book and forum available.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:arial;"&gt;Logparser can read data from many different inputs -- Active Directory, IIS logs, Windows Event logs, Registry -- to name a few. &lt;/span&gt;&lt;span style="font-family:arial;"&gt;Logparser can write to several different output formats, CSV being the most useful for QV. &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:arial;"&gt;Logparser uses a SQL syntax for it's queries. Here's an example:&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:courier new;"&gt;logparser -objClass:Group "select cn, member into tmp\AdGroups.csv from LDAP://mydomainController"&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:arial;"&gt;This Logparser query will create the output file "tmp\AdGroups.csv". The file will contain one row for each group (cn). The members of the group will be returned as a single field with the members separated by the pipe "|" character. The members are easily separated in the QV load using the QV subfield() function:&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:courier new;"&gt;subfield(member, '|') as member&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:arial;"&gt;Other uses I've found for using Logparser with Qlikview:&lt;/span&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-family:arial;"&gt;Extracting data from Windows Event logs.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:arial;"&gt;Preprocessing IIS log files. The fields contained in a IIS log can vary between sites and may also change dynamically within the same physical file. Logparser can neutralize these differerences and produce a common input for QV load.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-family:arial;"&gt;&lt;p&gt;Logparser is a favorite tool of mine. I use it frequently for non-Qlikview tasks as well. &lt;/p&gt;&lt;p&gt;-Rob &lt;/p&gt;&lt;p&gt;&lt;em&gt;Update 12/12/2008&lt;/em&gt; I've published a complete example of using logParser to extract Group and User data from AD for loading into QV. The example is in version 9 of the Qlikview Cookbook available at &lt;a href="http://robwunderlich.com/Download.html"&gt;http://robwunderlich.com/Download.html&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;/span&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5070255803043802824-7741231046187367624?l=qlikviewnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qlikviewnotes.blogspot.com/feeds/7741231046187367624/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5070255803043802824&amp;postID=7741231046187367624' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/7741231046187367624'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/7741231046187367624'/><link rel='alternate' type='text/html' href='http://qlikviewnotes.blogspot.com/2008/12/extracting-data-using-microsoft.html' title='Extracting data using Microsoft Logparser'/><author><name>Rob Wunderlich</name><uri>http://www.blogger.com/profile/13048694338956825695</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://3.bp.blogspot.com/_IhQc1-zXHmU/SwH7Z2D8lUI/AAAAAAAAADo/UY17XpuzKLw/S220/avatar.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5070255803043802824.post-5541385346023629819</id><published>2008-11-19T16:43:00.000-08:00</published><updated>2008-12-16T19:29:59.375-08:00</updated><title type='text'>Using the Evaluate API in Macros</title><content type='html'>&lt;span style="font-family:arial;"&gt;A common application of QV macros is to make initial selections. These selections may be applied when the document is opened, a sheet is activated or a button is pressed. The selections usually involve some type of dynamic value, such as "today()".&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;em&gt;In the examples below, the VBS continuation  character "_" is used to indicate the statement continues on the next line. You may type the statement on a single line if wish and omit the "_".&lt;/em&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;A typical macro to select yesterday's date looks like this:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;ActiveDocument.GetField("ShipDate").Select _&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Date()-1&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;It's all VBScript, but the functions used come from two different products. The ActiveDocument...Select is from the QV API, and the Date() function is a VBScript function. To make this work, you need some knowledge of VBS functions. In addition, there may also be a type mismatch -- the VBS function returns a number and the Select expects a string. Fixing that issue requires adding a CStr() or CDbl() function. &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;What if you want to make a more complex selection. Like the weekday for today? Or a selection that requires knowledge of the data values -- max(ShipDate)?&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;Wouldn't it be easier if you could use QV Expressions to define the selection expression? You can, with the &lt;span style="font-family:courier new;"&gt;ActiveDocument.Evaluate&lt;/span&gt; API function. Here are some examples.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;ActiveDocument.GetField("ShipDate").Select _&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;ActiveDocument.Evaluate("date(today(1)-1)")&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;ActiveDocument.GetField("Weekday").Select _&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;ActiveDocument.Evaluate("weekday(today(1))")&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;br /&gt;ActiveDocument.GetField("ShipDate").Select _&lt;br /&gt;ActiveDocument.Evaluate("max(ShipDate)") &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:arial;"&gt;The Evaluate argument is any expression that can be evaluated by QV. So you can stick with the QV functions you are used to. Those functions are also more likely to produce the correct data type for your selection. And most importantly, you get easy access to the QV data -- (&lt;span style="font-family:courier new;"&gt;"max(ShipDate)"&lt;/span&gt;).&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;You can even use QV search operators such as "&gt;". For example, to select the last 7 days:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;ActiveDocument.GetField("ShipDate").Select _&lt;br /&gt;ActiveDocument.Evaluate("'&gt;' &amp;amp;  date(today(1)-7)")&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;I hope you find this tip useful.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;-Rob&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5070255803043802824-5541385346023629819?l=qlikviewnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qlikviewnotes.blogspot.com/feeds/5541385346023629819/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5070255803043802824&amp;postID=5541385346023629819' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/5541385346023629819'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/5541385346023629819'/><link rel='alternate' type='text/html' href='http://qlikviewnotes.blogspot.com/2008/11/using-evaluate-api-in-macros.html' title='Using the Evaluate API in Macros'/><author><name>Rob Wunderlich</name><uri>http://www.blogger.com/profile/13048694338956825695</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://3.bp.blogspot.com/_IhQc1-zXHmU/SwH7Z2D8lUI/AAAAAAAAADo/UY17XpuzKLw/S220/avatar.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5070255803043802824.post-711298244277361211</id><published>2008-11-04T17:46:00.000-08:00</published><updated>2008-11-05T08:03:05.905-08:00</updated><title type='text'>Qliktech Communication</title><content type='html'>&lt;span style="font-family:arial;"&gt;I'm receiving new communications from &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;Qliktech&lt;/span&gt;, and I like it. &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;Jason Long, webmaster of the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;QlikCommunity&lt;/span&gt; site, has engaged community members in a dialog soliciting suggestions for improvements to the Forum. Jason has already implemented a number of requests as well as the very cool Google forum search engine.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;I'm now receiving a monthly email from John &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;Trigg&lt;/span&gt;, &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;Qlikview&lt;/span&gt; Developer Product Manager. The email acknowledges the product enhancement requests I submitted in the prior month. I assume other customers who have submitted &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_4"&gt;enhancement&lt;/span&gt; requests are receiving an email as well. This a vast improvement to the old "black box" submission process where I was left wondering if anyone ever read my request. Thanks John!&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;-Rob&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5070255803043802824-711298244277361211?l=qlikviewnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qlikviewnotes.blogspot.com/feeds/711298244277361211/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5070255803043802824&amp;postID=711298244277361211' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/711298244277361211'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/711298244277361211'/><link rel='alternate' type='text/html' href='http://qlikviewnotes.blogspot.com/2008/11/qliktech-communication.html' title='Qliktech Communication'/><author><name>Rob Wunderlich</name><uri>http://www.blogger.com/profile/13048694338956825695</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://3.bp.blogspot.com/_IhQc1-zXHmU/SwH7Z2D8lUI/AAAAAAAAADo/UY17XpuzKLw/S220/avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5070255803043802824.post-4265733200581253813</id><published>2008-10-25T12:58:00.000-07:00</published><updated>2008-10-27T11:49:24.735-07:00</updated><title type='text'>The match() Function</title><content type='html'>&lt;span style="font-family:arial;"&gt;In SQL, the "in" operator is commonly used to test if a value exists in a list of values. For example:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;SELECT * FROM TABLE WHERE CODE IN ('a', 'b', 'f');&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;New QV developers often spend some time looking for QV's equivalent of the "in" operator. It's the match() function. &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;LOAD * WHERE match(CODE, 'a', 'b', 'f');&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;The match() function, and its siblings "mixmatch" and "wildmatch". are documented in the "Conditional Functions" section of the Ref guide and the help:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;match( s, expr1 [ , expr2, ...exprN ] )&lt;br /&gt;&lt;/strong&gt;Compares the string s to a list of strings or string expressions. The result of the comparison is an integer indicating which of the comparison strings/expressions matched. If no match is found, 0 is returned. The match function performs a case sensitive comparison.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;mixmatch()&lt;/strong&gt; works just like match() except it does a case insensitive comparision.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;wildmatch()&lt;/strong&gt; is another form that can be particularly useful. wildmatch() allows (but does not require) the "?' and "*" wildcard characters in the match arguments.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-family:courier new;"&gt;wildMatch(text, '*error*')&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;will match:&lt;br /&gt;&lt;br /&gt;"An error has occurred"&lt;br /&gt;"Error processing account nnnn"&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;QV 8.5 provides a "like" operator that allows for testing against a single value with wildcards:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;strong&gt;text like '*error*'&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;Wildmatch can test against multiple values:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;strong&gt;wildMatch(text, '*error*', '*warning*')&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;The match() functions return a number indicating which of the comparison strings was found. You can use this index number nested in a pick function to do "wildcard mapping" as an alternative to a nested if() function.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;strong&gt;pick(&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;strong&gt;wildmatch(PartNo, &lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;strong&gt;'*99', 'P1586', '?15*', '?17*', '*'&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;strong&gt;),&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;strong&gt;'Taxes', 'Premium Fuel', 'Fuel', 'Lubricant', 'Other')&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;-Rob&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5070255803043802824-4265733200581253813?l=qlikviewnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qlikviewnotes.blogspot.com/feeds/4265733200581253813/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5070255803043802824&amp;postID=4265733200581253813' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/4265733200581253813'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/4265733200581253813'/><link rel='alternate' type='text/html' href='http://qlikviewnotes.blogspot.com/2008/10/match-function.html' title='The match() Function'/><author><name>Rob Wunderlich</name><uri>http://www.blogger.com/profile/13048694338956825695</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://3.bp.blogspot.com/_IhQc1-zXHmU/SwH7Z2D8lUI/AAAAAAAAADo/UY17XpuzKLw/S220/avatar.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5070255803043802824.post-5392674689042436659</id><published>2008-10-20T20:08:00.000-07:00</published><updated>2008-10-21T10:40:31.385-07:00</updated><title type='text'>An Example is Worth a Thousand Thread Replies</title><content type='html'>&lt;span style="font-family:arial;"&gt;There's a lot of information being exchanged on the QlikCommunity Forum &lt;/span&gt;&lt;a href="http://www.qlikcommunity.com/"&gt;&lt;span style="font-family:arial;"&gt;http://www.QlikCommunity.com&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:arial;"&gt; these days.&lt;/span&gt;&lt;span style="font-family:arial;"&gt; Customers and Consultants ask technical questions, and other Customers, Consultants and QT employees provide very useful answers. Today's post is a tip on how to improve the chances of your Forum question being answered quickly and accurately. &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Many back and forth replies to a forum thread are about clarifying the question. &lt;strong&gt;If possible, post a qvw file example with your question.&lt;/strong&gt; (I can't, my file is too big! The data is private! Keep reading for ways to handle these concerns).&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Reasons to post an example qvw:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-family:arial;"&gt;An example will help clarify your question. The Forum is conducted in English, but English is a second language for many, if not most, of the Forum users. An example will provide additional understanding of your question.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:arial;"&gt;More likely to get an accurate and complete response. Many questions require the responders to fiddle with expression or script syntax. If I have a qvw to work with, I'm more likely to test my answer before posting it, saving you the trouble of learning that I forgot a comma in my recommended solution.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:arial;"&gt;Time. Most Forum members answer questions on a volunteer basis and their time is limited. For myself, I can only take the time to answer a limited number of questions. I'm more likely to pick the questions that are clear and provide the data I need. If I have to code up my own test data to work on the problem, I'm less likely to respond.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:arial;"&gt;Some of the reasons you may be reluctant to post your qvw -- size and privacy. &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:arial;"&gt;The maximum attachment size allowed on the Forum is 1MB. You can make the example qvw smaller by using the QV Data Reduction feature. &lt;/span&gt;&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="font-family:arial;"&gt;Make some selections to reduce the number of selected values in the qvw. &lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:arial;"&gt;From the menu bar, select File-&gt;Reduce Data -&gt;Keep Possible Values.&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:arial;"&gt;Use File-&gt;Save As to save the reduced copy under a new name.&lt;br /&gt;&lt;br /&gt;If you use "Save", QV will still open the "Save As" to help you remember not to overwrite the master copy.&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;span style="font-family:arial;"&gt;You can protect the privacy of sensitive information, such as account numbers, revenue or customer names by using the QV Scrambling feature. &lt;/span&gt;&lt;span style="font-family:arial;"&gt;In the menu bar, select Settings-&gt;Document Properties-&gt;Scrambling. &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:arial;"&gt;Here you can select a field to scramble and press the "Scramble" button to perform a random scrambling of the field . No one can determine it's original contents. Like values will scramble to the same value which maintains the value linkages.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Arial;"&gt;In some cases, you may still be unable to post your &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;qvw&lt;/span&gt; even with reduction and scrambling. Or it may make your example more clear to post the data &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;inline&lt;/span&gt; with your question. In that case, post your example data in the question using comma delimited format, so it can easily be pasted to a LOAD &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;INLINE&lt;/span&gt;. For example:&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:courier new;"&gt;Accounts:&lt;br /&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;AccountNo&lt;/span&gt;, Name&lt;br /&gt;1234, ABC Corp&lt;br /&gt;4567, DEF Co&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:courier new;"&gt;Transactions:&lt;br /&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;AccountNo&lt;/span&gt;, &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;TranId&lt;/span&gt;, Amount&lt;br /&gt;4567, 1, 2000&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Arial;"&gt;One last tip. Before you post, remember to search for existing answers to your question. In the past, search on the Forum was not so robust. But QT has recently added an embedded Google search feature. This is great! It supports the full range of Google search operators. Try it. The "Google Custom Search" link is available at the top of each Forum page.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Arial;"&gt;Finally, don't forget to mark your question as "solved" when you've received a satisfactory answer.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Arial;"&gt;Happy posting!&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Arial;"&gt;-Rob&lt;/span&gt;&lt;/p&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5070255803043802824-5392674689042436659?l=qlikviewnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qlikviewnotes.blogspot.com/feeds/5392674689042436659/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5070255803043802824&amp;postID=5392674689042436659' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/5392674689042436659'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/5392674689042436659'/><link rel='alternate' type='text/html' href='http://qlikviewnotes.blogspot.com/2008/10/example-is-worth-thousand-thread.html' title='An Example is Worth a Thousand Thread Replies'/><author><name>Rob Wunderlich</name><uri>http://www.blogger.com/profile/13048694338956825695</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://3.bp.blogspot.com/_IhQc1-zXHmU/SwH7Z2D8lUI/AAAAAAAAADo/UY17XpuzKLw/S220/avatar.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5070255803043802824.post-1386573387361952322</id><published>2008-10-09T17:21:00.000-07:00</published><updated>2008-10-10T15:07:57.177-07:00</updated><title type='text'>Reducing the Need for Macros</title><content type='html'>&lt;p&gt;&lt;span style="font-family:arial;"&gt;Many QV Developers create macros to extend the functionality of a QV document. Using macros brings up a number of concerns, including performance, stability and maintainability. It's better to achieve the functionality using the core product wherever possible. &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:arial;"&gt;But...you can't always get the results you need using the core product features. Here's my wishlist of enhancements to the core product that would reduce the amount of necessary macro coding.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:arial;"&gt;&lt;strong&gt;1&lt;/strong&gt;. &lt;strong&gt;Sheet Object "OnDocumentOpen" expression&lt;/strong&gt;. This would allow an expression to establish a default selection in an object when the document is opened. For example, a calendar or listbox might use the expression "today()" to open to the current date. I see a lot of macros and questions on the QlikCommunity Forum doing this exercise.&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Arial;"&gt;There are some design considerations, such as what order these "selections" will be applied. I'm sure these details can be worked out. &lt;/span&gt;&lt;/p&gt;&lt;span style="font-family:arial;"&gt;&lt;strong&gt;2.&lt;/strong&gt; &lt;strong&gt;"Enable Expression" expression&lt;/strong&gt;. It's a somewhat common requirement to dynamically modify which columns are shown in a chart, based on selections and conditions. I've seen various approaches employed to meet this requirement. One method is to define all the expression columns in the GUI and use the macro API to toggle the Enable property of each expression. This works, but it's hard to code correctly and customers are developing the same code over and over again.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;The Expression "Enable" property in the GUI is currently defined by an on/off checkbox. If an expression was allowed the condition could be expressed there and a lot of macro code would be eliminated.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;If you've got suggestions for reducing macros, please leave a comment here or on the QlikCommunity Forum.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;-Rob&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5070255803043802824-1386573387361952322?l=qlikviewnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qlikviewnotes.blogspot.com/feeds/1386573387361952322/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5070255803043802824&amp;postID=1386573387361952322' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/1386573387361952322'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/1386573387361952322'/><link rel='alternate' type='text/html' href='http://qlikviewnotes.blogspot.com/2008/10/reducing-need-for-macros.html' title='Reducing the Need for Macros'/><author><name>Rob Wunderlich</name><uri>http://www.blogger.com/profile/13048694338956825695</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://3.bp.blogspot.com/_IhQc1-zXHmU/SwH7Z2D8lUI/AAAAAAAAADo/UY17XpuzKLw/S220/avatar.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5070255803043802824.post-2051518200417618224</id><published>2008-09-29T11:50:00.000-07:00</published><updated>2008-09-30T08:19:34.718-07:00</updated><title type='text'>Loading Multiple Excel Sheets</title><content type='html'>&lt;span style="font-family:arial;"&gt;Load from Excel is usually pretty straightforward, but sometimes you'll need to load multiple sheets and make some determinations at &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;runtime&lt;/span&gt;. Details such as &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;sheetnames&lt;/span&gt; may not be known at script creation time. &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;The &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;QV&lt;/span&gt; statements "&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;SQLTables&lt;/span&gt;" and "&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;SQLColumns&lt;/span&gt;" may be used to discover information about the sheets and columns available in a workbook. Both of these statements require an &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;ODBC&lt;/span&gt; connection. The &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;ODBC&lt;/span&gt; connection may also be used to subsequently read the data, but I find using the LOAD biff more &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_7"&gt;convenient&lt;/span&gt;.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;First make a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;OLEDB&lt;/span&gt; connection to the workbook:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;CONNECT TO [Provider=Microsoft.Jet.OLEDB.4.0;Data Source=workbook.&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;xls&lt;/span&gt;;Extended Properties="Excel 8.0;"];&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Specify the workbook name, relative to the current directory, in the "Data Source=" parameter. This example uses a "&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;DSN&lt;/span&gt;-less" connection. It does not require you to predefine an &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;ODBC&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_12"&gt;datasource&lt;/span&gt;.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;The &lt;span style="font-family:courier new;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_13"&gt;SQLTables&lt;/span&gt; &lt;/span&gt;statement return a set of fields describing the tables in the currently connected &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_14"&gt;ODBC&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_15"&gt;datasource&lt;/span&gt;, in this case the workbook. A "Table" is an Excel Sheet.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;tables: &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_16"&gt;SQLtables&lt;/span&gt;; &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Now I've got a list of sheets in the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_17"&gt;QV&lt;/span&gt; "tables" table. The field name that contains the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_18"&gt;sheetname&lt;/span&gt; is "TABLE_NAME". I'll loop through the set of TABLE_NAME values and load each one using a standard biff LOAD.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;FOR i = 0 to &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_19"&gt;NoOfRows&lt;/span&gt;('tables')-1&lt;br /&gt;LET &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_20"&gt;sheetName&lt;/span&gt; = &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_21"&gt;purgeChar&lt;/span&gt;(peek('TABLE_NAME', i, 'tables'), &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_22"&gt;chr&lt;/span&gt;(39));&lt;br /&gt;Sales:&lt;br /&gt;LOAD *&lt;br /&gt;FROM workbook.&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_23"&gt;xls&lt;/span&gt; (biff, embedded labels, table is [$(&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_24"&gt;sheetName&lt;/span&gt;)]);&lt;br /&gt;NEXT &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_25"&gt;Sheetnames&lt;/span&gt; that contain blanks will be surrounded by single quotes. The &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_26"&gt;purgeChar&lt;/span&gt;() function above removes any single quotes that may be present in the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_27"&gt;sheetname&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;What if I only want to load those sheets names whose name begins with "Sales"? Wrap the LOAD statement in an IF statement to test the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_28"&gt;sheetname&lt;/span&gt;:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;IF &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_29"&gt;wildmatch&lt;/span&gt;('$(&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_30"&gt;sheetName&lt;/span&gt;)', 'Sales*') THEN&lt;br /&gt;LOAD .....&lt;br /&gt;END IF&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;How about this case? I want to load any sheet that contains the three columns "Sales", "Year" and "Quarter":&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;columns:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_31"&gt;SQLColumns&lt;/span&gt;; &lt;/span&gt;&lt;span style="font-family:times new roman;"&gt;// Get list of columns&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="font-family:times new roman;"&gt;// Join list with columns of interest&lt;/span&gt;&lt;br /&gt;RIGHT JOIN (columns) LOAD *;&lt;br /&gt;LOAD * &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_32"&gt;INLINE&lt;/span&gt; [ &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;COLUMN_NAME&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Quarter&lt;br /&gt;Sales&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Year&lt;br /&gt;]&lt;br /&gt;; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="font-family:times new roman;"&gt;// Create a count of how many columns of interest each sheet has&lt;/span&gt;&lt;br /&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_33"&gt;selectSheets&lt;/span&gt;:&lt;br /&gt;LOAD TABLE_NAME as &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_34"&gt;SheetName&lt;/span&gt;, count(*) as count&lt;br /&gt;RESIDENT columns&lt;br /&gt;GROUP BY TABLE_NAME&lt;br /&gt;;&lt;br /&gt;&lt;span style="font-family:times new roman;"&gt;// Keep only the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_35"&gt;SheetName&lt;/span&gt; that have all 3 columns&lt;/span&gt;&lt;br /&gt;RIGHT JOIN&lt;br /&gt;LOAD &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_36"&gt;SheetName&lt;/span&gt;&lt;br /&gt;RESIDENT &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_37"&gt;selectSheets&lt;/span&gt;&lt;br /&gt;WHERE count = 3 &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;br /&gt;&lt;/span&gt;// Load the selected sheets&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;FOR i = 0 to NoOfRows('selectSheets')-1 &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;LET sheetName = purgeChar(peek('SheetName', i, 'selectSheets'), chr(39)); &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;em&gt;LOAD....&lt;/em&gt;&lt;br /&gt;NEXT&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="font-family:arial;"&gt;You may wonder if you could use the Excel Driver instead of the Jet provider like this:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;br /&gt;CONNECT TO [Provider=&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_38"&gt;MSDASQL&lt;/span&gt;;Driver={Microsoft Excel Driver (*.xls)};DBQ=workbook.xls];&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;The connection will complete and you can use this connection for &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_39"&gt;SQL&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_40"&gt;SELECTs&lt;/span&gt;. However, when &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_41"&gt;SQLTables&lt;/span&gt; is called, the connection will enumerate tables/columns for &lt;strong&gt;all&lt;/strong&gt; the *.&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_42"&gt;xls&lt;/span&gt; files in the current directory. &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;This provider uses the parameter "&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_43"&gt;DefaultDir&lt;/span&gt;=" (default is .) to control which directory is enumerated for &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_44"&gt;SQLTables&lt;/span&gt; and &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_45"&gt;SQLColumns&lt;/span&gt; calls. The &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_46"&gt;DBQ&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_47"&gt;parm&lt;/span&gt; plays no part. You may find this useful as an alternative to using a traditional "for each &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_48"&gt;filelist&lt;/span&gt;..." loop to process multiple files.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Complete text of the examples presented here can be found in the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_49"&gt;QV&lt;/span&gt; Cookbook at:&lt;br /&gt;&lt;/span&gt;&lt;a href="http://robwunderlich.com/Download.html"&gt;http://robwunderlich.com/Download.html&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5070255803043802824-2051518200417618224?l=qlikviewnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qlikviewnotes.blogspot.com/feeds/2051518200417618224/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5070255803043802824&amp;postID=2051518200417618224' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/2051518200417618224'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/2051518200417618224'/><link rel='alternate' type='text/html' href='http://qlikviewnotes.blogspot.com/2008/09/loading-multiple-excel-sheets.html' title='Loading Multiple Excel Sheets'/><author><name>Rob Wunderlich</name><uri>http://www.blogger.com/profile/13048694338956825695</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://3.bp.blogspot.com/_IhQc1-zXHmU/SwH7Z2D8lUI/AAAAAAAAADo/UY17XpuzKLw/S220/avatar.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5070255803043802824.post-3438142325093406721</id><published>2008-09-24T16:14:00.000-07:00</published><updated>2008-10-03T10:38:12.333-07:00</updated><title type='text'>Using the Google Chart API inside Qlikview</title><content type='html'>&lt;span style="font-family:arial;"&gt;I recently had a requirement to create a heat map of the US States and set about exploring if there was an easier way than creating a QV scatter plot mapped over an image. &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;I found the Google Chart API. With some help from the QlikCommunity forum, I got a fairly pleasing result. &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;The Google Chart API is provided free by Google. You pass in an http request with parameters that describe the data and desired layout, and a chart image is returned. &lt;/span&gt;&lt;span style="font-family:Arial;"&gt;I won't cover the details of the API, it's well documented at &lt;a href="http://code.google.com/apis/chart/"&gt;http://code.google.com/apis/chart/&lt;/a&gt;. Rather, I'll share my experience integrating it with QV.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;Here's a screenshot of my results. The map will update as selections are made in the Sales chart. The generated map is not clickable. It's just a static image.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_IhQc1-zXHmU/SNrORmh3LaI/AAAAAAAAAAM/k1LPUfDjQGc/s1600-h/chart.png"&gt;&lt;img id="BLOGGER_PHOTO_ID_5249735117449407906" style="CURSOR: hand" alt="" src="http://2.bp.blogspot.com/_IhQc1-zXHmU/SNrORmh3LaI/AAAAAAAAAAM/k1LPUfDjQGc/s320/chart.png" border="0" /&gt;&lt;/a&gt;&lt;a href="http://4.bp.blogspot.com/_IhQc1-zXHmU/SNrO-eEi2II/AAAAAAAAAAc/xsTaR7FoNKQ/s1600-h/map.png"&gt;&lt;img id="BLOGGER_PHOTO_ID_5249735888273070210" style="CURSOR: hand" alt="" src="http://4.bp.blogspot.com/_IhQc1-zXHmU/SNrO-eEi2II/AAAAAAAAAAc/xsTaR7FoNKQ/s320/map.png" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;A working QVW of the above may be found in the Qlikview Cookbook at:&lt;/span&gt;&lt;br /&gt;&lt;a href="http://robwunderlich.com/Download.html"&gt;&lt;span style="font-family:arial;"&gt;http://robwunderlich.com/Download.html&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;The map is a Straight Table with a single expression. The expression is the http://... string used to generate the map. The representation for the expression is set to "Image". Thanks to Tom on the forum for showing me this technique.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;The &lt;span style="font-family:courier new;"&gt;OnAnySelect&lt;/span&gt; document event is used to trigger a "&lt;span style="font-family:courier new;"&gt;showMap()"&lt;/span&gt; macro that creates the variables needed for the http string. In a production application, you would want to be more selective and use field level events on the fields relevant to the chart.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;In addition to chart layout parameters, the http string contains two parameters that describe the data. &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-family:courier new;"&gt;chld=&lt;/span&gt; provides the list of states&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:courier new;"&gt;chd=&lt;/span&gt; provides the data values for the states&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;span style="font-family:arial;"&gt;The States and Values are associated by ordinal position in the respective lists. I could not find a way to keep the lists in sync by using QV expressions alone. The solution was to use the Sales chart as my "data source". The macro walks the rows of the table to build two variables -- the State codes and the Sales values. Here's a snippet of the macro code:&lt;/span&gt;&lt;/p&gt;&lt;div align="left"&gt;&lt;br /&gt;&lt;pre&gt;set obj = ActiveDocument.GetSheetObject("CH01")&lt;br /&gt;' Collect the locations&lt;br /&gt;locations = ""&lt;br /&gt;for RowIter = 1 to obj.GetRowCount-1&lt;br /&gt;locations = locations &amp;amp; obj.GetCell(RowIter,0).Text&lt;br /&gt;next&lt;br /&gt;ActiveDocument.GetVariable("vValues").setContent values, false&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;span style="font-family:arial;"&gt;Another area where VBScript was useful was in encoding the data values as specified by the API. I chose the "simple encoding" method. The Sales values are translated to relative values within a range of single characters defined by the API. &lt;/span&gt;&lt;span style="font-family:arial;"&gt;The doc &lt;a href="http://code.google.com/apis/chart/#simple"&gt;http://code.google.com/apis/chart/#simple&lt;/a&gt; provided a javascript encoding example which I converted to VBS. &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Arial;"&gt;The encoding algorithm requires that the maximum value of the dataset be known to properly spread the individual values across the relative range. To determine the maxvalue in the macro, I use the QV evaluate() function to "callback" to the QV expression language.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:courier new;"&gt;maxValue = ActiveDocument.evaluate(&lt;br /&gt;"max(aggr(sum(Sales), State))" )&lt;/span&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_IhQc1-zXHmU/SNrOc-Cq9CI/AAAAAAAAAAU/1BKLV0CEobo/s1600-h/map.png"&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;Producing a chart with the Google API does have some downsides. The user must be connected to the internet and the chart will render slower than a native QV chart. It also does not provide for making selections in the chart and tooltip values like a QV chart does. But I found it to be a simple solution to my requirement. I hope that someday the QV product will provide regional maps as chart types. &lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:arial;"&gt;&lt;em&gt;&lt;strong&gt;Update October 3, 2008&lt;/strong&gt;: Alistair on the QlikCommunity forum has posted an example of calling the Google Chart API without using macros, which I find to be the preferred method:&lt;/em&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.qlikcommunity.com/575/?tx_mmforum_pi1%5Baction%5D=list_post&amp;amp;tx_mmforum_pi1%5Btid%5D=3763&amp;amp;tx_mmforum_pi1%5Bfid%5D=9"&gt;&lt;span style="font-family:arial;"&gt;http://www.qlikcommunity.com/575/?tx_mmforum_pi1%5Baction%5D=list_post&amp;amp;tx_mmforum_pi1%5Btid%5D=3763&amp;amp;tx_mmforum_pi1%5Bfid%5D=9&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:arial;"&gt;&lt;em&gt;The next update to the Qlikview Cookbook will include the "macro-less" technique.&lt;/em&gt;&lt;/span&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5070255803043802824-3438142325093406721?l=qlikviewnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qlikviewnotes.blogspot.com/feeds/3438142325093406721/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5070255803043802824&amp;postID=3438142325093406721' title='17 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/3438142325093406721'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/3438142325093406721'/><link rel='alternate' type='text/html' href='http://qlikviewnotes.blogspot.com/2008/09/using-google-chart-api-inside-qlikview.html' title='Using the Google Chart API inside Qlikview'/><author><name>Rob Wunderlich</name><uri>http://www.blogger.com/profile/13048694338956825695</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://3.bp.blogspot.com/_IhQc1-zXHmU/SwH7Z2D8lUI/AAAAAAAAADo/UY17XpuzKLw/S220/avatar.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_IhQc1-zXHmU/SNrORmh3LaI/AAAAAAAAAAM/k1LPUfDjQGc/s72-c/chart.png' height='72' width='72'/><thr:total>17</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5070255803043802824.post-7202082245328279463</id><published>2008-09-11T21:07:00.000-07:00</published><updated>2008-09-13T10:52:29.923-07:00</updated><title type='text'>Gripe re Bug Reporting &amp; Research</title><content type='html'>&lt;span style="font-family:arial;"&gt;Love that Qlikview product. Love that Qliktech support staff. Hate that bug communication.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;br /&gt;In my last post, I described a bug encountered on a QV Server upgrade. How many customers should be warned of that bug? Under what conditions would the bug be suffered by other customers? All customers upgrading to the target release? Those coming from a specific release? A specific configuration? Are you impacted by this bug?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;Answer: you don't know. Qliktech probably does, but you -- the potentially impacted customer, do not. Unless we call or email our support rep, one at a time, and ask just the right question.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;I've been nagging Qliktech for some time now about online bug reporting and more importantly -- a searchable bug database. I've been told that it's "coming" for some time now. &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;What I want is:&lt;/span&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;To be able to submit and track a tech support ticket through a web interface.&lt;/span&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;That authorized users in my organization can view the content and status of those tickets. &lt;/span&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-family:Arial;"&gt;To be able to search a moderated database of all tickets/bug/solutions/workarounds submitted by all customers.&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;Are these cutting edge requirements? No, I get these facilities now from all my other enterprise software vendors.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;In my current organization, there are two part time QV Admins providing support, a dozen or so developers, a few managers who may want to be kept informed and sometimes a key user who is impacted by a problem.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;The current Qliktech support is via phone or email conversation. That means the staff person working the problem has to continually forward the ongoing conversation to all the interested parties in the Enterprise.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;A new problem? Has it already been reported and sufficiently documented by another customer? Is there a workaround? I don't know. So I'll take the time to create documentation and maybe a clear example for support. Only to find "we already know about that one". Or I'll make the quick inquiry and get the response "we need more detail". It's a guessing game. It's slow. It's inefficient. &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;I want to make it clear that I'm satisfied with the quality of the support representatives and the developers I've had contact with. My complaint is not about people, it's about tools. Having those tools would make both the customer and Qliktech's job easier.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5070255803043802824-7202082245328279463?l=qlikviewnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qlikviewnotes.blogspot.com/feeds/7202082245328279463/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5070255803043802824&amp;postID=7202082245328279463' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/7202082245328279463'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/7202082245328279463'/><link rel='alternate' type='text/html' href='http://qlikviewnotes.blogspot.com/2008/09/gripe-re-bug-reporting-research.html' title='Gripe re Bug Reporting &amp; Research'/><author><name>Rob Wunderlich</name><uri>http://www.blogger.com/profile/13048694338956825695</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://3.bp.blogspot.com/_IhQc1-zXHmU/SwH7Z2D8lUI/AAAAAAAAADo/UY17XpuzKLw/S220/avatar.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5070255803043802824.post-940519825340437623</id><published>2008-08-27T09:52:00.000-07:00</published><updated>2008-08-29T08:28:48.309-07:00</updated><title type='text'>QV Server 8.5 Upgrade</title><content type='html'>Last week I upgraded my Server (QVS) from 8.20 to 8.50.6091 and Publisher (QVP) from 8.20 to 8.20.6085.&lt;br /&gt;&lt;br /&gt;I don't have test server licenses, so both upgrades were done to production servers in the evening when few users were active.&lt;br /&gt;&lt;br /&gt;&lt;u&gt;&lt;strong&gt;QVS&lt;/strong&gt;&lt;/u&gt;&lt;br /&gt;After confirming I had current backups, I uninstalled the previous version and installed the new version. As stated in the documentation, the server primary folder needed to be respecified.&lt;br /&gt;&lt;br /&gt;Only one problem has been encountered, and it's significant. Server collaboration objects, including server bookmarks, created on 8.2 were no longer visible on 8.5! New objects can be created, but the old ones are "gone". QT support has identified this as a bug and I hope to receive a fix soon, including recovering the 8.2 objects.&lt;br /&gt;&lt;br /&gt;&lt;em&gt;Update 8/28: QT expects to provide a fix for this "mid to late September".&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;u&gt;&lt;strong&gt;QVP&lt;/strong&gt;&lt;/u&gt;&lt;br /&gt;After confirming I had backups of the server files, I shut down the services and performed a backup of the SQL Server QVPR repository. This was followed by an uninstall and install of the new version.&lt;br /&gt;&lt;br /&gt;Two problems occurred at startup.&lt;br /&gt;&lt;br /&gt;1. As expected, I had to reconnect to the repository (SQL Server QVPR database) at startup. When I tried to connect to the SQL Server, the connection failed with&lt;br /&gt;Login failed for user 'NT AUTHORITY\ANONYMOUS LOGON'&lt;br /&gt;&lt;br /&gt;The Execution Service and the Directory Service were both using domain accounts, per the documentation. The CommandCenter Service was using a local account, so it appeared to me that it must be trying to connect using the CommandCenter credentials. I modified the CommandCenter to use a domain account, but then could not get the ControlPanel page to display again. I was getting an asp.net error page -- something about could not connect to localhost:8081 (I didn't record the message and can't recreate it).&lt;br /&gt;&lt;br /&gt;I worked around the problem by using a SQL Server account to make the repository connection. Once the connection was established, I could change the Repository Settings screen back to "Use Windows authentication" and all works fine.&lt;br /&gt;&lt;br /&gt;2. The document links in the Access Point page were missing a "/" character.&lt;br /&gt;&lt;br /&gt;The generated links: &lt;span style="font-family:courier new;"&gt;qvp://serverfolder/doc.qvw&lt;/span&gt;&lt;br /&gt;were missing a "/" between the server and folder names. I fixed this by adding a "/" to LinkMachineName in settings.xml in&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;C:\Documents and Settings\All Users\Application Data\QlikTech\Publisher\AccesspointService&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&amp;lt;AddQvs Port="4747" LinkMachineName="(FromRequest)&lt;strong&gt;&lt;span style="color:#ff0000;"&gt;/&lt;/span&gt;&lt;/strong&gt;"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;My understanding is that a patch release is due out in early September.&lt;/span&gt;&lt;br /&gt;&lt;em&gt;Update 8/28: QT expects the patch release in "mid to late September".&lt;/em&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5070255803043802824-940519825340437623?l=qlikviewnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qlikviewnotes.blogspot.com/feeds/940519825340437623/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5070255803043802824&amp;postID=940519825340437623' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/940519825340437623'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/940519825340437623'/><link rel='alternate' type='text/html' href='http://qlikviewnotes.blogspot.com/2008/08/qv-server-85-upgrade.html' title='QV Server 8.5 Upgrade'/><author><name>Rob Wunderlich</name><uri>http://www.blogger.com/profile/13048694338956825695</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://3.bp.blogspot.com/_IhQc1-zXHmU/SwH7Z2D8lUI/AAAAAAAAADo/UY17XpuzKLw/S220/avatar.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5070255803043802824.post-3861804419190510194</id><published>2008-05-29T10:23:00.000-07:00</published><updated>2008-08-19T20:14:26.259-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tuning'/><category scheme='http://www.blogger.com/atom/ns#' term='qlikview'/><title type='text'>Memory sizes for data types</title><content type='html'>&lt;span style="font-family:arial;"&gt;An earlier post of mine &lt;a href="http://qlikviewnotes.blogspot.com/2008/05/when-less-data-means-more-ram.html"&gt;When less data means more RAM&lt;/a&gt; discussed the ways in which storage ("Symbol" space) needed for field values can increase depending on how a field is loaded or manipulated. This generated some followup questions on the QlikCommunity forum about the optimal storage sizes for fields of various data types.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;What's presented below is information gleaned from the documentation, QT Support and experimentation. The numbers come from the document memory statistics file. I hope someone from QT will help me correct any errors.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;QV fields have both an internal and external representation. There is a video "&lt;a href="http://qlikacademy.learn.com/files/upload/Video/Datatypes/Datatypes.html"&gt;Datatype Handling in Qlikview&lt;/a&gt;" available on QlikAcademy that explores this subject.&lt;/span&gt;&lt;span style="font-family:Arial;"&gt;This post is concerned with the internal storage of fields.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;strong&gt;&lt;u&gt;&lt;/u&gt;&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;strong&gt;&lt;u&gt;Numbers&lt;/u&gt;&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;I've found that the storage size appears to be related to the number of total digits. Storage size in bytes, for various digit ranges:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;1-10 digits, size=4&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;11 or more digits, size=13&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;The above sizes assume that the internal storage format is numeric, which is usually the case if loading from a database. Numbers loaded as text such as from a text file or inline, may be stored as strings which will occupy different sizes.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;u&gt;&lt;strong&gt;Dates, Times and Timestamps&lt;/strong&gt;&lt;/u&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;Different Database systems provide various degrees of precision in timestamps and I assume the ODBC driver is also involved with the exact value provided to QV during the load. QV times are the fractional part of a day, using up to 9 digits to the right of the decimal point.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;- Best size for a Date, 4 bytes.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;- Best size for a full Time, 13 bytes.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;- Best size for a full Timestamp, 13 bytes.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;These sizes can increase when the field is manipulated. Want to get the date portion of a timestamp? Don't use&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;date(aTimestamp)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;date() is a formatting function, it doesn't "extract" the underlying date portion. In many cases, it actually increases storage size because the result may be a string. Instead, use &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;floor(aTimestamp)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;this will produce a 4 byte integer result.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;A common technique for reducing the memory footprint of timestamps is to separate the timestamp into two fields, integer date and fractional time. You can further reduce the number of unique time values by eliminating the hundredths of seconds, or even eliminating the seconds if your application is ok with minute precision.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;u&gt;&lt;strong&gt;Strings&lt;/strong&gt;&lt;/u&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;Thanks to QT support for providing this detail on Strings. &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;"The representation is that each symbol has a pointer (4/8 bytes on 32/64-bit platform) + the actual symbol space. This space is the number of bytes (UTF-8 representation) + 2 (1 is a flag byte and 1 is a terminating 0) + 0, 4 or 8 bytes that store the numeric representation of the field."&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;So on the 32bit version, a non-numeric string occupies 6 bytes more than the length of the string itself. A numeric string occupies 10 more bytes. For example:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;"a" uses 7 bytes&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;"1" uses 11 bytes&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;The only way to reduce the string footprint is to reduce the number of unique values. This can be done by breaking the string into component parts if that makes sense in the application. For example, the first 3 characters of a 10 character product code may be a product class. Breaking the field into ProductClass and ProductNumber fields may reduce the number of unique values.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;If the strings are keys that don't need to be displayed, the autonumber() or autonumberhash128() functions can be used to transform the values to 4 byte integers. With these functions you can also get the "sequential integer optimization" which reduces the symbols space to zero. &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;I've found that concatenating fields in autonumber like&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;autonumber(f1 &amp;amp; f2) &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;can sometimes produce false duplicates. Better to instead use autonumberhash128 like&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;autonumberhash128(f1, f2)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;This seems to always produce correct results.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;strong&gt;&lt;u&gt;Sequential Integer Optimization&lt;/u&gt;&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:arial;"&gt;For each field, QV maintains both a Symbol table -- the unique values of a field -- and a State array that tracks which values are selected. If the symbol values are consecutive integers, a very clever optimization takes place. The Symbol space is eliminated and the State array is used to represent both selection state and value. This is a very beneficial effect of using the autonumber functions.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:arial;"&gt;&lt;/span&gt;&lt;p&gt;&lt;span style="font-family:arial;"&gt;The values need not begin at zero for the optimization to take place, they only need to be consecutive. A set of 5000 consecutive dates will occupy no Symbol space. Take one date out of the middle and the storage reverts to the standard 4 bytes for each date.&lt;/span&gt;&lt;/p&gt;&lt;span style="font-family:arial;"&gt;It's not always necessary to be concerned about memory usage. But when it is, I hope this information proves useful.&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Arial;"&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5070255803043802824-3861804419190510194?l=qlikviewnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qlikviewnotes.blogspot.com/feeds/3861804419190510194/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5070255803043802824&amp;postID=3861804419190510194' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/3861804419190510194'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/3861804419190510194'/><link rel='alternate' type='text/html' href='http://qlikviewnotes.blogspot.com/2008/05/memory-sizes-for-data-types.html' title='Memory sizes for data types'/><author><name>Rob Wunderlich</name><uri>http://www.blogger.com/profile/13048694338956825695</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://3.bp.blogspot.com/_IhQc1-zXHmU/SwH7Z2D8lUI/AAAAAAAAADo/UY17XpuzKLw/S220/avatar.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5070255803043802824.post-6539710674693757575</id><published>2008-05-22T00:39:00.000-07:00</published><updated>2008-12-01T14:18:00.607-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tuning'/><category scheme='http://www.blogger.com/atom/ns#' term='qlikview'/><title type='text'>64bit Implementation Experience</title><content type='html'>&lt;span style="font-family:arial;"&gt;When I started using Qlikview, I mistakenly believed I would not need the 64bit version of Server. I thought that because my Analyzer users were using the QV Windows Client, the memory required to hold the document would come from the user's machine. Wrong. When a document is opened from the server, the document is loaded into server memory.&lt;br /&gt;&lt;br /&gt;The 32bit Server uses a single 2GB address space to contain all the currently loaded documents. When the number of users increased, and more importantly, the number of concurrent documents, the Server ran out of memory. This unfortunately causes a Server crash, taking all the users down, not just the user that pushed it over the limit. It became clear we needed the 64bit edition.&lt;br /&gt;&lt;br /&gt;Upgrading the Server (QVS) to 64bit was easy. It immediately solved the memory issue and allowed for many documents to be used simultaneously with no problem.&lt;br /&gt;&lt;br /&gt;QV Publisher (QVP) turned out to be a different story. I initially installed Publisher on the same machine as Server but immediately ran into a problem with the availability of 64bit ODBC drivers.&lt;br /&gt;&lt;br /&gt;Any ODBC Driver used in 64bit Windows must be written as 64bit capable. I was using four ODBC data sources – IBM DB2, MS SQLServer, Lotus Domino and SAS. 64Bit SQLServer drivers are supplied with the OS. DB2 64bit drivers are available, but they can be expensive. The sticking point was that there were no 64bit drivers available for Lotus Domino and SAS.&lt;br /&gt;&lt;br /&gt;My first step was to move Publisher to a 32bit machine. This turns out to be a recommended practice anyway – host Server and Publisher on different machines. But I also had an application in development that would require 64bit for a full reload. How would I reload this application when it moved to production? I expected I would see more of these applications that required 64bit for reload.&lt;br /&gt;&lt;br /&gt;Publisher provides for defining multiple Execution Services (XS) on different machines. XS is the service that performs the reload process. The multiple XS's can be viewed and managed from a single Publisher Control panel screen. This feature allowed me to define an additional XS on a 64 bit server.&lt;br /&gt;&lt;br /&gt;My configuration now consists of three servers. A 64bit QVS, one 32bit QVP and one 64bit QVP. The 32bit QVP is loaded with all the ODBC drivers I need, the 64bit QVP has no drivers installed. The restriction in this configuration is that reloads on the 64bit QVP may only load QVDs and other non-ODBC datasources. In some cases, this may require a script to be split into two or more documents. Thus far, this restriction has proven to be only a minor inconvenience. The two reloads can be connected together by utilizing a RequestEDX task to trigger the second reload task.&lt;br /&gt;&lt;br /&gt;We chose not to migrate the developer workstations to 64bit due to the limited availability of ODBC drivers and other software. Most of the applications that require 64bit for reload can still be developed on a 32bit machine by loading a limited number of records. We did set up a single shared 64bit workstation that can be used by any developer when they require 64bit.&lt;br /&gt;&lt;br /&gt;Migrating QVS to 64bit provides the capacity to support many concurrent documents and users. If you plan to use the 64bit QVP, check on 64bit driver availability as part of your planning process. &lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5070255803043802824-6539710674693757575?l=qlikviewnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qlikviewnotes.blogspot.com/feeds/6539710674693757575/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5070255803043802824&amp;postID=6539710674693757575' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/6539710674693757575'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/6539710674693757575'/><link rel='alternate' type='text/html' href='http://qlikviewnotes.blogspot.com/2008/05/64bit-implementation-experience.html' title='64bit Implementation Experience'/><author><name>Rob Wunderlich</name><uri>http://www.blogger.com/profile/13048694338956825695</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://3.bp.blogspot.com/_IhQc1-zXHmU/SwH7Z2D8lUI/AAAAAAAAADo/UY17XpuzKLw/S220/avatar.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5070255803043802824.post-9090264093876199253</id><published>2008-05-19T07:20:00.000-07:00</published><updated>2010-10-04T15:55:25.479-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tuning'/><category scheme='http://www.blogger.com/atom/ns#' term='qlikview'/><title type='text'>When less data means more RAM</title><content type='html'>&lt;span style="font-family: arial;"&gt;I attended Niklas Boman's excellent Performance Tuning talk at Qonnections in Miami. One of his tuning recommendations was to reduce the number of rows and columns when possible. This will probably always have a positive impact on chart calculation time, but if done incorrectly, reducing the quantity of data can have an adverse impact on RAM usage.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: arial;"&gt;Consider a QVD file with one million rows. The QVD was loaded from a database and contains two fields:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: arial;"&gt;&lt;strong&gt;aNum&lt;/strong&gt; – unique integers, 1M unique values.&lt;br /&gt;&lt;strong&gt;aDate&lt;/strong&gt; – dates distributed equally throughout 2000-2003, 1,460 unique values.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: arial;"&gt;&lt;br /&gt;QV stores each of these values as integers, occupying 4 bytes of RAM each. Nice and compact.&lt;br /&gt;&lt;br /&gt;Which of the following statements will create a QVW that uses more RAM? Statement A, which loads 1000K rows or Statement B, which loads only 750K rows?&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Statement A:&lt;/strong&gt;&lt;span style="font-family: courier new;"&gt;// Load all 1,000,000 rows&lt;br /&gt;LOAD * FROM qvdData.qvd (qvd); &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;strong&gt;Statement B&lt;/strong&gt;:&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;// LOAD only 2001+ which should be 750,000 rows&lt;br /&gt;LOAD * FROM qvdData.qvd (qvd)&lt;br /&gt;WHERE year(aDate) &amp;gt; 2000; &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Pat yourself on the back if you answered “B”. B will use more RAM! More RAM for less data? Why? Because “B” causes an unoptimized load which results in QV converting the Integer representations of the data to String representation.&lt;br /&gt;&lt;br /&gt;QV can load QVDs in one of two modes – Optimized or Unoptimized (more in the Ref Guide). In an optimized load, the RAM image from the QVD is loaded directly into memory. An optimized load is indicated in the Loading message in the progress window. (Note to development: would be nice if the optimized message appeared in the log as well).&lt;br /&gt;&lt;br /&gt;In unoptimized mode, the QVD image is “unwrapped” and the data processed discretly. This causes the internal formatting to be lost and the data is stored internally as Mixed. So each “aNum” that previously occupied 4 bytes, now takes 9 bytes. “aDate” now averages 18.96 bytes each.&lt;br /&gt;&lt;br /&gt;It's the WHERE clause that forces the unoptimized load. Generally, adding fields or anything that causes a field value to be examined will force an unoptimized load. Examples of unoptimzed loads:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;LOAD *, year(aDate) as Year FROM qvdData.qvd (qvd) ;&lt;br /&gt;LOAD *, rowno() as rowid FROM qvdData.qvd (qvd) &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Even a WHERE clause that does not reference any field will be unoptimized:&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;LOAD * FROM qvdData.qvd (qvd)&lt;br /&gt;WHERE 1=1; &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;How can you tell how much RAM a field is using? “Document Settings, General, Memory Statistics” button will generate a .mem text file that contains a storage size for the “Symbols” (values) of each field. You can view the .mem file directly or load it into a QVW for processing. The 8.5 beta provides a “Qlikview Optimizer.qvw” for just this purpose. I've uploaded this file to the “Share Qlikviews” section of QlikCommunity if you don't have 8.5.&lt;br /&gt;&lt;br /&gt;&lt;u&gt;&lt;strong&gt;Workarounds&lt;/strong&gt;&lt;/u&gt;I've found that I can usually “fix” the field by setting the desired format in the Document Properties and checking the “Survive Reload” box. You can also apply formats in the load script, but I find this tedious if I have more than a few fields. Here are some alternative workarounds.&lt;br /&gt;&lt;br /&gt;To create additional fields, use a RIGHT JOIN after the optimized load.&lt;br /&gt;Instead of:&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;LOAD *, year(aDate) as Year FROM qvdData.qvd (qvd); &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;&lt;br /&gt;&lt;/span&gt;Use:&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;tdata:&lt;br /&gt;LOAD * FROM qvdData.qvd (qvd);&lt;br /&gt;RIGHT JOIN LOAD DISTINCT *, year(aDate) as Year&lt;br /&gt;RESIDENT tdata; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;&lt;br /&gt;&lt;/span&gt;For a subset selection, version 8 allows an optimized load using where exists() if the exists clause refers to only a &lt;em&gt;single&lt;/em&gt; field. This means you'll have to generate the desired values before the load using the same field name. Something like this: &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;&lt;br /&gt;//Generate table of the dates we want 2001-2004&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;LET vStartDate=num(MakeDate(2001,1,1)-1);&lt;br /&gt;LET vEndDate=num(MakeDate(2004,12,31));&lt;br /&gt;DateMaster:&lt;br /&gt;LOAD date($(vStartDate) + IterNo()) as aDate&lt;br /&gt;AUTOGENERATE 1&lt;br /&gt;WHILE $(vStartDate) + IterNo() &amp;lt;= $(vEndDate); &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;// Optimized load of the subset dates &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;tdata: &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;LOAD * FROM qvdData.qvd (qvd) WHERE exists(aDate); &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;DROP TABLE DateMaster; // No longer needed &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;In some cases, the above example will give you an additional optimization. Something I call the “sequential integer optimization” which I'll discuss on another day.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Worrying about RAM is not always necessary and many times is not worth the effort, especially if it makes your script harder to follow. However, for large datasets, particularly in the 32bit environment, you may be forced to optimize RAM usage. Using the mem files allows you to identify the most productive candidates for tuning.&lt;br /&gt;&lt;br /&gt;The QV Reference Guide points out that an optimized load will run faster than an unoptimized load. I think it would be useful to have brief discussion of the impact on RAM usage as well.&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5070255803043802824-9090264093876199253?l=qlikviewnotes.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qlikviewnotes.blogspot.com/feeds/9090264093876199253/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=5070255803043802824&amp;postID=9090264093876199253' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/9090264093876199253'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/5070255803043802824/posts/default/9090264093876199253'/><link rel='alternate' type='text/html' href='http://qlikviewnotes.blogspot.com/2008/05/when-less-data-means-more-ram.html' title='When less data means more RAM'/><author><name>Rob Wunderlich</name><uri>http://www.blogger.com/profile/13048694338956825695</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://3.bp.blogspot.com/_IhQc1-zXHmU/SwH7Z2D8lUI/AAAAAAAAADo/UY17XpuzKLw/S220/avatar.jpg'/></author><thr:total>3</thr:total></entry></feed>
