Unlock a world of possibilities! Login now and discover the exclusive benefits awaiting you.
By reading the Product Innovation blog, you will learn about what's new across all of the products in our growing Qlik product portfolio.
The Support Updates blog delivers important and useful Qlik Support information about end-of-product support, new service releases, and general support topics.
This blog was created for professors and students using Qlik within academia.
Hear it from your Community Managers! The Community News blog provides updates about the Qlik Community Platform and other news and important announcements.
The Qlik Digest is your essential monthly low-down of the need-to-know product updates, events, and resources from Qlik.
The Qlik Education blog provides information about the latest updates of our courses and programs with the Qlik Education team.
Often when you create scripts, you need to create new fields, based on counters. There are several ways to do this. Some are simple, others not so…
Using RecNo()
The RecNo() function simply counts the input records and returns the number of the current record. Simple, and very useful if you want to create a record ID. However, if you concatenate several input files, or use a While clause, the numbers will not be unique.
Using RowNo()
The RowNo() function is very similar to the RecNo(), but this instead counts the output records and returns the number of the current record. Also simple and useful, especially if you concatenate several input tables. In such a case, the function will return consecutive numbers for the output table.
Using AutoNumber()
The AutoNumber() function is useful if you want to put a number on a specific field value, or on an attribute that is a combination of field values. The attributes will be numbered and their numbers re-used appropriately.
AutoNumber( Product & '|' & Date ) as ID
Using inline Peek() and RangeSum()
This is the mother of all record counters. Anything can be numbered; it can be done conditionally and anything can be used as condition. The idea is to fetch the counter value from the previous record and increase it only if some condition is fulfilled. Or reset it.
An example: For production quality control, some process indicator is measured and the Quality Manager wants to track trends and trend shifts. Then it is important to see the number of consecutive days that this indicator has increased or decreased. It is also good if the series of consecutive days can get a unique ID that can be used for selections and charts.
The following script creates these two fields; TrendID and DaysWithTrend.
Load *,
If( Change * Peek( Change ) > 0,
Peek( TrendID ),
RangeSum( 1, Peek( TrendID ))
) as TrendID,
If( Change * Peek( Change ) > 0,
RangeSum( 1, Peek( DaysWithTrend )),
0
) as DaysWithTrend;
Load
Indicator,
Indicator - Peek( Indicator ) as Change
Resident Daily_TQM_Measurement
Order By Date;
First of all, the change of the indicator value is calculated in the bottom Load using the Peek() function. In the preceding Load, the change is used as condition in the If() function. The condition compares current record with the previous record using the last change and the second last change. If the product of the two is greater than zero, the trend has been the same two days in a row, so the TrendID of the previous record is used (the Peek() function) and DaysWithTrend is increased by one.
But if the condition is false, the TrendID is increased by one and the DaysWithTrend is reset to zero.
When a counter is increased, normal addition cannot be used since the Peek() will return NULL for the very first record. Instead the addition is made using the RangeSum() function.
Summary: You can create any auto-incrementing counter in a QlikView script. Just choose your counter function…
For Qlik Sense 2.1, the Qlik Dev Hub, accessible at https://<ServerName>/dev-hub/ , replaces the Qlik Sense Workbench, formerly accessed by https://<ServerName>/workbench/ (this will now redirect you to the Dev Hub). In addition to a brand new user interface layout, the Dev Hub has a couple of new features worth mentioning.
The new user interface has a sleek dark color design, and its layout more closely resembles the Qlik Sense client than its predecessor. The top nav bar has a drop-down menu that provides access to an “About” link, which displays information regarding the Qlik Dev Hub, and a “Help” link, which brings up helpful documentation in a new browser window. There’s an added search functionality also included on the top nav bar which lets you search through your mashups and extensions, which is really useful as your number of them grows. A second nav bar allows filter by “Mashups” or “Visualization extensions.” There is also a “Create new” button that lets you jump right into creating a mashup or extension.
A left-aligned nav bar allows you to choose from “Single configurator,” “Extension editor,” “Mashup editor,” or “Engine API Explorer.” The “Single Configurator” was previously not accessible from the Qlik Sense Workbench, and its inclusion in the Qlik Dev Hub is very convenient. The “Engine API Explorer” was previously known as the “Protocol tester” and has a new look to match the Dev Hub.
The “Mashup editor” has a couple new features. There are now menus on the left and right of the main work area which can be toggled to make the main work area larger. An added feature I’m very fond of is the ability to create new files for your mashup right from the top nav bar. The “Preview” tab has been improved, and you can now interact with your mashup in addition to dragging and dropping charts, which is a nice improvement because formerly if you had off-canvas chart areas, there was no way to access them to drag and drop charts.
The Qlik Dev Hub comes with quite a few new templates for both mashups and visualization extensions. I highly suggest you try some of these out, I think you’ll be amazed at how quickly you can put together a decent mashup, even with little to no web development skills. Steps below -
1) Navigate to the Qlik Dev Hub, click on the “Create new” button, give your mashup a name, and select either “Basic single page mashup” or “Slideshow mashup” from the dropdown menu.
2) Click the “Create and edit” button and this will open up your mashup in the “Mashup editor” for you.
3) Select an app from the dropdown menu in the left nav, and start dragging and dropping charts into the chart areas.
4) Customize as much as you want by modifying the auto-generated HTML and JS files
I’m going to include a few links to documentation below. If you haven’t tried the new Qlik Dev Hub yet, you should definitely check it out.
In the QlikCommunity forum I have often seen people claim that you should minimize the number of hops in your Qlik data model in order to get the best performance.
I claim that this recommendation is not (always) correct.
In most cases, you do not need to minimize the number of hops since it affects performance only marginally. This post will try to explain when an additional table significantly will affect performance and when it will not.
The problem is which data model to choose:
The question is: Should you normalize and have many tables, with several hops between the dimension table and the fact table? Or should you join the tables to remove hops?
So, I ran a test where I measured the calculation time of a pivot table calculating a simple sum in a large fact table and using a low-cardinality dimension, while varying the number of hops between the two. The graph below shows the result. I ran two series of tests, one where the cardinality of the dimensional tables changed with a factor 10 for each table; and one where it changed with a factor 2.
You can clearly see that the performance is not affected at all by the number of hops – at least not between 0 and 3 hops.
By 4 hops, the calculation time in the 10x series however starts to increase slightly and by 5 hops it has increased a lot. But this is not due to the number of hops. Instead, it is the result of the primary dimension table (the dim table closest to the fact table) getting large: By 5 hops it has 100.000 records and can no longer be regarded as a small table.
To show this, I made a second test: I measured the calculation time of the same pivot table using a fix 3-table data model, varying the number of records in the intermediate table, but keeping the sizes of the other tables.
In real life, this structure would correspond to a part of a more complex data model, e.g.
The result of my measurement can be seen in the red bars below:
The graph confirms that the size of the intermediate table is a sensitive point: If it has 10.000 records or less, its existence hardly affects performance. But if it is larger, you get a performance hit.
I also measured the calculation times after joining the intermediate table, first to the left with the fact table, and then to the right with the dimension table, to see if the calculation times decreased (blue and green bars). You can see that joining tables with 10.000 records or less, does not change the performance. But if you have larger tables, a join with the fact table may be a good idea.
Conclusions:
PS. A couple of disclaimers:
Further reading related to this topic:
Dear Qlik users,
We are proud to announce that our connectivity team have released the latest version of the Qlik Connector for SAP, version 6.1. The new connector for BEx and SQL Connector included in 6.1 are based on a new Windows framework. In addition, a new SalesForce connector has also been released, Qlik SalesForce Connector 13.10. The new SalesForce connector supports SalesForce's TLS 1.1 and 1.2.
Both of these new connectors are now available on our download site.
Please read the associated release notes for the new connectors before any installing any new software.
Thank you for choosing Qlik software!
regards,
Global Support Team
Every time you click, the Qlik engine recalculates everything.
Everything.
A new selection implies a new situation: Other field values than before are possible; other summations need to be made; the charts and the KPIs get other values than before. The state vectors and the objects are invalidated. Everything needs to be recalculated since this is what the user demands.
Well, there is of course a cache also – so that the Qlik engine doesn’t have to recalculate something which has been calculated before. So it isn’t quite true that everything is recalculated: If a calculation has been made before, the result is simply fetched from the cache. But it is true that nothing is pre-calculated. There is no need for that. Everything can be done in real-time.
The Qlik engine is an on-demand calculation engine.
From a principal point, there are two steps in the recalculation of data: The logical inference in the data model, and the calculations of all objects, including sheet labels and alerts.
The logical inference is done first. The goal is to figure out which field values in the symbol tables are possible and which records in the data tables are possible, given the new selection. There is no number crunching involved - it is a purely logical process. The result is stored in the state vectors.
Think of it as if the selection propagates from one table in the data model to all other tables. Table after table is evaluated and the Qlik engine figures out which values and records are possible, and which are excluded.
When the logical inference is done, the Qlik engine starts to evaluate all exposed objects. List boxes and dimensions in charts must be populated and sorted. All expressions – in charts, in text boxes, in labels, in alerts – must be calculated. Objects that are on other sheets, minimized or hidden, are however not calculated.
The calculations are always aggregations based on the data records that have been marked as possible by the logical inference engine. I.e., the objects do not persist any data on their own.
The calculation phase is usually the phase that takes time – often over 90% of the response time is due to calculations. The calculations are asynchronous and multi-threaded on several levels: First of all, every object is calculated in its own thread. Secondly, in the 64-bit version, many aggregations e.g. Sum() are calculated using several threads, so that a sum in one single object can be calculated quickly using several CPUs.
Finally, when an object has been calculated, it is rendered. Since the calculation is asynchronous and multi-threaded, some objects are rendered long before other objects are ready.
And when an object has been rendered, you can click again. And everything is repeated.
PS. All of the above is of course true for both QlikView and Qlik Sense. Both use the same engine.
If you want to read more about the Qlik engine internals, see
Symbol Tables and Bit-Stuffed Pointers
The Qlik Continuous Classroom is a new 24/7 self-service distance learning platform for Qlik Sense!
Innovative customized role-based curriculum, courses, and delivery accelerates the power of Qlik to customers around the world!
Qlik now provides users with a new way to learn that allows them to completely customize their learning journey based on their individual needs. Users can choose from dozens of modules equivalent to approximately 25 hours of work, with topics ranging from “Foundations of Building Visualizations” to ”Build and Play Stories”.
Learner-centric Distance Training Boosts Productivity with Qlik
The Qlik Continuous Classroom education package includes innovative offerings, such as:
More Information and Availability
Qlik Continuous Classroom is a subscription-based, self-service learning platform for Qlik Sense that can either be used on its own or supplemented by instructor-led courses. Users will have the option to preview videos prior to purchase. Today, customers and partners can purchase the Qlik Sense Business Analyst role, with additional roles to be added in the future. For more information and to try the platform for free, please visit http://qcc.qlik.com.
Check out the Qlik Continuous Classroom Video
I often see incorrect expressions being used in the QlikCommunity forum. Expressions that seem to work correctly – but really don’t…
So, let me make this clear: Calculations in QlikView are aggregations.
It doesn’t matter if it is a measure in a chart, or a calculated object label, or a show condition for an object, or a calculated color, or an expression search – all expressions in the user interface are evaluated as aggregations. (Except calculated dimensions, and some search strings.)
This means that it is correct to use the Sum() function in an expression, since this is an aggregation function - a function that uses several records as input. But if you omit the aggregation function or use a scalar function only, e.g. RangeSum(), you can get an unexpected behavior.
Basically, all field references should be wrapped in an aggregation function. The Aggr() function and some constructions using the total qualifier can even have several layers of aggregations.
But if the created expression does not contain an aggregation function, the expression is ill-formed and potentially incorrect.
Examples:
=Sum(Amount)
=Count(OrderID)
These are both correct aggregations. Amount is wrapped in the Sum() function which will sum several records of the field Amount. OrderID is wrapped in the Count() function, which will count the records where OrderID has a value.
=Only(OrderID)
This is also a correct aggregation. OrderID is wrapped in the Only() function, which will return the OrderID if there is only one value, otherwise NULL.
=OrderID
A single field reference is not an aggregation, so this is an ill-formed expression. But QlikView will not throw an error. Instead it will use the Only() function to interpret the field reference. I.e., if there is only one value, this value will be used. But if there are several possible values, NULL will be used. So, it depends on the circumstances whether an expression without aggregation function is correct or not.
=If(Year=Year(Today()), Sum(Amount1), Sum(Amount2))
Here, both the amounts are correctly wrapped in the Sum() function. But the first parameter of the if() function, the condition, is not. Hence, this is an ill-formed expression. If it is used in a place where there are several possible Years, the field reference will evaluate to NULL and the condition will be evaluated as FALSE, which is not what you want. Instead, you probably want to wrap the Year in the Min() or Max() function.
=ProductGroup= 'Shoes'
=IsNull(ProductGroup)
These expressions can both be used as show conditions or as advanced searches. However, since there are no aggregation functions, the expressions are ill-formed. If you want to test whether there exists Shoes or NULL values among the field values, you probably want to use the following instead:
=Count(If(ProductGroup= 'Shoes', ProductGroup))>0
=NullCount(ProductGroup)>0
Conclusions:
Further reading related to this topic:
Hello Qlik Community! - I am pleased to announce the availability of Qlik Sense 2.1. Our third and final release in the Qlik Sense product family this year. With this release, Qlik is continuing its commitment to helping organizations use analytics to see the whole story that lives within their data. Version 2.1 provides the most complete Qlik Sense experience to date and allows customers to explore, create and collaborate with greater simplicity by taking advantage of Qlik’s unique associative model.
Allow me to summarize some of the new feature highlights in this release:
There is of course much more including additional user experience features and even new Qlik DataMarket Topical Packages. These premium subscription packages include 180 currencies and weather data for 2600 cities.
Now....enough reading and get to watching! The below New Feature video summarizes these highlights and then will link you to other videos to demonstrate and briefly show you how to use these new features.
Note:
Regards,
Michael Tarallo
Senior Product Marketing Manager
Qlik
@mtarallo
Qlik Sense 2.1 New Features Presentation
Other videos worth watching:
Dear Qlik Sense users,
We are pleased to announce that the latest release on the Qlik Sense 2.0 Service Release track is now available on our download site. Service Release 2.0.4 includes several bug fixes, details of which can be found in the attached release notes.
Please note as this is purely a Service Release, there is no new functionality included. Thanks for choosing Qlik software, please don't hesitate to contact Qlik Support if you have any questions or need help.
kind regards
Global Support Team
Hello Qlik Users!
Effective October 1, 2015, Qlik will no longer sell the QlikView Expressor product and all renewal activity will cease. Customers may continue to use Expressor, but maintenance and support services will cease on May 31, 2016 in accordance with our current maintenance and support policy.
All outstanding Expressor quotes, which have been approved as of October 1, will be honored. However, for prospects interested in the capabilities offered by Expressor, our guidance is to instead direct those prospects to alternate Qlik partner-based solutions such as Alteryx or Lavastorm.
For the small number of existing maintenance and support contracts, which terminate after May, 2016, those support contracts will be honored through the end of the contract term.
Any individual customer contractual licensing and pricing obligations in effect beyond October 1, 2015 for Expressor will also be honored. However, the same guidance to steer customers to partner-based solutions is applicable.
Existing Customers with a renewal date later than October 1st has individually been notified via email.
Regards,
/Global Support Team
One of the great features in Qlik Sense is the Smart Search capabilities. Smart Search allows you to search the data in your app when you are on a sheet. All you have to do is select the Smart Search icon on the selection bar and type what you want to search for. In the image below I start typing “fresh vegetables” and data that matches “fresh” or “ve” (the start of the word “vegetables”) is displayed. From here, I can select one of the items found if it is what I am looking for. I will select “Fresh Vegetables” in the Product Sub Group Desc field and this selection will be added to the selection bar.
One thing I should note is that I did not use quotes when I searched for “Fresh Vegetables” so “fresh” and “vegetables” were interpreted as separate search terms. If I use quotes, my search returns less results (seen in the image below) because my search term was more specific and considered one search term versus two.
Now if I want to perform another search, I can do so and it will automatically search within my selections which is Fresh Vegetables. If I search for broccoli, all possible data will be displayed within my Fresh Vegetables selection.
Now say I search for something that is not within my Fresh Vegetable selection like apple. I will be given a message indicating that no matches were found and will be prompted to start a new search for only apple if I chose. If I select the “Start a new search …” button, then my Fresh Vegetables selection will be de-selected before the search begins.
By default, Smart Search searches all fields in the data model but you have the option to set what fields you would like to include or exclude in the Smart Search. This can be done in the script by using the Search Include or Search Exclude statements:
Search Include * fieldlist
Search Exclude * fieldlist
Fieldlist is a comma separated list of the fields that should be included or excluded in the search. The Search Include statement is used to indicate which field(s) should be searched when performing a search. In some apps, there may be several fields that the user may not need to search. In that case, it is smart to use the Search Include to narrow down the list of fields to search. This can help with the performance of the search as well. The Search Exclude statement is used to indicate which field(s) should not be used in the search. This may be used to exclude ID or key fields that were used to build the data model but that the user does not need to search. In both statements, wildcard characters * and ? can be used. Just to show you how this works, if I add the Search Exclude statement below to my script and reload, it will exclude all values in the “Line Desc 1” field when a search is being performed.
In the Master Items, the “Line Desc 1” field is added as a Dimension named Product. When I performed the search earlier, broccoli results were found in the Product dimension. Now watch what happens when I do another search for Broccoli within my Fresh Vegetables selection. Broccoli does not come up in my search results because the exclude statement does not allow a search in the “Line Desc 1” field/Product dimension.
Smart Search provides an easy way for users to find the data they are looking for to filter their data. The Search Include and Search Exclude statements offer the developer a way to control the fields that can be searched. This can improve performance and it can make it easier for the user to focus on the fields that are most relevant. Keep these statements in mind the next time you are developing an app. It will improve the users search experience.
Thanks,
Jennell
Hi Qlik users!
We are very pleased to announce two releases today.
Qlik Sense 2.1
The latest Feature Release for Qlik Sense is now available, Qlik Sense build 2.1.1 which introduces some exciting new features:
For Qlik Sense System Requirements please see:
Qlik DataMarket
We have introduced our first topical packages:
Visit our download site for installation files and release notes. Thank you for choosing Qlik software!
regards,
Global Support Team
With QlikView 4 and QlikView 5 we reached a much larger audience than before. We now had large enterprise customers that had demands on the product that we didn’t quite satisfactory fulfill: The demands were around Security, Distribution and Workflow.
As a result, one large Swedish customer developed their own system to administrate QlikView: They developed software that used the QlikView COM Automation interface to update and distribute QlikView documents. They showed it to us and we were impressed – so impressed that we bought the code to develop it further.
As a result, we could in 2001 release the QlikView Administrator.
The Administrator had three basic components:
The Factory’s tasks were to update the QlikView documents and distribute them in a secure way. On the portal, the users could either download the documents for off-line use or connect to the documents using QlikWeb – which was the name of our server at the time. Finally, the administration panel was used to set the rules for how and when the updates should be made and to whom the documents should be distributed.
The Administrator was the basic workflow tool that our enterprise customers demanded. It contained tasks, scheduling, data reduction, document categorization, document distribution and it also set the user rights per document. So it covered all the basic needs.
The administration panel for Administrator version 1
The name was not quite good, so we renamed it “QlikView Publisher”. We also improved the UI and the functionality and when we released version 2 a few years later, it was much richer in features and much more usable.
The administration panel for Publisher version 2
Initially, it was developed in Visual basic 6, but we soon were looking for a more modern development tool and today it is developed in C#.
The version numbers were not in sync with QlikView until QlikView 8. Before that, the Publisher had its own numbering. For QlikView 9 the QlikView Server and the QlikView Publisher were completely merged, with a common management console and a common installation. This also means that some of the original Publisher features became available also without a Publisher license, e.g. the reload of a document.
Although very much has changed since the first Publisher version, the basic concepts for the Publisher remain the same: Security, Distribution and Workflow.
Today, the Publisher is a mature workflow tool that allows our customers to manage the distribution of information both to off-line and on-line users. It can connect to a large number of directory services; it can be integrated with almost any authentication system and it can use either Windows integrated authorization or the QlikView internal authorization. It can take a master document, refresh it, reduce it so that the user only gets its own data and finally distribute it in any way the administrator wants it. It is an absolute necessity for a company with enterprise demands on security and data governance.
Qlik Sense Workbench is a development toolbox used for building solutions with Qlik Sense. It includes JavaScript API libraries used for building Qlik Sense visualizations or for building mashup websites with Qlik Sense content.
Qlik Sense Workbench provides developers with a quick start for creating custom visualizations and mashup websites, including code samples and templates for creating different types of visualizations as well as templates for creating basic mashup websites. Those templates constitute in fact the perfect starting point for your next mashup project.
Qlik Sense Workbench provides three JavaScript APIs for building extensions and mashups. The Extensions API for building visualizations, the Mashups API for building mashups websites, and the Backend API for communicating with the Qlik Sense engine.
The good news is Workbench doesn't have a separate installation package, so if you already have Qlik Sense Server or Desktop you have Workbench working.
To launch Qlik Sense Workbench open a web browser and type in the URL https://ServerName/workbench/ . If you are a Qlik Sense Desktop user, make sure it is running and do the following, open a web browser and type in the URL http://localhost:4848/workbench/ et voila!
To reply to that question I leave you with a 5 min video that will walk you through the mashup creation process.
Enjoy!
AMZ
PS: Remember you can find lots of useful videos, howtos and tutorials at the Qlik Youtube channel
Check out a step by step tutorial here: Creating a webpage based on the Qlik Sense Desktop Mashup API
There are no data types in QlikView.
This is not a limitation – it is a conscious design decision.
One of the initial requirements of QlikView was that it should be possible to mix data from different sources: We wanted users to be able to have a data model with some data from a database, some from an Excel sheet, and some from a comma delimited text file. Some of these sources have proper data types, others don’t. So relying on the data types of the data source would be difficult. Further, we wanted the internal functions to be able to always return a relevant calculation – there must never be any type of conversion problems. We wanted simplicity for the user.
Enter the Dual format.
The dual format is a brilliantly simple solution to the above requirements: Its core is that every field value has two values – one string that is displayed, and one number that is used for sorting and calculations. The two values are inseparable; they are like the two sides of a single coin. They are both needed to describe the field value properly.
For example, months have the string values ‘Jan; ‘Feb’ … ‘Dec’, which are displayed. At the same time they have numeric values 1 to 12, which are used for sorting. Similarly, weekdays have the string values ‘Mon’; ‘Tue’ … ‘Sun’ and at the same time the numeric values 0 to 6.
Dates and times have string values that look like dates, e.g. ‘12/31/2011’ or ‘06.06.1944 06:30’ and at the same time they have numeric values corresponding to the number of days since Dec 30 1899. As I write this, the (numeric) time is 41215.6971. How months, weekdays, dates and times should be displayed is defined in the environment variables in the beginning of the script.
This way QlikView can sort months, days and dates numerically, or calculate the difference between two dates. Numbers can be formatted in arbitrary ways. In essence, QlikView can have data that is much more complex than plain strings.
When dual values are used as parameters inside QlikView functions, the function always uses just one of the two representations. If a string is expected, as in the first parameter of Left(s,n), the string representation is used. And if a number is expected, as in the Month(date) function, the number representation is used.
QlikView functions all return dual values, when possible. Even the color functions do, see table. However, string functions, e.g. Left(s,n), is the exception; because they don’t have a number that can be associated with the string, they leave the number part of the dual empty.
Finally, there is of course a function with which you can create your own dual values: Dual(s,n). With it you can create any combination of string and number. Use it if you want to assign a sort order to strings or if you want to assign text to numeric values.
Here is how one of the top contributors of QlikCommunity uses duals for Booleans: Rob Wunderlich’s Dual flags.
Further reading related to this topic:
I am sure that I am not the only one who has added a filter pane to their Qlik Sense app and found a combination of strings and numbers when you were expecting all numeric data. This happened to me recently when I was building an app that had many data sources. I was loading a year field from each of the data sources but I soon realized that the data I was loading was not always numeric. So when I added a filter pane to my app and added the dimension year, I ended up with a list like the image below (on the left). Some of the years were left-aligned and some were right-aligned.
One of my data sources had years from 2000 to 2012 which were loading as strings (left-aligned) while my other data source had years from 1990 to 2014 that were right-aligned. My obvious problem is I want each year listed once and to be consistent across all my data sources so that when a user wants to select 2010, they do not have to select both the string and numeric representation of the year.
Part of the script that loaded these files looked like this:
After some testing I realized that the second table shown above, Consumptionhousehold, was where the string year values were coming from. I did not generate the QVD being used for this app but I have found that sometimes numeric values are loaded as strings if there are additional characters in the original field. For instance, in Excel, a year column may be stored as text if there is a leading single quote. If you look at the image below, you can see that the year in column A is stored as text because it starts with a single quote (‘2015). In column B, the year is numeric because it is just numbers. When both these values are loaded into Qlik Sense, they are evaluated differently and can lead to problems.
To resolve this issue I modified my script to evaluate the string year as a date by using the Date# function and then I added the format parameter (‘YYYY’) to indicate how the year is formatted (see image below). Going forward, I added this modification to my script every time I loaded year just to be on the safe side. You can read more about the Date function in blog titled The Date Function.
Once this modification was made I ended up with a list of years from 1990 to 2014 and they were all right-aligned and listed only once.
While this is a small problem, it can cause confusion when you are building an app especially if you do not realize it has happened. I noticed the issue because I added a filter pane to my app but had I not done that and tried to use the year field in a chart or in set analysis, my results would have been incorrect. The lesson I took from this is to always check to make sure that the data I am loading is loading as expected. I can easily test this by adding filter panes to my app or looking at the data model viewer to ensure that everything is loaded as planned. Good luck scripting.
Thanks,
Jennell
Hello Qlik Community Members,
We have just completed some updates we think you will find useful.
The categories on our Qlik Community Index page have been revised to provide easier navigation. The new categories are:
Under General you can find areas which are not product specific - such as Community Information, Education Services, Technical Blogs and Groups.
We have also added two resource areas on the top right of the home page highlighting:
We will adding more getting started resources over the coming weeks to help new members learn best practices like where and how to post their questions. We hope you like the updates.
If you have a recommendation for resource materials, please contact sara.leslie@qlik.com.
-The Qlik Community Team
As I was working on an app that displays live data, I was called to display the time when the QVF was created. In Qlik Sense we have the function ReloadTime(), but how do we call that in our script from the API and how do we display that based on our region since, our server may very well be in another one?
In an earlier post, I showed how do connect to our app with qsocks and the Engine API Engine API and qSocks - Connecting and getting a list of available apps
After we establish our connection and create the session, we will create our HyperQube of a simple ListObject.
var obj = {
"qInfo": {
"qId": "LB02",
"qType": "ListObject"
},
"qListObjectDef": {
"qStateName": "$",
"qDef": {
"qFieldDefs": [
"Round"
],
"qFieldLabels": [
"Round"
],
"qSortCriterias": [{
"qSortByExpression": -1,
"qExpression": {
"qv": ""
}
}]
},
"qInitialDataFetch": [{
"qTop": 0,
"qLeft": 0,
"qHeight": 100,
"qWidth": 2
}]
}
This only returns one field, in this case the "Round". In order to get the time we will need to create an expression and get it as a second field. So we add right after "qInitialDataFetch"
,
"qExpressions": [{
"qExpr": "=ReloadTime()"
}]
So now we can create our session and grab all of the fields. For now, we will just focus on the time so here we will take it from the array returned and store it in a global variable reloadTime.
qsocks.Connect(app.config).then(function(global) {
global.openDoc(id).then(function(app) {
app.createSessionObject(obj).then(function(list) {
list.getLayout().then(function(layout) {
reloadTime = layout.qListObject.qDataPages[0].qMatrix[0][1].qText;
});
});
});
});
Now we need to display this on our page but based on the timezone of the user.
First we need to create the returned date as a javascript date so we can work with it,
var lastReloadTime = new Date(reloadTime);
Get the time server/user time difference in hours.
var timeDiff = lastReloadTime.getTimezoneOffset() / 60;
Now set the time to the users time.
lastReloadTime.setHours(lastReloadTime.getHours() - timeDiff);
Finally Display it.
$('#lastReloadTime').html('LAST UPDATE: ' + lastReloadTime.toLocaleTimeString());