<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Load Script Archives -</title>
	<atom:link href="https://www.quickintelligence.co.uk/tag/load-script/feed/" rel="self" type="application/rss+xml" />
	<link></link>
	<description></description>
	<lastBuildDate>Fri, 21 Nov 2025 15:57:16 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9</generator>

<image>
	<url>https://www.quickintelligence.co.uk/wp-content/uploads/2017/05/cropped-QuickIntelligence_Square-32x32.png</url>
	<title>Load Script Archives -</title>
	<link></link>
	<width>32</width>
	<height>32</height>
</image> 
<site xmlns="com-wordpress:feed-additions:1">48890870</site>	<item>
		<title>Starting External Services From Qlik Sense Load Scripts</title>
		<link>https://www.quickintelligence.co.uk/starting-external-services-from-qlik-sense-load-scripts/</link>
					<comments>https://www.quickintelligence.co.uk/starting-external-services-from-qlik-sense-load-scripts/#respond</comments>
		
		<dc:creator><![CDATA[Steve Dark]]></dc:creator>
		<pubDate>Fri, 21 Nov 2025 15:57:16 +0000</pubDate>
				<category><![CDATA[Qlik Sense Tutorials]]></category>
		<category><![CDATA[IFTTT]]></category>
		<category><![CDATA[Load Script]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[Sense]]></category>
		<guid isPermaLink="false">https://www.quickintelligence.co.uk/?p=1505962</guid>

					<description><![CDATA[<p>We live in an increasingly interconnected world and various systems need to talk to each other to exchange information and to cause events to happen. Webhooks are one of the ways that messages can be sent between systems and this blog post explains how you can put these to work for you in your Qlik  [...]</p>
<p>The post <a href="https://www.quickintelligence.co.uk/starting-external-services-from-qlik-sense-load-scripts/">Starting External Services From Qlik Sense Load Scripts</a> appeared first on <a href="https://www.quickintelligence.co.uk"></a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>We live in an increasingly interconnected world and various systems need to talk to each other to exchange information and to cause events to happen. Webhooks are one of the ways that messages can be sent between systems and this blog post explains how you can put these to work for you in your Qlik load script.<span id="more-1505962"></span></p>
<h3>Why Call A Webhook?</h3>
<p>In my previous blog post (<a href="https://www.quickintelligence.co.uk/start-a-qlik-sense-cloud-reload-from-a-webhook/">Start a Qlik Sense Cloud Reload from a Webhook</a>) I described how to create a webhook using <a href="https://help.qlik.com/en-US/cloud-services/Subsystems/Hub/Content/Sense_QlikAutomation/introduction/home-automation.htm">Qlik Automations</a> which can start a reload of any app in your Qlik Cloud tenant. One of the places you might want to trigger this from is from a Qlik load script. This way you can call a reload of one or more Sense apps at the end of another script, perhaps dependant on data or status.</p>
<p>Triggering a Qlik Automation is one example of why you might want to fire a webhook, but in this post I want to share another example &#8211; raising an alert when things are broken.</p>
<p><img fetchpriority="high" decoding="async" src="https://www.quickintelligence.co.uk/wp-content/uploads/2025/11/Raise-Alert-From-Qlik-Using-A-Load-Script-Webhook-400x224.png" alt="Starting External Services From Qlik Sense Load Scripts" width="400" height="224" class="aligncenter size-fusion-400 wp-image-1505981" srcset="https://www.quickintelligence.co.uk/wp-content/uploads/2025/11/Raise-Alert-From-Qlik-Using-A-Load-Script-Webhook-200x112.png 200w, https://www.quickintelligence.co.uk/wp-content/uploads/2025/11/Raise-Alert-From-Qlik-Using-A-Load-Script-Webhook-300x168.png 300w, https://www.quickintelligence.co.uk/wp-content/uploads/2025/11/Raise-Alert-From-Qlik-Using-A-Load-Script-Webhook-400x224.png 400w, https://www.quickintelligence.co.uk/wp-content/uploads/2025/11/Raise-Alert-From-Qlik-Using-A-Load-Script-Webhook-600x335.png 600w, https://www.quickintelligence.co.uk/wp-content/uploads/2025/11/Raise-Alert-From-Qlik-Using-A-Load-Script-Webhook-768x429.png 768w, https://www.quickintelligence.co.uk/wp-content/uploads/2025/11/Raise-Alert-From-Qlik-Using-A-Load-Script-Webhook.png 800w" sizes="(max-width: 400px) 100vw, 400px" /></p>
<h3>How Do You Notify When Your Notifications Are Broken?</h3>
<p>Something we always set up when building customer environments is sufficient notifications to make us aware when anything is wrong. On Qlik Sense Client Managed this is essential, as there is very little out of the box, and on Cloud it needs to be set up space by space, so some things can be missed. Sometimes we are working on a secure site where SMTP relaying from within the site is not permitted. Other times it can be that communication between the Qlik server and the SMTP server is down due to network issues, so the route to let us know there is an issue is broken along with the rest of the network. In these cases we need a way to get a message out, when nothing else is working.</p>
<p>Something that is likely to work in Sense, even when all else is failing, is calling a URL to extract data. If that URL is a webhook then that call can then trigger an action. What we have is a an applet set up in <a href="https://ifttt.com/">IFFTT</a> (If This Then That) which sends an email via GMail containing values from the parameters of the webhook called. I won&#8217;t go into setting up that applet here, as it will be slightly different if you want to use a different mail client or call a different service, but I have given details on this in a previous blog post on <a href="https://www.quickintelligence.co.uk/ifttt-webhooks-qlik-cloud/">Inserting Qlik Capacity Usage Into a Spreadsheet</a>.</p>
<p><img decoding="async" class="aligncenter size-full wp-image-1505966" src="https://www.quickintelligence.co.uk/wp-content/uploads/2025/11/IFTTT-Gmail-via-Webhook.png" alt="IFTTT Gmail via Webhook" width="400" height="174" srcset="https://www.quickintelligence.co.uk/wp-content/uploads/2025/11/IFTTT-Gmail-via-Webhook-200x87.png 200w, https://www.quickintelligence.co.uk/wp-content/uploads/2025/11/IFTTT-Gmail-via-Webhook-300x131.png 300w, https://www.quickintelligence.co.uk/wp-content/uploads/2025/11/IFTTT-Gmail-via-Webhook.png 400w" sizes="(max-width: 400px) 100vw, 400px" /></p>
<p>Once you have a webhook set up that can send the notification you are ready to build an app that triggers that webhook when there is a problem.</p>
<h3>Raise a Notification When Files Go Stale</h3>
<p>The most basic measure of everything being up and working is that files that are used by your Qlik environment are all up to date. If the applications you wish to monitor do not currently create any files then it is a simple job to add a <a href="https://www.quickintelligence.co.uk/write-csv-qlikview-store/">STORE</a> statement to write a small text file that can be checked for. The application we shall build here then has an inline table (which will work even if all else is broken) with a list of file locations and how old those files can go before we want to be told about them.</p>
<p>Before building the load script for this app you will need to set up a REST connector that we can pass parameters in to. To do this build a new <a href="https://help.qlik.com/en-US/connectors/Subsystems/REST_connector_help/Content/Connectors_REST/Load-REST-data/Load-data.htm">REST connector</a>, set it to a placeholder URL (I tend to use <a href="https://jsonplaceholder.typicode.com/posts">https://jsonplaceholder.typicode.com/posts</a>), set the type to <strong>GET</strong>, ensure that <strong>Allow WITH CONNECTION</strong> is ticked and give it a name of <strong>Generic GET</strong>.</p>
<p><img decoding="async" class="aligncenter size-full wp-image-1505968" src="https://www.quickintelligence.co.uk/wp-content/uploads/2025/11/Create-Qlik-REST-Connection.png" alt="Create Qlik REST Connection" width="550" height="141" srcset="https://www.quickintelligence.co.uk/wp-content/uploads/2025/11/Create-Qlik-REST-Connection-200x51.png 200w, https://www.quickintelligence.co.uk/wp-content/uploads/2025/11/Create-Qlik-REST-Connection-300x77.png 300w, https://www.quickintelligence.co.uk/wp-content/uploads/2025/11/Create-Qlik-REST-Connection-400x103.png 400w, https://www.quickintelligence.co.uk/wp-content/uploads/2025/11/Create-Qlik-REST-Connection.png 550w" sizes="(max-width: 550px) 100vw, 550px" /></p>
<p>Once that connection is in place you can build the load script.</p>
<p>First you will need to set up some variables for use later in the script. Obviously the webhook parameter will need to be changed to match the webhook that you want to call.</p>
<pre class="qlik-highlight-pre"><code class="qlik-highlight-codeqvs">let vEnv = 'My Qlik Sense Tenant';
let vLib = 'DataSpace:';
let vGET = '$(vLib)Generic GET';
let vQVDs = 'lib://$(vLib)DataFiles/';
let vTimestamps = '$(vQVDs)Timestamp/';
let vWebhook = 'https://maker.ifttt.com/trigger/error/with/key/your-webhook-key-here';

let vLastLoad = now();</code></pre>
<p>Then you need to build the table of files that you want to be checking. These could be QVD files or small files that are written as part of a load script to indicate that the load script has completed. The table requires the full path to each file to be checked, how many hours old the file can get before an alert is raised and what label is to be used in the alert when that file becomes old.</p>
<pre class="qlik-highlight-pre"><code class="qlik-highlight-codeqvs">tmp:
LOAD
    File,Threshold,Name
INLINE [
File,Threshold,Name
$(vQVDs)Sales.qvd,1,Sales Application
$(vTimestamps)QVDGenerateCompleted.csv,3,QVD Generation Application
];</code></pre>
<p>That inline table can then be transformed to convert the hour given in the load script into a time delta to come off the current time, which can then be taken off the current time to work out the time that the file should be newer than. The actual date of the file also needs to be looked up. These two dates can then be compared to find the delta and to flag whether the file is old.</p>
<pre class="qlik-highlight-pre"><code class="qlik-highlight-codeqvs">FileAges:
LOAD
    *,
    if(FileDate &lt; Target, 'Yes', 'No') as Old,
    num((24)*(FileDate - Target), '0.00') as Difference
    ;
LOAD
    File,
    Threshold,
    Name,
    Date(alt(ConvertToLocalTime(FileTime(File), 'London'),0), 'DD MMM YYYY hh:mm') as FileDate,
    Date((LocalTime('London') - ((1/24)*Threshold)), 'DD MMM YYYY hh:mm') as Target
RESIDENT tmp;

DROP TABLE tmp;</code></pre>
<p>This table then needs to be aggregated to find out how many of the files checked are older than they should be. That value needs to be Peeked out into a variable.</p>
<pre class="qlik-highlight-pre"><code class="qlik-highlight-codeqvs">Old:
LOAD sum(1) as Old RESIDENT FileAges WHERE Old = 'Yes';
let vOld = alt(Peek('Old', -1, 'Old'), 0);
DROP TABLE Old;</code></pre>
<p>Now we get to the actual point of the app and the demonstration. If there are any old files, we need to do the call to the webhook endpoint along with a payload that tells us which environment is affected and how many of the files are stale.</p>
<pre class="qlik-highlight-pre"><code class="qlik-highlight-codeqvs">if alt(vOld, 0) &gt; 0 then
    SET errormode = 0;
    LIB CONNECT TO [$(vGET)];
    SQL SELECT "col_1" FROM CSV (header off, delimiter ",", quote """") "CSV_source"
    WITH CONNECTION (URL "$(vWebhook)?value1=$(vEnv)&amp;value2=$(vOld)%20Files%20Are%20Older%20Than%20They%20Should%20Be");
    SET errormode = 1;
end if

TRACE There are $(vOld) files older than expected;</code></pre>
<p>To wrap up, because we are tidy Qlik developers, we clear down the variables that we have used.</p>
<pre class="qlik-highlight-pre"><code class="qlik-highlight-codeqvs">let vEnv =;
let vWebhook =;
let vLib =;
let vGET =;
let vQVDs =;
let vTimestamps =;

Exit Script;</code></pre>
<p>That is it for the load script, and that is all you need to make this work. What you might want to do though, as the list of files checked is in a table in the data model along with their status, is to add a table to a sheet in the app listing the six columns in the <strong>FileAges</strong> table, with some conditional formatting to show when files are old. I would also add a button, which can then refresh the app without going into the load script.</p>
<h3>But What If Even This App Cannot Run?</h3>
<p>If you are running Sense on a Client Managed server it is possible (although very unlikely) that even this application will not be able to run and call the webhook, perhaps if someone has unplugged the server in order to recharge their mobile phone. In this case we need an external service to monitor what is going on. If the server is (as is most likely) behind a firewall that external service will not be able to reach in and check the status. In this case we want a service outside of the network which is expecting to hear from the server at a regular beat which can then raise an alert if it doesn&#8217;t hear anything.</p>
<p>This is exactly what I am going to cover in my next blog post, pulling together elements of this post and the previous post. This solution will use a webhook on a Sense Cloud tenant which calls a reload of a script that writes a to a QVD. There is also a separate application that checks the date of this QVD and notifies if that has not been updated in a specified window. The history of the webhook being called is persisted, so a history of when the calling server was up and able to reach the outside world is recorded, giving an accurate account of uptime on the server.</p>
<p><img decoding="async" class="aligncenter size-fusion-600 wp-image-1505969" src="https://www.quickintelligence.co.uk/wp-content/uploads/2025/11/Sense-Server-Uptime-Matrix-600x116.png" alt="Sense Server Uptime Matrix" width="600" height="116" srcset="https://www.quickintelligence.co.uk/wp-content/uploads/2025/11/Sense-Server-Uptime-Matrix-200x39.png 200w, https://www.quickintelligence.co.uk/wp-content/uploads/2025/11/Sense-Server-Uptime-Matrix-300x58.png 300w, https://www.quickintelligence.co.uk/wp-content/uploads/2025/11/Sense-Server-Uptime-Matrix-400x77.png 400w, https://www.quickintelligence.co.uk/wp-content/uploads/2025/11/Sense-Server-Uptime-Matrix-600x116.png 600w, https://www.quickintelligence.co.uk/wp-content/uploads/2025/11/Sense-Server-Uptime-Matrix-768x149.png 768w, https://www.quickintelligence.co.uk/wp-content/uploads/2025/11/Sense-Server-Uptime-Matrix.png 780w" sizes="(max-width: 600px) 100vw, 600px" /></p>
<p>If you have any comments on anything you would like to see covered in that blog post, or anything related to this blog post, please use the comments box below to get in touch.</p>
<h3>Other Uses For Calling A Webhook From The Qlik Load Script</h3>
<p>There is literally no end to what you can achieve by calling webhooks, particularly if you use a tool such as <a href="https://ifttt.com/">IFTTT</a>.</p>
<p>Another use you might want to consider, if you are using Qlik Sense Cloud, is <a href="https://www.quickintelligence.co.uk/start-a-qlik-sense-cloud-reload-from-a-webhook/">kicking off a reload using a webhook</a>. In my previous blog post I described how a Qlik Automation can be set up to be triggered from a webhook to do a reload. If at the end of the load script for one app you call the webhook with the correct parameter to kick off the next reload in a chain this reload chain will work however the reload is started, interactively or from a schedule. This gets around the limitation that Qlik Sense Cloud reload chaining from the hub presently has, where the next reload in the chain only takes place if the previous reload was started from a particular schedule. This reload chaining approach also allows for logic to be applied around whether the next reload should take place or not, perhaps the front end should only reload if there has been a change to the backend data?</p>
<p>I hope this post has given you plenty of inspiration of how you can link different services together within, and beyond, your Sense environment.</p>
<p>The post <a href="https://www.quickintelligence.co.uk/starting-external-services-from-qlik-sense-load-scripts/">Starting External Services From Qlik Sense Load Scripts</a> appeared first on <a href="https://www.quickintelligence.co.uk"></a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.quickintelligence.co.uk/starting-external-services-from-qlik-sense-load-scripts/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1505962</post-id>	</item>
		<item>
		<title>Compare Rolling Twelve Month Period in Qlik</title>
		<link>https://www.quickintelligence.co.uk/compare-rolling-twelve-month-period-in-qlik/</link>
					<comments>https://www.quickintelligence.co.uk/compare-rolling-twelve-month-period-in-qlik/#comments</comments>
		
		<dc:creator><![CDATA[Steve Dark]]></dc:creator>
		<pubDate>Fri, 05 May 2023 11:12:11 +0000</pubDate>
				<category><![CDATA[Load Script]]></category>
		<category><![CDATA[Qlik Sense Tutorials]]></category>
		<category><![CDATA[Dates]]></category>
		<category><![CDATA[Prior Period]]></category>
		<guid isPermaLink="false">https://www.quickintelligence.co.uk/?p=1505817</guid>

					<description><![CDATA[<p>Creating a line chart in Qlik showing a year on year comparison is very easy, using the Month and Year functions to create two dimensions. What if you want to show a rolling twelve month comparison though? This is not quite so obvious, but this post makes it just as easy. The Challenge The question  [...]</p>
<p>The post <a href="https://www.quickintelligence.co.uk/compare-rolling-twelve-month-period-in-qlik/">Compare Rolling Twelve Month Period in Qlik</a> appeared first on <a href="https://www.quickintelligence.co.uk"></a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Creating a line chart in Qlik showing a year on year comparison is very easy, using the Month and Year functions to create two dimensions. What if you want to show a rolling twelve month comparison though? This is not quite so obvious, but this post makes it just as easy.</p>
<p><span id="more-1505817"></span></p>
<h2>The Challenge</h2>
<p>The question was posed on Qlik Community how to overlay two 12 month measures in one chart. Using set analysis it is straight forward to have two measures which cover the correct date ranges, but when the Month dimension is used it will sort by calendar month, rather in the order required for rolling periods. You can see the question and my response in <a href="https://community.qlik.com/t5/New-to-Qlik-Sense/Overlay-2-rolling-12-month-measures-in-one-chart/m-p/2065557" target="_blank" rel="noopener">this post</a>.</p>
<p>The response uses a technique I have used a number of times before but it occurred to me that I have not documented it on the blog, so here it goes.</p>
<h2>Creating Rolling Month and Year Dimensions</h2>
<p>This code can either sit in your master calendar code, should you use one, or you can place it directly in the load statement from source data. Typically I will go for the latter approach.</p>
<p><img decoding="async" class="alignright size-medium wp-image-1505826" src="https://www.quickintelligence.co.uk/wp-content/uploads/2023/05/Rolling-Twelve-Month-Gauge-300x190.png" alt="Qlik Rolling Twelve Month Compare Gauge" width="300" height="190" srcset="https://www.quickintelligence.co.uk/wp-content/uploads/2023/05/Rolling-Twelve-Month-Gauge-200x126.png 200w, https://www.quickintelligence.co.uk/wp-content/uploads/2023/05/Rolling-Twelve-Month-Gauge-300x190.png 300w, https://www.quickintelligence.co.uk/wp-content/uploads/2023/05/Rolling-Twelve-Month-Gauge-320x202.png 320w, https://www.quickintelligence.co.uk/wp-content/uploads/2023/05/Rolling-Twelve-Month-Gauge-400x253.png 400w, https://www.quickintelligence.co.uk/wp-content/uploads/2023/05/Rolling-Twelve-Month-Gauge.png 467w" sizes="(max-width: 300px) 100vw, 300px" />The first thing that we need to do in the load script is to create a sequential integer for each month. This then allows us to work out the number of calendar months between any two dates. This technique has many more uses than just rolling twelve month analysis and is an incredibly useful dimension to have in your data model.</p>
<p>If we do <strong>(Year(Date)*100)+Month(Date) </strong>we will get a sequential integer value within a year (e.g. as at now it will give <strong>202305</strong>), but the deltas break when you go across a year (e.g. comparing <strong>202212</strong> to <strong>202301</strong>). In order to fix this we can just multiply the year by 12 and add the month. So, again taking May 23 as an example you will get <strong>24,281</strong>. This is obviously not at all useful as a human readable number (just as telling someone that the date today is <strong>45051</strong> is only useful if they are a machine), but it means that the numbers for Dec 22 (<strong>24,276</strong>) and Jan 23 (<strong>24,277</strong>) are now just one integer apart.</p>
<p>In the load script we can put this code in to create a new field called <strong>MonthNo</strong> like this:</p>
<pre class="qlik-highlight-pre"><code class="qlik-highlight-codeqvs">(Year(Date) * 12) + Month(Date) as MonthNo,</code></pre>
<p>Now we have that value we need to work out how many months back any given month is from today. The code that we used on the <strong>Date</strong> field can also be done on the <strong>today()</strong> function, giving a comparable figure for the current date. Using a <strong><a href="https://www.quickintelligence.co.uk/preceding-load-qlikview/" target="_blank" rel="noopener">preceding load</a></strong>, we can compare that to the <strong>MonthNo</strong> field to get a value for <strong>Months Back</strong>, like this:</p>
<pre class="qlik-highlight-pre"><code class="qlik-highlight-codeqvs">(Year(today()) * 12) + Month(Today()) - MonthNo as [Months Back]</code></pre>
<p>This new field in itself may be useful in your charts and filters within Sense, for instance it could make your <strong><a href="https://www.quickintelligence.co.uk/prior-period-comparison/" target="_blank" rel="noopener">set analysis</a></strong> for a chart showing the last twelve months much easier as you do not need to deal with date formats in the set code.</p>
<p>Jumping up another level of preceding load we can now use the <strong>Months Back</strong> value to create the <strong>Rolling Month</strong> and <strong>Rolling Year</strong> values.</p>
<p>The <strong>Month</strong> function gives us a dual data-typed value with the three letter month name and the integer order for the month from 1 to 12. The text part of that dual datatype is great for us but the number does not give us what we want.</p>
<p>We can use the <strong>Dual</strong> function though to build our own dual data-typed value with the correct sequential number. Using the output of the Month function as the first parameter of the <strong>Dual</strong> statement will only take the text part of that value. The correct sequential number can be calculated by working out how many months back the start of the year was and then taking away the months back for the date in question.</p>
<p>The whole of that code looks like this:</p>
<pre class="qlik-highlight-pre"><code class="qlik-highlight-codeqvs">Dual(Month(Month), (Floor([Months Back]/12)*12)-[Months Back]) as [Rolling Month],</code></pre>
<p>We can get the number of rolling years back from our <strong>Months Back</strong> value by taking the integer part of the number of months back divided by 12. In order to turn that into text to show as a dimension we want to suffix it with the text &#8220;Years Back&#8221;. As having &#8220;0 Years Back&#8221; looks a bit naff, we need to have anything in the past 12 months showing as &#8220;Current Year&#8221;. Having that text means that sorting on the field breaks (as it would if you have more than a decade of data), so we need to use the <strong>dual</strong> function again.</p>
<p>Putting all of that together gives us this statement:</p>
<pre class="qlik-highlight-pre"><code class="qlik-highlight-codeqvs">Dual(if([Months Back] &lt; 12, 'Current Year',
    Floor([Months Back]/12) &amp; ' Years Back'),
    Floor([Months Back]/12)) as [Rolling Year]</code></pre>
<p>We then have the two dimensions that we can use in a line chart:</p>
<p><img decoding="async" class="aligncenter size-full wp-image-1505822" src="https://www.quickintelligence.co.uk/wp-content/uploads/2023/05/Rolling-Twelve-Month-Line-Chart.png" alt="Line chart showing rolling twelve months" width="926" height="336" srcset="https://www.quickintelligence.co.uk/wp-content/uploads/2023/05/Rolling-Twelve-Month-Line-Chart-200x73.png 200w, https://www.quickintelligence.co.uk/wp-content/uploads/2023/05/Rolling-Twelve-Month-Line-Chart-300x109.png 300w, https://www.quickintelligence.co.uk/wp-content/uploads/2023/05/Rolling-Twelve-Month-Line-Chart-400x145.png 400w, https://www.quickintelligence.co.uk/wp-content/uploads/2023/05/Rolling-Twelve-Month-Line-Chart-600x218.png 600w, https://www.quickintelligence.co.uk/wp-content/uploads/2023/05/Rolling-Twelve-Month-Line-Chart-768x279.png 768w, https://www.quickintelligence.co.uk/wp-content/uploads/2023/05/Rolling-Twelve-Month-Line-Chart-800x290.png 800w, https://www.quickintelligence.co.uk/wp-content/uploads/2023/05/Rolling-Twelve-Month-Line-Chart.png 926w" sizes="(max-width: 926px) 100vw, 926px" /></p>
<h2>Putting It All Together</h2>
<p>This code generates a whole bunch of dates and then applies the date code described above in a resident load. You can copy and paste this to a new app and see the code working in isolation, or your can take parts of it to apply to your own data.</p>
<pre class="qlik-highlight-pre"><code class="qlik-highlight-codeqvs">tmpDate:
LOAD
    Date(today()-RowNo(), 'DD MMM YYYY') as Date
AUTOGENERATE(2000);

Dates:
LOAD
    *,
    Dual(Month(Month),
        (Floor([Months Back]/12)*12)-[Months Back]) as [Rolling Month],
    Dual(if([Months Back] &lt; 12, 'Current Year',
        Floor([Months Back]/12) &amp; ' Years Back'),
        Floor([Months Back]/12)) as [Rolling Year]
    ;
LOAD
    *,
    (Year(today()) * 12) + Month(Today()) - MonthNo as [Months Back]
    ;
LOAD
    Rand() * 1000 as Value,
    Date,
    Date(MonthStart(Date), 'MMM YYYY') as Month,
    (Year(Date) * 12) + Month(Date) as MonthNo,
    Month(Date) as [Month Name]
RESIDENT tmpDate
;

DROP TABLE tmpDate;</code></pre>
<p>Something else you might want to deal with when looking at rolling months is a <strong><a href="https://www.quickintelligence.co.uk/qlik-run-rate/" rel="noopener" target="_blank">run rate</a></strong> value for the current month, which takes into account how far through the month we are and what the value will be if extrapolated to the number of days in the month. I have covered this in a <a href="https://www.quickintelligence.co.uk/qlik-run-rate/" rel="noopener" target="_blank">previous post</a>.</p>
<p>Not only does this code give you dimensions that you can use in your charts, the same dimensions can be used in set analysis also. To create the variance to prior rolling twelve months gauge at the top of the chart you can now just use this code:</p>
<pre class="qlik-highlight-pre"><code class="qlik-highlight-codeexp">(Sum({&lt;[Rolling Year]*={'1 Years Back'}&gt;}Value) /
Sum({&lt;[Rolling Year]*={'Current Year'}&gt;}Value)) -1</code></pre>
<p>An example QVF file including this code and some example charts can be downloaded from the <a href="https://community.qlik.com/t5/New-to-Qlik-Sense/Overlay-2-rolling-12-month-measures-in-one-chart/m-p/2065557" target="_blank" rel="noopener">Qlik Community</a> post.</p>
<p>I would be very interested to hear from you on this technique and whether you have used similar or can suggest other ways it could be used. Please use the comments below if you would like to add your thoughts.</p>
<p>The post <a href="https://www.quickintelligence.co.uk/compare-rolling-twelve-month-period-in-qlik/">Compare Rolling Twelve Month Period in Qlik</a> appeared first on <a href="https://www.quickintelligence.co.uk"></a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.quickintelligence.co.uk/compare-rolling-twelve-month-period-in-qlik/feed/</wfw:commentRss>
			<slash:comments>4</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1505817</post-id>	</item>
		<item>
		<title>Loading Data from Online CSV Sources into Qlik</title>
		<link>https://www.quickintelligence.co.uk/load-online-csv-into-qlik/</link>
					<comments>https://www.quickintelligence.co.uk/load-online-csv-into-qlik/#respond</comments>
		
		<dc:creator><![CDATA[Steve Dark]]></dc:creator>
		<pubDate>Fri, 08 Jan 2021 10:17:30 +0000</pubDate>
				<category><![CDATA[Instant App]]></category>
		<category><![CDATA[Load Script]]></category>
		<category><![CDATA[Qlik Sense Tutorials]]></category>
		<category><![CDATA[csv]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[qlik sense]]></category>
		<guid isPermaLink="false">https://www.quickintelligence.co.uk/?p=1505308</guid>

					<description><![CDATA[<p>There are myriad different data sources out there, and it is possible to load any of them into Qlik. Some are easier than others, sure, but there is always a way. There are good articles and posts on some of the trickier sources, but today I want to show you how you can bring in  [...]</p>
<p>The post <a href="https://www.quickintelligence.co.uk/load-online-csv-into-qlik/">Loading Data from Online CSV Sources into Qlik</a> appeared first on <a href="https://www.quickintelligence.co.uk"></a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>There are myriad different data sources out there, and it is possible to load any of them into Qlik. Some are easier than others, sure, but there is always a way. There are good articles and posts on some of the trickier sources, but today I want to show you how you can bring in CSV data from GitHub. This means you can pull up to date, crowdsourced and governed data directly into your applications, just by following these simple steps.<br />
<span id="more-1505308"></span></p>
<h3>Introducing The CSV Data</h3>
<p>Recently I was asked to be involved with the <a href="https://dataonthe.earth/" target="_blank" rel="noopener noreferrer">Data On The Earth</a> project. This is an initiative to get data that can help everyone, from policy makers to concerned individuals, make more informed decisions about environmental issues. Naturally, I was very happy to help.</p>
<p><a href="https://dataonthe.earth/"><img decoding="async" class="aligncenter size-full wp-image-1505317" src="https://www.quickintelligence.co.uk/wp-content/uploads/2021/01/DataOnTheEarth.png" alt="Data On The Earth" width="550" height="96" srcset="https://www.quickintelligence.co.uk/wp-content/uploads/2021/01/DataOnTheEarth-200x35.png 200w, https://www.quickintelligence.co.uk/wp-content/uploads/2021/01/DataOnTheEarth-300x52.png 300w, https://www.quickintelligence.co.uk/wp-content/uploads/2021/01/DataOnTheEarth-400x70.png 400w, https://www.quickintelligence.co.uk/wp-content/uploads/2021/01/DataOnTheEarth.png 550w" sizes="(max-width: 550px) 100vw, 550px" /></a></p>
<p>The first thing I wanted to do was to present some ideas over some data that had relevance to the job in hand. The site <a href="https://ourworldindata.org/" target="_blank" rel="noopener noreferrer">Our World In Data</a> seemed like a good place to start.</p>
<p><img decoding="async" class="alignright size-medium wp-image-1505318" src="https://www.quickintelligence.co.uk/wp-content/uploads/2021/01/OctoCatMap-300x189.png" alt="GitHub OctoCat Map" width="300" height="189" srcset="https://www.quickintelligence.co.uk/wp-content/uploads/2021/01/OctoCatMap-200x126.png 200w, https://www.quickintelligence.co.uk/wp-content/uploads/2021/01/OctoCatMap-300x189.png 300w, https://www.quickintelligence.co.uk/wp-content/uploads/2021/01/OctoCatMap-320x202.png 320w, https://www.quickintelligence.co.uk/wp-content/uploads/2021/01/OctoCatMap-400x253.png 400w, https://www.quickintelligence.co.uk/wp-content/uploads/2021/01/OctoCatMap-600x379.png 600w, https://www.quickintelligence.co.uk/wp-content/uploads/2021/01/OctoCatMap.png 640w" sizes="(max-width: 300px) 100vw, 300px" />There I found data which related to Co2 emissions, hosted on <a href="https://github.com/" target="_blank" rel="noopener noreferrer">GitHub</a>, you can find more about these data <a href="https://ourworldindata.org/co2-and-other-greenhouse-gas-emissions" target="_blank" rel="noopener noreferrer">here</a>. The data are by Country and Year, so a bit of extra metadata on the countries would allow some demographic filtering. I found this in two further CSV files, also conveniently hosted on GitHub.</p>
<p>The data are not perfect, as some of the figures are not reported by all countries in every year and countries change over time. There are things that could be done to fix this up a bit (rolling forward last known figures, for instance), but I have not done that here. If you are planning to lobby a government over their emissions (or something) please check your facts and don&#8217;t rely on what is presented in these data alone!</p>
<h3>Creating a Connection</h3>
<p>The code in this article is for the load script of Qlik Sense. You can do similar with the REST connector in QlikView, but the syntax is a bit different, this post should give you pointers should you wish to build your own load script.</p>
<p>As with any load script in Sense you first need to have your connection created. Rather than create a separate connection for each data source I load I tend to create a generic connection of each type required and modify it using <a href="https://help.qlik.com/en-US/connectors/Subsystems/REST_connector_help/Content/Connectors_REST/Load-REST-data/Load-data.htm#WITH-CONNECTION-keyword" target="_blank" rel="noopener noreferrer">WITH CONNECTION</a>. You may already have the required connection set up if you have previously followed my tutorials on <a href="https://www.quickintelligence.co.uk/sense-session-logs/" target="_blank" rel="noopener noreferrer">Loading Sense Session Logs</a> or <a href="https://www.quickintelligence.co.uk/reading-rss-feeds-with-qlik-rest-connector/" target="_blank" rel="noopener noreferrer">Loading RSS Feeds</a>, if not go to the <strong>Data Load Editor</strong> and click <strong>Create New Connection</strong>.</p>
<p>Give your connection the name <strong>GenericGET</strong> and point it to a placeholder, such as <a href="https://jsonplaceholder.typicode.com/posts" target="_blank" rel="noopener noreferrer">https://jsonplaceholder.typicode.com/posts</a>, ensure the Method is set to <strong>GET</strong> and leave everything else as defaults.</p>
<p><img decoding="async" class="aligncenter size-full wp-image-1505262" src="https://www.quickintelligence.co.uk/wp-content/uploads/2020/07/GenericGet-Connection.jpg" alt="Config screen for GenericGET connection" width="428" height="238" srcset="https://www.quickintelligence.co.uk/wp-content/uploads/2020/07/GenericGet-Connection-200x111.jpg 200w, https://www.quickintelligence.co.uk/wp-content/uploads/2020/07/GenericGet-Connection-300x167.jpg 300w, https://www.quickintelligence.co.uk/wp-content/uploads/2020/07/GenericGet-Connection-400x222.jpg 400w, https://www.quickintelligence.co.uk/wp-content/uploads/2020/07/GenericGet-Connection.jpg 428w" sizes="(max-width: 428px) 100vw, 428px" /></p>
<p>Click on <strong>Test Connection</strong>, then <strong>Close</strong> and finally (if all is good) <strong>Create</strong>.</p>
<h3>Building the Load Script</h3>
<p>Now, onto building the load script. First we need to do some set up, to connect to our connection and set up some variables:</p>
<pre class="qlik-highlight-pre"><code class="qlik-highlight-codeqvs">LIB CONNECT TO 'GenericGET';

let vCompleteYears = 'Y'; // Y/N for all years or only 1990 - 2016 where data is quite complete
let vExcludeYears = if(upper(left(vCompleteYears, 1)) = 'Y', 'AND (year &gt;= 1990 AND year &lt;= 2016)', '');

set vFix = if([$1] = '', '$3', [$1]) as [$2];

let v1B = 1000000000;
let v1M = 1000000;</code></pre>
<p>The first variable allows us to turn on or off data for years which are not that complete, the second puts the code to implement that into a variable if switched on. Next we have a variable which includes parameters that we will use later on. If you have not used them before you should see this post on <a href="https://www.quickintelligence.co.uk/variables-parameters-load-script/" target="_blank" rel="noopener noreferrer">Using Parameters with Qlik Variables</a>. Finally a couple of variables to remove the risk of typing the wrong number of zeros later on.</p>
<p>Now we are set up, we can do the main part of the load.</p>
<pre class="qlik-highlight-pre"><code class="qlik-highlight-codeqvs">Emissions:
LOAD
iso_code &amp; year as CountryYear,
iso_code as [Country ISO],
country as Country,
year as Year,
co2 as CO2,
consumption_co2 as [CO2 Consumption],
trade_co2 as [CO2 Trade],
co2_per_unit_energy as [CO2 Per Unit Energy],
cement_co2 as [CO2 Cement],
coal_co2 as [CO2 Coal],
flaring_co2 as [CO2 Flaring],
gas_co2 as [CO2 Gas],
oil_co2 as [CO2 Oil],
total_ghg as [Total GHG],
methane as Methane,
nitrous_oxide as [Nitrous Oxide],
population as Population,
gdp as GDP
WHERE iso_code &lt;&gt; '' and index(iso_code, '_') = 0 // Remove rolled up values
$(vExcludeYears)
;
SQL SELECT
"iso_code",
"country",
"year",
"co2",
"consumption_co2",
"trade_co2",
"co2_per_unit_energy",
"cement_co2",
"coal_co2",
"flaring_co2",
"gas_co2",
"oil_co2",
"total_ghg",
"methane",
"nitrous_oxide",
"population",
"gdp"
FROM CSV
(header on, delimiter ",", quote """") "CSV_source"
WITH CONNECTION
(URL "https://raw.githubusercontent.com/owid/co2-data/master/owid-co2-data.csv")
;</code></pre>
<p>As with a database load this load will use the last opened connection. The <strong>CSV</strong> on the FROM line is specifying the basic format that we are loading from this connection, the exact format of the CSV is specified in the brackets &#8211; just as it would be if you were loading the CSV from a Folder Connection. The <strong>CSV_Source</strong> relates to which data source at the connection you wish to load &#8211; with a CSV this will only ever be CSV_source, but with JSON data there may be many named sets of data for you to choose from. The <strong>WITH CONNECTION</strong> then defines the URL we are loading from.</p>
<p>To explore these options further create another connection, pointing to that URL and look at the <strong>Select Data</strong> dialog for that connection.</p>
<p>Atop of the REST load we have a <a href="https://www.quickintelligence.co.uk/preceding-load-qlikview/" target="_blank" rel="noopener noreferrer">Preceding Load</a>, to tidy the fieldnames and remove data we don&#8217;t want. There are rows with data rolled up to regional levels, but we are going to do that ourselves in Qlik so need to remove the roll ups to avoid double counting. Note that when doing a <strong>WHERE</strong> in a preceding load all of the data still has to come down from the REST source first, so you may want to look if you can pass parameters to the URL you are loading from to drop some data, rather than using a WHERE statement.</p>
<p>So, that is the data we require from our main data source. We are going to continue though, and augment and categorise these data some more.</p>
<h3>Bringing in more CSV Data</h3>
<p>The next table of data is a simple table of country demographics, provided by GitHub, keyed on the ISO code for the country.</p>
<pre class="qlik-highlight-pre"><code class="qlik-highlight-codeqvs">Region:
LOAD
[ISO3166-1-Alpha-3] as [Country ISO],
$(vFix(Developed / Developing Countries, Developed, Not Known)),
$(vFix(Region Name, Region, Other)),
$(vFix(Sub-region Name, Sub Region, Other))
WHERE EXISTS ([Country ISO], [ISO3166-1-Alpha-3])
;
SQL SELECT
"ISO3166-1-Alpha-3",
"Developed / Developing Countries",
"Region Name",
"Sub-region Name"
FROM CSV (header on, delimiter ",", quote """") "CSV_source"
WITH CONNECTION
(URL "https://raw.githubusercontent.com/datasets/country-codes/master/data/country-codes.csv");</code></pre>
<p>This file has many more columns than we need, but we are cherry picking the few that we want. As you can see, the code for connecting to a CSV source is almost identical to above &#8211; just the URL is changing. In the Preceding load the <strong>vFix</strong> variable we created at the start is being used to replace any missing values with Not Known or Other. A WHERE EXISTS ensures we only get rows which relate to countries we have emissions data for.</p>
<p>Using a lookup table like this from a repository like GitHub in your Qlik apps means that your application will benefit from improvements to that dataset over time, rather than having a CSV or Excel spreadsheet languishing on your server which will never see an update.</p>
<h3>Where In The World Is That?</h3>
<p>As we are looking at country data it would be great to plot that on a map, and another GitHub source has just that information available for us. These data are provided and maintained by <a href="https://codeme.lt/" target="_blank" rel="noopener noreferrer">Tadas Tamošauskas</a> in a personal repo.</p>
<p>Here we are going to LEFT JOIN the data onto the existing region table, bringing the latitude/longitude data into the same table as the regions. You will see why in a bit.</p>
<pre class="qlik-highlight-pre"><code class="qlik-highlight-codeqvs">LEFT JOIN (Region)
LOAD
*,
GeoMakePoint(lat,long) as [Country Point]
;
LOAD
purgechar([Alpha-3 code], ' "') as [Country ISO],
purgechar([Latitude (average)], ' "') as lat,
purgechar([Longitude (average)], ' "') as long
WHERE EXISTS ([Country ISO], purgechar([Alpha-3 code], ' "'))
;
SQL SELECT
"Alpha-3 code",
"Latitude (average)",
"Longitude (average)"
FROM CSV (header on, delimiter ",", quote """") "CSV_source"
WITH CONNECTION
(URL "https://gist.githubusercontent.com/tadast/8827699/raw/f5cac3d42d16b78348610fc4ec301e9234f82821/countries_codes_and_coordinates.csv");</code></pre>
<p>This now lets us plot emissions data on a map by country. Our second data source though gave us <strong>Region</strong> and <strong>Sub Region</strong> names. It would be good if we could also plot by those regions. There is probably a data source out there which has SVG data for each region, but that could take a while to find and will not necessarily map to our existing region names.</p>
<p>We can apply a simple hack to generating points at each of the regions though.</p>
<pre class="qlik-highlight-pre"><code class="qlik-highlight-codeqvs">RegionPoint:
LOAD
Region,
GeoMakePoint(avg(lat),avg(long)) as [Region Point]
RESIDENT Region
GROUP BY Region;

SubRegionPoint:
LOAD
[Sub Region],
GeoMakePoint(avg(lat),avg(long)) as [Sub Region Point]
RESIDENT Region
GROUP BY [Sub Region];</code></pre>
<p>Here, a couple of RESIDENT loads from the existing Region table can be grouped to give one row per Region and Sub Region. For each of these rows the average latitude and average longitude can be calculated. These two values can then be changed to a point that can be easily used on a map. Note that some points may appear in the ocean, but that is the joy of using averages.</p>
<h3>Finding Latest Data and Grouping Figures</h3>
<p>The figures from our initial dataset are great for trending over time as they are provided on an annual basis. They are not so great for categorical data and providing filters though, as a country could move from one bucket to another year to year. For these filters we only want to use the latest figures. Here we hit another minor snag though, in that the last year in which data is available differs by country.</p>
<p>We can deal with this by finding the latest year for each country, using a RESIDENT, GROUP BY and MAX to create a composite key.</p>
<pre class="qlik-highlight-pre"><code class="qlik-highlight-codeqvs">LatestPop:
LOAD
[Country ISO] &amp; Year as LatestPop
;
LOAD
[Country ISO],
max(Year) as Year
RESIDENT Emissions
WHERE Population &lt;&gt; ''
GROUP BY [Country ISO];</code></pre>
<p>That composite key can then be used in the WHERE EXISTS of a subsequent RESIDENT load to only bring the latest data.</p>
<pre class="qlik-highlight-pre"><code class="qlik-highlight-codeqvs">Population:
LOAD
Country,
Population as [Population Latest],
dual(num(Round(Population, 100000) / $(v1M), '#,##0.0') &amp; 'M', Round(Population, 100000)) as [Population 100K],
dual(num(Round(Population, $(v1M)) / $(v1M), '#,##0') &amp; 'M', Round(Population, $(v1M))) as [Population 1M],
dual(num(Round(Population, $(v1M)0) / $(v1M), '#,##0') &amp; 'M', Round(Population, $(v1M)0)) as [Population 10M]
RESIDENT Emissions
WHERE EXISTS (LatestPop, CountryYear);</code></pre>
<p>This is a useful technique, and one I use frequently in live projects. As well as getting the exact number for the latest year for each country we can also put things into buckets. This can be done with a massive IF statement or for equal buckets an aggregation. Here I have used a <strong>Round</strong> statement, but you could use a <strong>Floor</strong> or <strong>Ceil</strong> if you prefer. The <a href="https://help.qlik.com/en-US/qlikview/April2020/Subsystems/Client/Content/QV_QlikView/ChartFunctions/GeneralNumericFunctions/round.htm" target="_blank" rel="noopener noreferrer">Round</a> function in Qlik is more flexible than in most languages as, rather than just rounding to a number of decimal places, you can specify what grouping you wish to go to, whether that is more or less than one.</p>
<p>The same technique can then be used for GDP, then there is just a little bit of housekeeping to do at the end of our script.</p>
<pre class="qlik-highlight-pre"><code class="qlik-highlight-codeqvs">LatestGDP:
LOAD
[Country ISO] &amp; Year as LatestGDP
;
LOAD
[Country ISO],
max(Year) as Year
RESIDENT Emissions
WHERE GDP &lt;&gt; ''
GROUP BY [Country ISO];

GDP:
LOAD
Country,
GDP as [GDP Latest],
dual(num(Round(GDP, $(v1B)), '#,##0') / $(v1B) &amp; 'B', Round(GDP, $(v1B))) as [GDP 1B],
dual(num(Round(GDP, $(v1B)0), '#,##0') / $(v1B) &amp; 'B', Round(GDP, $(v1B)0)) as [GDP 10B],
dual(num(Round(GDP, $(v1B)00), '#,##0') / $(v1B) &amp; 'B', Round(GDP, $(v1B)00)) as [GDP 100B]
RESIDENT Emissions
WHERE EXISTS (LatestGDP, CountryYear);

DROP FIELDS lat, long, LatestPop, LatestGDP;</code></pre>
<p>So, that is it. Put all those bits of script together and you should have a working load script to bring in emissions and demographic data from three separate online CSV sources.</p>
<p>Now you just need a quick way to analyse those data. Fortunately we have your back there.</p>
<h3>Viewing The Data In The Instant Sense Application</h3>
<p>To make it quick for us at Quick Intelligence to produce Proof Of Concepts for potential clients I created the Instant Sense Application. This application allows you to load any data source, and a spreadsheet of metadata about that data source, and then explore the data over twelve sheets of user configurable visualisations and tables.</p>
<p><img decoding="async" class="aligncenter size-full wp-image-1505265" src="https://www.quickintelligence.co.uk/wp-content/uploads/2020/07/Instant-Sense-Application-Thumbs-Blog.jpg" alt="Instant Sense Application Thumbs Blog" width="600" height="240" srcset="https://www.quickintelligence.co.uk/wp-content/uploads/2020/07/Instant-Sense-Application-Thumbs-Blog-200x80.jpg 200w, https://www.quickintelligence.co.uk/wp-content/uploads/2020/07/Instant-Sense-Application-Thumbs-Blog-300x120.jpg 300w, https://www.quickintelligence.co.uk/wp-content/uploads/2020/07/Instant-Sense-Application-Thumbs-Blog-400x160.jpg 400w, https://www.quickintelligence.co.uk/wp-content/uploads/2020/07/Instant-Sense-Application-Thumbs-Blog.jpg 600w" sizes="(max-width: 600px) 100vw, 600px" /></p>
<p>We have made this application available to all, at no cost, to make it quick and easy for others to showcase what Qlik Sense is capable of.</p>
<p>The application can be downloaded from here:</p>
<p><a href="https://www.quickintelligence.co.uk/instant-qlik-sense-app/" target="_blank" rel="noopener noreferrer">The Quick Intelligence Instant Sense Application</a></p>
<p>Details of how the application has been built can be found here:</p>
<p><a href="https://www.quickintelligence.co.uk/instant-qlik-sense-application/" target="_blank" rel="noopener noreferrer">How To Build A User Configurable Sense Application</a></p>
<p>If you already have the application, or if you just want the script above, you can download the script and meta-data here:</p>
<p><a href="https://www.quickintelligence.co.uk/isa/emissions.zip" target="_blank" rel="noopener noreferrer">Global Emissions Data By Year with Metadata</a></p>
<p>If you use the application and build more expressions that you feel will be useful for others, please share them in the comments below. As ever, I&#8217;m happy to receive questions and comments from readers, and will get back to these as soon as I am able.</p>
<p>The post <a href="https://www.quickintelligence.co.uk/load-online-csv-into-qlik/">Loading Data from Online CSV Sources into Qlik</a> appeared first on <a href="https://www.quickintelligence.co.uk"></a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.quickintelligence.co.uk/load-online-csv-into-qlik/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1505308</post-id>	</item>
		<item>
		<title>Send Data from the Qlik Load Script</title>
		<link>https://www.quickintelligence.co.uk/send-data-from-qlik-load-script/</link>
					<comments>https://www.quickintelligence.co.uk/send-data-from-qlik-load-script/#comments</comments>
		
		<dc:creator><![CDATA[Steve Dark]]></dc:creator>
		<pubDate>Sun, 04 Nov 2018 21:38:09 +0000</pubDate>
				<category><![CDATA[Qlik Sense Tutorials]]></category>
		<category><![CDATA[email]]></category>
		<category><![CDATA[Load Script]]></category>
		<category><![CDATA[Sense]]></category>
		<category><![CDATA[Tutorial]]></category>
		<guid isPermaLink="false">https://www.quickintelligence.co.uk/?p=504628</guid>

					<description><![CDATA[<p>Qlik Sense allows for interactive analysis of data, but sometimes you just want to send data to users via email. This tutorial describes how you can email a table of data during the load process using Qlik Web Connectors and HTML. It also looks at some of the other things you can do with the  [...]</p>
<p>The post <a href="https://www.quickintelligence.co.uk/send-data-from-qlik-load-script/">Send Data from the Qlik Load Script</a> appeared first on <a href="https://www.quickintelligence.co.uk"></a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>Qlik Sense allows for interactive analysis of data, but sometimes you just want to send data to users via email. This tutorial describes how you can email a table of data during the load process using Qlik Web Connectors and HTML. It also looks at some of the other things you can do with the free SMTP Connector.<br />
<span id="more-504628"></span></p>
<p style="text-align: center; padding: 20px 20px; font-size: 16px; background: #edfdd3; border: 1px solid #c4dba0; color: #657e3c;">Note that this article was written for Qlik Sense Enterprise Client Managed, and the solution still works on that platform. On Qlik Sense Cloud the syntax is slightly different as you have to use the SMTP connector rather than Qlik Web Connectors. Take a look at <strong><a href="https://www.quickintelligence.co.uk/sense-capacity-licence-notify/">this post</a></strong> for details of how to do that.</p>
<h2>Why Send Data From The Qlik Load Script</h2>
<p>QlikView has a couple of features which are very useful which are not provided with Sense straight out of the box. The first is that the QMC sends email alerts whenever a task fails, and the other is the Alerts functionality. Using the SMTP Connector within Qlik Web Connectors allows you to replicate this functionality and do more besides. This blog post looks at sending data to users from within the load script, I&#8217;m looking to write up Task failure notifications in a future blog post. As a reminder of how you can send data from QlikView you may want to see this blog post on <a href="https://www.quickintelligence.co.uk/qlikview-alerts/">Sending Data In QlikView Alerts</a>. The SMTP Connector is one of the Standard (i.e. free) connectors provided with Qlik Web Connectors, for details of these you can see this post on <a href="https://www.quickintelligence.co.uk/free-qlik-web-connectors/">Free Qlik Web Connectors</a>. Note that the SMTP Connector has been renamed from the original name of Notification Connector, which provides a bit more clarity around what it does.</p>
<p>What we are going to look at in this post is pushing a table of aggregated data out to an email address on each refresh of the data.</p>
<p><img decoding="async" class="aligncenter size-medium wp-image-504633" src="https://www.quickintelligence.co.uk/wp-content/uploads/2018/11/Send-Email-From-The-Sense-Load-Script-300x196.jpg" alt="Mailbox Receiving Sense Data" width="300" height="196" srcset="https://www.quickintelligence.co.uk/wp-content/uploads/2018/11/Send-Email-From-The-Sense-Load-Script-200x130.jpg 200w, https://www.quickintelligence.co.uk/wp-content/uploads/2018/11/Send-Email-From-The-Sense-Load-Script-300x196.jpg 300w, https://www.quickintelligence.co.uk/wp-content/uploads/2018/11/Send-Email-From-The-Sense-Load-Script-400x261.jpg 400w, https://www.quickintelligence.co.uk/wp-content/uploads/2018/11/Send-Email-From-The-Sense-Load-Script-600x391.jpg 600w, https://www.quickintelligence.co.uk/wp-content/uploads/2018/11/Send-Email-From-The-Sense-Load-Script-768x501.jpg 768w, https://www.quickintelligence.co.uk/wp-content/uploads/2018/11/Send-Email-From-The-Sense-Load-Script-800x521.jpg 800w, https://www.quickintelligence.co.uk/wp-content/uploads/2018/11/Send-Email-From-The-Sense-Load-Script-1024x667.jpg 1024w, https://www.quickintelligence.co.uk/wp-content/uploads/2018/11/Send-Email-From-The-Sense-Load-Script-1200x782.jpg 1200w" sizes="(max-width: 300px) 100vw, 300px" /></p>
<h2>Solution Approach</h2>
<p>Typically in a Sense app you are loading a number of details rows and then building tables and charts which provide aggregated views of the data. Using QlikView Alerts or NPrinting the Qlik engine can be used to build these aggregations for you. As we are going to be sending the data from the load script we need to perform the aggregations ourselves at this point. Both Alerts and NPrinting can also trigger mails based on criteria &#8211; whilst this example does not cover this always remember the load script is a full programming language so conditionally calling parts of the code is very simple.</p>
<p>In order to show the aggregated data clearly in an email we are going to be using HTML to build a table, with a touch of CSS to make it look tidy. The SMTP Connector allows you to pass the body of the email in the URL, or to link to a local file with the content. As our table may get quite large we are going to write it to a HTML file on disk and tell the connector to pull that in. The process of creating the file has been covered in this previous post on the <a href="https://www.quickintelligence.co.uk/write-csv-qlikview-store/">Qlik STORE Command</a>, but I will tell you all you need here also.</p>
<p>The SMTP Connector can also mail attachments and link to images (perhaps created on the fly using the Sense API), but I am not covering that in this post.</p>
<h2>Before You Start &#8211; The Prerequisites</h2>
<p>The solution given below assumes that your version of Sense supports the command <strong>URL IS</strong>. This was brought in in the February 2018 release of Sense. It also refers to the SMTP Connector, which was renamed at some point this year, so a up to date version of QWC is recommended. If you are using QWC without a licence (i.e. only free connectors) then you need to keep within the last couple of versions anyway, so an upgrade is always wise.</p>
<h2>Building An App Which Sends Data</h2>
<p>Now you are all set here are the steps you need to follow to have email sent to you directly from your Qlik load script. I&#8217;ve described connecting to some sample data (from the excellent <a href="https://www.gapminder.org/" target="_blank" rel="noopener noreferrer">GapMinder</a> site), but obviously you can plumb in whatever data you like. I&#8217;ve uploaded my app to <a href="https://community.qlik.com/" target="_blank" rel="noopener noreferrer">Qlik Community</a> should you want to download it, but you should get a fully working app by following these steps.</p>
<h3>Setting Up Libraries</h3>
<p>This app requires two libraries to be set up.</p>
<p>Firstly set up a <strong>Web</strong> library called <strong>GenericWeb</strong>. This can point to any valid web page, as we will replace the URL later on in code. This is still quite a new feature in Sense, and is well worth knowing how to use to avoid loads of different Web connections.</p>
<p>Next set up a <strong>Folder</strong> connection called <strong>TempData</strong> to a temporary store on your Sense server or desktop. I&#8217;ve used <strong>c:\temp\</strong>. You can use a different location, just adapt the code later on. As this location will have a copy of your data in it you will need to ensure it is secure.</p>
<h3>Creating Encoding Subroutine</h3>
<p>A number of the variables which make up the URL which is passed to Qlik Web Connectors need to be URL Encoded. This means that characters which could be misinterpreted need to be changed to a sequence of characters instead.</p>
<p>Create a sub routine to do this encoding:</p>
<pre class="qlik-highlight-pre"><code class="qlik-highlight-codeqvs">sub Encode(vEncodeMe, vEncoded)
let vEncoded = replace(replace(replace(replace(replace(replace(replace(vEncodeMe, ':', '%3a'), '/', '%2f'), '?', '%3f'), '=', '%3d'), '\', '%5c'), '@', '%40'), ' ', '+');
end sub</code></pre>
<p>The first parameter is the value to be encoded, the second parameter is a variable to be populated with the encoded value.</p>
<h3>Setting Constants</h3>
<p>These three variables store some environmental values. The variable <strong>vQwcConnectionName</strong> is used when Qlik Web Connectors when it generates Standard Mode code for us, so it is worth using that name. The <strong>vConn</strong> is just to make our URL shorter later, as we can refer to the variable. Finally vEmailFile defines where our staging file will be written, this must match the folder of the library created earlier.</p>
<pre class="qlik-highlight-pre"><code class="qlik-highlight-codeqvs">let vQwcConnectionName = 'lib://GenericWeb';
let vConn = 'https://localhost:5555/data?connectorID=NotificationConnector';
let vEmailFile = 'c:\temp\EMailOutput.html';</code></pre>
<p>The URL of your Qlik Web Connector server may differ, so enter that in here. You may require a machine name or domain reference here, rather than localhost, if your QWC instance is on another machine.</p>
<h3>SMTP Settings</h3>
<p>Now we define the settings for the SMTP connection. Note that some of these variables use the <strong>Encode</strong> sub-routine we created, others we don&#8217;t need to use it for.</p>
<pre class="qlik-highlight-pre"><code class="qlik-highlight-codeqvs">call Encode('notifyme@wherever.com', vMailRecipients);
call Encode('smtp.gmail.com', vSMTP);
let vPassword = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX';
call Encode('someaddress@gmail.com', vFromEmail);
call Encode('Sending data from Sense Load Script', vSubject);
call Encode(vEmailFile, vEmailContent);
let vUseSSL = 'True';
let vSSLMode = 'Implicit';
let vPort = '465';</code></pre>
<p>The settings above are for a GMail account. You will need to plumb in the correct settings for whichever SMTP server you wish to use. As this process is for sending emails only it is a good idea to set up a new account expressly for this purpose.</p>
<p>The password needs to be encoded before it is entered here. This can be done using the Qlik Web Connectors UI. First go to your QWC page (https://localhost:5555/) and go to the SMTP Connector settings (this is under the Standard connectors). In here you can set up and test your SMTP settings, including entering your password. The code which is generated on successful running will include the encoded version of your password. Extract this from the URL and enter it in the right place, it will appear after <strong>Password=</strong> and before the next ampersand (&amp;).</p>
<p>Note that whilst the password looks very different it needs to be passed to SMTP as the original string. This means that a two way encoding mechanism is used, so someone who has your encoded password could in theory turn it back to the original one. Hence the advice to set up a new account just for sending.</p>
<p>There is a function in QWC where you can send a plain text password and receive the encoded one back (the Helper connector). This means you can enter the password in plain text in your script. I wouldn&#8217;t recommend this approach though.</p>
<p>Note that the Subject is included in these variables. If you want to have a dynamic subject (e.g. with record count) you can move that line to later in your code.</p>
<h3>Get Some Data</h3>
<p>Here you need to get the source data for whatever table you want to email around. If the application you are creating is purely for sending data you may want to bring in the aggregated data that you wish to send. If you are sending from an app that is also used for analysis you probably want detailed data for that analysis, and the aggregated data can be created in the next step.</p>
<p>This statement uses our generic library and grabs some data.</p>
<pre class="qlik-highlight-pre"><code class="qlik-highlight-codeqvs">Population:
CROSSTABLE (Year, Population) LOAD
"Total population" as Country,
[2011.0] as [2011],
[2012.0] as [2012],
[2013.0] as [2013],
[2014.0] as [2014],
[2015.0] as [2015]
FROM [$(vQwcConnectionName)]
(URL IS [https://docs.google.com/spreadsheet/pub?key=phAwcNAVuyj0XOoBL_n5tAQ&amp;output=xlsx], ooxml, embedded labels, table is Data)
;</code></pre>
<h3>Aggregate That Data</h3>
<p>When you create a table in Qlik Sense you will provide a number of dimensions and then some calculations (Measures). This will then give you one row per distinct combination of dimensions.</p>
<p>We need to create that same table in code. This can be done with a GROUP BY statement, like this.</p>
<pre class="qlik-highlight-pre"><code class="qlik-highlight-codeqvs">AnnualData:
LOAD
Year,
num(sum(Population), '#,##0') as [World Population],
num(max(Population), '#,##0') as [Largest Population],
num(avg(Population), '#,##0') as [Country Average]
RESIDENT Population
GROUP BY Year
;</code></pre>
<p>In this instance we are creating one row per Year. Additional dimensions can be added to the load list, each of these also need to be added to the GROUP BY statement, in a comma separated list.</p>
<p>The expressions given in a GROUP BY load are very similar to those used in the expressions in Qlik objects in the front end, but there are some differences. Try the expressions that you would use to see if they work, if not you will need to modify. Probably the most notable difference is that you do not have access to Set Analysis in the load script.</p>
<h3>Load Header Information into a Table</h3>
<p>We are going to write the contents of a Qlik table to a file to then send as an HTML email. So first we need to put the preamble into the table.</p>
<pre class="qlik-highlight-pre"><code class="qlik-highlight-codeqvs">EMailOutput:
LOAD
[&lt;!--EMailOutput--&gt;]
INLINE [
&lt;!--EMailOutput--&gt;
&lt;html&gt;
&lt;head&gt;
&lt;style&gt;
tr:first-child td {font-weight: bold;background-color: #dddddd;}
h3 {Font-family: Arial;Font-size: 12pt;}
td {border-left:1px solid #555555;border-top:1px solid #555555;font-family: Arial;font-size:9pt;text-align:left;padding: 2px 10px 2px 10px;}
table {border-right:1px solid #555555;border-bottom:1px solid #555555;border-collapse:collapse;}
&lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;h3&gt;Population stats for past five years&lt;/h3&gt;
&lt;table&gt;
&lt;tr&gt;&lt;td&gt;Year&lt;/td&gt;&lt;td&gt;World Population&lt;/td&gt;&lt;td&gt;Largest Population&lt;/td&gt;&lt;td&gt;Country Average&lt;/td&gt;&lt;/tr&gt;
];</code></pre>
<p>Note that the field name will be written to our output file, so it needs to make sense as HTML. This is why I have put a HTML comment there.</p>
<p>A style sheet is given here, which means that the table which is written out with the data in can be much simpler as all styling is handled by the CSS.</p>
<h3>Add The Data Table</h3>
<p>We have the data we need in a table, we now just need to format it so it displays right in HTML and add it to our table.</p>
<pre class="qlik-highlight-pre"><code class="qlik-highlight-codeqvs">CONCATENATE(EMailOutput)
LOAD
'&lt;tr&gt;&lt;td&gt;' &amp; Year &amp;
'&lt;/td&gt;&lt;td&gt;' &amp; replace([World Population], ',', '&amp;#44;') &amp;
'&lt;/td&gt;&lt;td&gt;' &amp; replace([Largest Population], ',', '&amp;#44;') &amp;
'&lt;/td&gt;&lt;td&gt;' &amp; replace([Country Average], ',', '&amp;#44;') &amp; '&lt;/td&gt;&lt;/tr&gt;' as [&lt;!--EMailOutput--&gt;]
RESIDENT AnnualData
ORDER BY Year DESC
;</code></pre>
<p>Here we are constructing a number of HTML table cells to properly contain each value in our data. Note that one row of text will be written for each row of the table.</p>
<p>Note that we need to do a replace on the values to URL Encode the commas in the numbers. This is not because the commas will not display correctly in HTML, rather than when the STORE statement is called later it will place double quotes around any values that include commas in them. This will break our HTML. If you don&#8217;t use commas as thousand separators then you are good to go without the replaces.</p>
<h3>Append On The Footer Information</h3>
<p>Just as we started with the header information we now need to concatenate on the footer information.</p>
<pre class="qlik-highlight-pre"><code class="qlik-highlight-codeqvs">CONCATENATE(EMailOutput)
LOAD
[&lt;!--EMailOutput--&gt;]
INLINE [
&lt;!--EMailOutput--&gt;
&lt;/table&gt;
&lt;/body&gt;
&lt;/html&gt;
];</code></pre>
<p>You have probably noticed that we are simply building up our code in bite-sized chunks. In the same way we could build in a number of tables and bits of narrative in one email. We are not limited to a single table of data here.</p>
<h3>Write The HTML to a Text File</h3>
<p>Now we have our table constructed with all of our HTML code we need to write this to a file that the SMTP connector can use. This is simply a case of using the STORE statement that you have probably used for writing QVDs, but here we are saying that we want this written as a text file.</p>
<pre class="qlik-highlight-pre"><code class="qlik-highlight-codeqvs">STORE EMailOutput INTO [lib://TempData/EmailOutput.html] (txt);</code></pre>
<p>If your Library was set to point to a web server, perhaps on a UNC path or on the Sense server, then this output can be served up on a web page. This is a great way of outputting data from Sense for a wall board. A very simple Sense extension can be used to make Sense into a web server for this purpose &#8211; I will write this up in a future blog post.</p>
<p>For now though we are just using this output in the SMTP Connector.</p>
<h3>Send The Email</h3>
<p>Finally we just need to send the email. This is done by pulling data from a web page (the same as any other Qlik Web Connector call), the difference is though that this call interacts with a server to send data and not just receive it.</p>
<pre class="qlik-highlight-pre"><code class="qlik-highlight-codeqvs">SendEmail:
LOAD
status as SendEmail_status,
result as SendEmail_result,
filesattached as SendEmail_filesattached
FROM [$(vQwcConnectionName)]
(URL IS [$(vConn)&amp;table=SendEmail&amp;SMTPServer=$(vSMTP)&amp;useSSL=$(vUseSSL)&amp;SSLmode=$(vSSLMode)&amp;Port=$(vPort)&amp;Password=$(vPassword)&amp;to=$(vMailRecipients)&amp;subject=$(vSubject)&amp;message=%40file%3d$(vEmailContent)&amp;fromName=Sense&amp;fromEmail=$(vFromEmail)&amp;appID=],
qvx);</code></pre>
<p>Note that we have three fields coming back from the query. These will confirm to us whether the send was successful or not. If you want to bulletproof your code you should use PEEK to look at these values just to check that the process has done what you expect.</p>
<p>You will see in the URL all of the variables that we have set up. Crucially there is the <strong>message=</strong> parameter, which then is pointed to a file, and the location of the content we have written to disk.</p>
<p>Note that you can generate the bulk of this code using the Qlik Web Connectors UI, but the code here has all the various parts moved out into variables, which makes it easier to configure.</p>
<p><img decoding="async" class="aligncenter size-full wp-image-504646" src="https://www.quickintelligence.co.uk/wp-content/uploads/2018/11/Qlik-Sense-Email-Received.jpg" alt="Qlik Sense Email Received" width="450" height="225" srcset="https://www.quickintelligence.co.uk/wp-content/uploads/2018/11/Qlik-Sense-Email-Received-200x100.jpg 200w, https://www.quickintelligence.co.uk/wp-content/uploads/2018/11/Qlik-Sense-Email-Received-300x150.jpg 300w, https://www.quickintelligence.co.uk/wp-content/uploads/2018/11/Qlik-Sense-Email-Received-400x200.jpg 400w, https://www.quickintelligence.co.uk/wp-content/uploads/2018/11/Qlik-Sense-Email-Received.jpg 450w" sizes="(max-width: 450px) 100vw, 450px" /></p>
<h2>Example Application</h2>
<p>If you have followed the instructions above you should now have an application which emails you data on each reload.</p>
<p>In case this hasn&#8217;t quite worked out for you, or if you would just like to check your workings, you can download my completed application from Qlik Community. You can find this here:</p>
<p><a href="https://community.qlik.com/t5/Qlik-Sense-Documents/Qlik-Sense-App-Send-Data-From-The-Load-Script/ta-p/1481383" target="_blank" rel="noopener noreferrer">https://community.qlik.com/t5/Qlik-Sense-Documents/Qlik-Sense-App-Send-Data-From-The-Load-Script/ta-p/1481383</a></p>
<p>The application also has a sheet which shows the two sets of data (aggregated and raw), the result from the SMTP send and the HTML generated as a table.</p>
<p>If you have any questions regarding this technique please put them in the comments below, thanks!</p>
<h2>Community Update!</h2>
<p><a href="https://qlikdevgroup.com/speaker/hector-munoz/">Héctor Muñoz</a> has kindly shared this post on his blog, and not only that he has taken it to another level. With the code above it is only possible to send tables of data. What Héctor has done is provided the code needed to get data in the load script, parse it, send it to the <a href="https://www.image-charts.com/">Image Charts</a> site to get a chart and then include that in the body of the email. This is awesome and opens up some very interesting possibilities. Many thanks Héctor for doing this.</p>
<p>The blog post has unfortunately now been taken down.</p>
<p>We always welcome people commenting on or expanding the things we do in our posts. Please used the comments field below if you have something you would like to share.</p>
<p>The post <a href="https://www.quickintelligence.co.uk/send-data-from-qlik-load-script/">Send Data from the Qlik Load Script</a> appeared first on <a href="https://www.quickintelligence.co.uk"></a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.quickintelligence.co.uk/send-data-from-qlik-load-script/feed/</wfw:commentRss>
			<slash:comments>50</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">504628</post-id>	</item>
	</channel>
</rss>

<!--
Performance optimized by W3 Total Cache. Learn more: https://www.boldgrid.com/w3-total-cache/?utm_source=w3tc&utm_medium=footer_comment&utm_campaign=free_plugin

Page Caching using Disk: Enhanced 
Minified using Disk

Served from: www.quickintelligence.co.uk @ 2026-04-16 21:49:57 by W3 Total Cache
-->