Qlik to Power BI Migration Services
Most of the business logic in a Qlik estate lives in the load script and the set analysis, not in the charts. Move those two things carefully and the rest of the project is routine; rush them and the new dashboards will disagree with the old ones in front of the people who matter.
Qlik to Power BI migration services are needed because there is no converter between the two platforms. A Qlik Sense .qvf app or a QlikView .qvw document does not open in Power BI Desktop, and the parts that carry the most logic — the load script, QVD layers, set analysis expressions and section access rules — are exactly the parts that have to be rebuilt deliberately. What a migration delivers is a Power BI semantic model that replaces the Qlik data model, DAX measures that return the same numbers as the Qlik expressions, re-implemented security, rebuilt reports, and a reconciliation pass that proves it before anyone lets a Qlik subscription lapse.
This page covers moves off Qlik Sense (client-managed or Qlik Cloud) and QlikView specifically. If you are coming off Tableau instead, the workbook, extract and LOD-expression work is different enough to have its own page: Tableau to Power BI migration services. For a migration from spreadsheets or another legacy reporting platform, see business intelligence migration services.
Why a Qlik migration is a data model project first
Qlik's associative engine links tables automatically on identically named fields, and every selection filters the whole data model at once. Power BI works the other way round: relationships are declared explicitly, each one has a cardinality and a filter direction, and a model performs best as a star schema with fact tables surrounded by dimension tables. The consequence is that a Qlik data model cannot be copied across table for table — it has to be redesigned.
That redesign is where Qlik habits surface. Synthetic keys, where Qlik has silently combined several shared fields into a composite key, have to be resolved into a proper key or a bridge table. Link tables built to avoid circular references usually become conformed dimensions. Wide concatenated fact tables are often split into separate facts that share dimensions. None of this is visible on a sheet, and all of it decides whether the Power BI measures return the right numbers.
The upside is the same as any rebuild: you decide what to leave behind. Most Qlik estates contain apps nobody has opened in a year, several copies of the same sales app with slightly different scripts, and QVD layers that exist to feed one sheet. Microsoft's own migration guidance frames a migration around the business question rather than a pixel-for-pixel copy, and that is the right lens here too.
- App and document inventory — owner, usage, data sources and a migrate / merge / retire decision
- Load script analysis — every source, transformation and QVD it reads or writes
- Semantic model design — a star schema with explicit relationships in place of associative links
- Expression translation — master measures, variables and set analysis rewritten as DAX
- Section access re-implemented as row-level and object-level security
- Report rebuild, number-for-number reconciliation, a parallel run, then Qlik retirement
| In Qlik | In Power BI | What the rework usually is |
|---|---|---|
| Qlik Sense app (.qvf) or QlikView document (.qvw) | Report (.pbix) on a shared semantic model | Rebuilt — there is no importer; sheets and objects are recreated |
| QlikView sheet or Qlik Sense sheet | Report page | Redesigned around slicers, drill-through and bookmarks |
| Associative data model | Star schema with explicit relationships | Remodeled; synthetic keys and link tables resolved |
| Load script | Power Query, Dataflow Gen2 or Fabric pipeline | Translated step by step, with undocumented business rules surfaced |
| QVD file | Source re-extract, or Parquet / Delta tables in a Fabric lakehouse | Re-pointed at the source; history-only QVDs exported once and verified |
| Set analysis expression | DAX measure using CALCULATE and filter arguments | Rewritten and reconciled at more than one grain |
| Aggr() function | DAX iterator over SUMMARIZE or ADDCOLUMNS | Rewritten; subtotals verified rather than assumed |
| Master items and variables | Measures, calculation groups or field parameters | Defined once in the model instead of per app |
| Section access | RLS roles and object-level security, mapped to Entra ID groups | Re-implemented and tested for every role |
| Streams and spaces | Workspaces and Power BI apps | Re-mapped — access is granted differently |
Load scripts and QVD files: re-extract or convert
A QVD is Qlik's own storage format, and Power BI cannot read it. Every QVD therefore needs a decision. Where the QVD is simply a staged copy of a source system — the ERP, a SQL database, a CRM — the cleaner path is to re-point Power BI at that source directly, with the transformations rebuilt in Power Query or, at larger scale, in a Microsoft Fabric lakehouse or warehouse where the data lands as Delta tables stored in Parquet.
The exception matters. Some QVDs hold history that no longer exists anywhere else: nightly snapshots of inventory or open orders, or data from a system that has since been retired. Those cannot be re-extracted, so they are exported out of Qlik once — via the load script, to an open format such as CSV or Parquet where your Qlik version supports it — then loaded into the new platform and reconciled row for row before the Qlik environment is switched off.
Load script logic is translated step by step. Joins, ApplyMap lookups, incremental loads and calendar generation all have Power Query or SQL equivalents, but they are rarely written the same way, and Qlik scripts accumulated over years often contain business rules nobody has documented. Reading the script is the fastest way to find them. If the data platform itself is in scope, that work belongs in a Microsoft Fabric implementation rather than being squeezed into a migration deadline.
Set analysis becomes DAX filter context
Set analysis is where Qlik logic is densest and where translation takes the most care. An expression like Sum({<Year={2025}>} Sales) overrides the user's selection on one field; in DAX that is a CALCULATE with a filter argument on the Year column. The identifier {1}, which ignores all selections, maps to ALL or REMOVEFILTERS. Element functions such as P() and E(), and set operators that combine or exclude sets, need more thought — typically a filter table built with VALUES, TREATAS or EXCEPT.
Aggr() is the other common pain point. It builds a virtual table at a chosen grain and aggregates over it, and its DAX equivalent is usually an iterator over SUMMARIZE or ADDCOLUMNS — correct once written, but easy to get subtly wrong at subtotal level. Dollar-sign variables either become measures, calculation groups or field parameters, depending on whether they hold a value, an expression or a user choice.
Every translated measure is reconciled against Qlik output at more than one grain: the total, by period, and by the dimension the business actually slices on. A translation that matches at the grand total and drifts by customer is the most common defect in these projects, and it is far cheaper to find in testing than in a board pack.
Section access becomes row-level security
Section access does not carry across. Qlik restricts data by reducing the model per user at load time, driven by a security table in the script; Power BI enforces row-level security at query time through roles with DAX filter expressions, mapped to Microsoft Entra ID users and groups. Where section access used a reduction table keyed on region or cost centre, dynamic RLS driven by a security table in the model is usually the closest and most maintainable match.
Fields hidden with OMIT in section access map to object-level security, which hides tables or columns from roles entirely. Test the result as a matrix, not a spot check: every role verified against expected row counts with View as role in Power BI Desktop, and again in the service after publishing, because group membership behaves differently once a model is live.
What users notice when the associative model is gone
Qlik users are used to seeing green, white and grey — selected, associated and excluded values — and to clicking anywhere to filter everything. Power BI cross-filters visuals on the same page and can sync slicers across pages, but it does not show excluded values the same way, and filter direction follows the relationships in the model. Nobody should discover this on the first Monday after cutover.
Plan for it in the report design and in training. Slicer panels, drill-through pages and bookmarks cover most of what Qlik users did with free selection, and a short session on how filtering works in Power BI prevents a lot of "the numbers are wrong" tickets that are really "the filter is different" tickets. Training happens during the parallel run, while the Qlik apps are still there to compare against.
Reconciliation, the parallel run and retiring Qlik
Each rebuilt report is compared against its Qlik original with the same selections applied, at the total and at the grain the business uses. Visual differences are fine and often deliberate; numerical differences are defects until explained. A named business owner signs off each report, because a consultant cannot certify that a margin figure is right.
Both platforms then run side by side for a defined window that covers at least one full reporting cycle, month-end close included. Usage of the new reports is monitored in the Power BI admin portal so the switch is confirmed rather than assumed. Qlik is retired on a date set at the start of the project, after the last historical QVDs have been exported and verified — an open-ended parallel run just means paying for two BI platforms.
- Number-for-number reconciliation at total and at the business grain
- Named owner sign-off per report, recorded
- A parallel run spanning at least one close cycle
- Historical QVDs exported, loaded and verified before shutdown
- A fixed decommission date agreed at kickoff
How we scope and run the engagement
We start with the inventory and a read of the load scripts, because a Qlik estate cannot be estimated from the number of apps alone. An app with two sources and a handful of charts is quick; an app with a multi-tier QVD pipeline, heavy set analysis and section access is not, and the plan says so. The work then runs in waves — highest-traffic apps first — with rebuild, reconciliation and sign-off in each.
Engagements are scoped and run by Edward Pinela, MBA, Principal Consultant at Lightray Solutions; the person who reads your load scripts is the person who rebuilds the model. Most Qlik migrations are fixed-scope projects sized from the inventory. If your team is doing the migration and needs senior help with the data model, set analysis translation or RLS, Power BI Flex Support starts at $2,500 for 20 hours at $100–$125 per hour, in prepaid blocks whose hours never expire.
One honest caveat: if your Qlik estate is small, well used and not facing a renewal, migrating this year may not be worth the disruption. Bring your renewal date and a rough app count to a free call and you will get a straight answer on whether the project is worth running.
Further reading: Microsoft Learn — Power BI migration overview.
Not sure if this is the right fit?
Book a free 30-minute call with Edward Pinela, MBA. If it is not the right fit, you will be told that on the call.
Frequently asked questions
Can Qlik apps be converted to Power BI automatically?
Not in a way you should plan around. Power BI cannot open .qvf or .qvw files or read QVDs, and the logic that matters most — the load script, set analysis and section access — has to be rebuilt and verified against the original numbers. A Qlik migration is scoped as a rebuild with a known target, not a conversion.
What happens to our QVD files?
Most are replaced by connecting Power BI, or a Fabric lakehouse, directly to the source systems the QVDs were built from. QVDs that hold history which no longer exists in any source, such as daily snapshots, are exported once to an open format, loaded into the new platform and reconciled before Qlik is switched off.
How is set analysis translated into DAX?
Set modifiers become filter arguments inside CALCULATE, ignoring selections becomes ALL or REMOVEFILTERS, and more complex sets become filter tables built with functions such as VALUES, TREATAS or EXCEPT. Each translated measure is reconciled against Qlik output at the total and at the grain the business slices on, because totals can match while subtotals drift.
Do we migrate QlikView and Qlik Sense the same way?
The method is the same — inventory, model redesign, expression translation, security, reconciliation — but QlikView documents tend to carry older scripts, more embedded logic and more per-document duplication, so they usually need more consolidation. Qlik Sense apps built on shared QVD layers and master items are generally quicker to scope.
How long does a Qlik to Power BI migration take?
It depends on what survives the inventory, not on the raw app count. A small estate of well-used apps on clean sources is typically weeks; a large estate with layered QVD pipelines, heavy set analysis and section access runs for months. The parallel run adds at least one full reporting cycle on top of the build.
Will users miss Qlik's associative selections?
Some will, at first. Power BI cross-filters visuals and can sync slicers across pages, but it does not show excluded values the way Qlik does. Designing reports with clear slicer panels and drill-through, and training users during the parallel run, handles most of it.
Talk it through with a senior consultant
Book a free 30-minute call with Edward Pinela, MBA. No obligation and no sales pitch — just an honest read on whether this is the right fit.
Prefer to call? +1 (714) 872-9606