5.5 Script Documentation, Organization & Reusable Include Files
Key Takeaways
Qlik load scripts support three comment styles: // for one line, /* */ for blocks, and REM, which comments out text up to the next semicolon.
$(Must_Include=...)stops the reload with an error if the include file is missing, while$(Include=...)fails silently.COMMENT FIELD and COMMENT TABLE statements store descriptions as data model metadata, documenting what fields mean rather than how the script works.
Tabs run left to right as one script, so organize them by purpose: settings, includes, mappings, extracts and transforms, calendar, security, and cleanup.
Shared logic such as connection setup, calendar code, or subroutines belongs in one include file so every app runs the identical version.
Why Documentation and Organization Are Tested
Qlik's blueprint lists two objectives that are easy to underestimate: "Determine the correct method to document Data Load scripts" and "Determine the correct method to perform script organization and cleansing." On a real project the load script is the only complete record of how raw sources became the model. If the next architect cannot tell why a filter exists or which tab builds the calendar, every change becomes a risk. Exam questions in this area usually ask which technique documents or organizes something correctly: a comment style, a statement, or a reuse mechanism.
1. Comment Styles in the Load Script
| Syntax | Scope | Typical use |
|---|---|---|
// text | Rest of the line | Short notes beside a field or statement |
/* text */ | Everything between the markers, across lines | Header blocks; temporarily disabling a block of code |
REM text; | Up to the next semicolon | Legacy style; comments out a whole statement |
/* ===================================================================
App: Sales_Transform (Tier 2)
Purpose: Build the conformed Fact_Sales QVD
Sources: lib://QVD_Raw/Raw_Orders.qvd
Outputs: lib://QVD_Conformed/Fact_Sales.qvd
Owner: BI Data Engineering
History: 2026-10-01 Added returns flag (ticket DA-412)
=================================================================== */
REM Legacy discount logic was retired in 2026 and is kept only in version control;
Fact_Sales:
LOAD
OrderID,
CustomerID,
// Net of discounts; returns are handled in Fact_Returns
GrossAmount - DiscountAmount AS NetAmount
FROM [lib://QVD_Raw/Raw_Orders.qvd] (qvd);
Good comments explain why: the business rule, the ticket, or the source quirk, not what the next line obviously does. A header block at the top of the first tab answers the questions a maintainer asks first: purpose, sources, outputs, owner, and change history.
Warning
REM ends at the next semicolon, not at the end of the line. A REM line without its own semicolon, placed directly above a LOAD, comments out that entire LOAD statement.
2. Organizing the Script into Tabs
Tabs run left to right as one continuous script, so their order is part of the logic. A readable layout:
| Tab | Contents |
|---|---|
| Main / Settings | System variables (DateFormat, ThousandSep), ErrorMode, environment variables |
| Includes & Subroutines | $(Must_Include=...) statements and SUB definitions that later tabs call |
| Mappings | All MAPPING LOAD tables, so later tabs can use ApplyMap() |
| Extract / Transform | One tab per subject area (Orders, Customers, Inventory) |
| Calendar | Master calendar built from the finished fact dates |
| Security | Section Access; table followed by Section Application; |
| Cleanup & QA | DROP statements, TRACE row counts, validation checks |
When Qlik stores the script as text, each tab starts with a ///$tab TabName marker, which is why exported scripts and include files often contain those lines.
3. Reusable Code: Include Files and Subroutines
Copying the same connection setup, calendar code, or cleansing logic into 30 apps guarantees that the copies drift apart. Qlik provides two reuse mechanisms.
Include files insert the text of an external script file (or, in Qlik Cloud, another script referenced with script:// and its ID) and evaluate it as script code:
// Stop the reload if the shared settings file is missing
$(Must_Include=lib://Shared_Scripts/Settings.qvs);
// Optional extras: no error if the file does not exist
$(Include=lib://Shared_Scripts/Optional_Debug.qvs);
| Variant | Missing file behavior | When to use |
|---|---|---|
$(Include=...) | Fails silently; the reload continues without that code | Truly optional code |
$(Must_Include=...) | Raises an error and stops the reload | Anything the app cannot run correctly without |
Qlik's help adds two syntax rules: do not put a space before or after the equal sign, and the form SET Include = filename is not valid.
Subroutines (SUB ... END SUB with CALL) package logic that runs several times inside one script with different parameters; Section 7.2 shows a parameterized store-feed loader. The two combine well: keep subroutine definitions in an include file, then CALL them from any app.
| Need | Best tool |
|---|---|
| The same code in many apps | Include file (preferably Must_Include) |
| The same logic many times in one script, with different inputs | SUB and CALL |
| The same value in several statements | A variable set once in the settings tab |
4. Documenting the Data Model Itself
Script comments explain how the script works, but they stay in the script. To document what fields and tables mean, Qlik provides statements that store comments and tags as metadata in the data model:
COMMENT TABLE Fact_Sales WITH 'One row per order line; net of discounts; excludes returns';
COMMENT FIELD NetAmount WITH 'GrossAmount minus DiscountAmount, in USD';
// Bulk comments from a governed data dictionary (field name -> description)
Map_FieldComments:
MAPPING LOAD FieldName, Description
FROM [lib://Governance/Field_Dictionary.xlsx] (ooxml, embedded labels, table is Fields);
COMMENT FIELDS USING Map_FieldComments;
// Custom tags classify fields, for example measures certified by finance
TAG FIELD NetAmount WITH 'Certified';
A mapping-driven COMMENT FIELDS USING statement keeps descriptions in one governed dictionary instead of scattering them through scripts, and master items add user-facing descriptions in the app itself.
5. Cleansing Belongs in a Predictable Place
The second half of the organization objective is cleansing. Keep data-quality rules in the transform tier and in clearly named steps (Trim() and Upper() on keys, null and blank normalization, date interpretation) rather than scattering fixes across front-end expressions. Section 7.2 teaches the individual functions. Organizationally, the right design applies each rule once, in one documented place, so every downstream app inherits the same fix.
6. Exam Traps
Warning
Trap 1: Include for required code. $(Include=...) hides a missing file. If the shared settings or connection script is essential, $(Must_Include=...) makes the reload fail loudly instead of producing a wrong model.
Warning
Trap 2: Treating script comments as model documentation. // and /* */ help developers reading the script; use COMMENT FIELD and COMMENT TABLE (and master item descriptions) to document what a field means.
Warning
Trap 3: Copy-paste reuse. When a scenario stresses consistency or maintenance across many apps, duplicating a calendar or cleansing block is the wrong answer; an include file or a subroutine is the right one.
Thirty apps must run an identical connection-and-variables script stored in lib://Shared_Scripts/Settings.qvs. If that file is ever missing, the reload must stop instead of continuing with default settings. Which statement should each app use?
$(Include=lib://Shared_Scripts/Settings.qvs);
$(Must_Include=lib://Shared_Scripts/Settings.qvs);
SET Include = lib://Shared_Scripts/Settings.qvs;
CALL Settings.qvs;
A data architect wants anyone inspecting the data model to see what the NetAmount field means without reading the load script. Which approach documents the field itself?
Add a // comment above the line that creates NetAmount in the LOAD statement.
Wrap the LOAD statement in a /* */ block comment that describes NetAmount.
Write a TRACE statement that prints the definition of NetAmount during every reload.
Add COMMENT FIELD NetAmount WITH 'GrossAmount minus DiscountAmount, in USD'; after the field is loaded.
A developer adds the line "REM Old discount logic" without a semicolon directly above a LOAD statement that ends with a semicolon. What happens on the next reload?
The LOAD statement becomes part of the comment and does not run, because REM comments out text up to the next semicolon.
Only the REM line is ignored; the LOAD statement below it runs normally.
The reload stops with a syntax error because REM must be written in lowercase.
REM is not supported in Qlik Sense, so the text is loaded as a field name.
Sections you finish are checked off in the contents.