172 lines
7.1 KiB
Markdown
172 lines
7.1 KiB
Markdown
---
|
|
name: qvw-preserve-interface
|
|
description: >
|
|
Protect QVW interface edits (sheets, tableboxes, charts, listboxes) from being
|
|
destroyed by reload-save cycles. Sets up local git tracking of the -prj/ folder,
|
|
enables QlikView's native auto-backup, installs a rolling 20-slot QVW backup,
|
|
and wraps the reload BAT with pre/post-reload git commits so every interface
|
|
edit is recoverable even if the QVW binary gets clobbered. Use this skill when
|
|
the user says "my interface disappeared", "reload overwrote my edits",
|
|
"protect my QVW objects", "version-control the QlikView app",
|
|
"set up git for the QVW project", or mentions losing tableboxes/charts
|
|
after a reload. Also apply proactively when scaffolding any new QVW project
|
|
that will be reloaded repeatedly. Uses the COM GetProperties/SetProperties
|
|
pattern (NOT SetScript — which doesn't exist on modern QV Document).
|
|
---
|
|
|
|
# QVW Interface Preservation (git-backed)
|
|
|
|
You are setting up a git-based safety net for QlikView Desktop projects so
|
|
that **every interface edit survives reload cycles**. Without this, QV's
|
|
default behaviour can silently drop charts/tableboxes whose source fields
|
|
change during a reload.
|
|
|
|
## Why this is needed (the failure mode)
|
|
|
|
1. User opens `app.qvw` in QlikView, adds a tablebox or chart, saves.
|
|
2. Reload BAT fires (`qv.exe /r app.qvw`) — QV re-executes the script,
|
|
which may rename/drop fields, then saves.
|
|
3. Objects referencing dropped/renamed fields are **silently removed** from
|
|
the saved `.qvw` binary.
|
|
4. QV's native ring-buffer backup (`BackupKeepCopies=4` by default) gets
|
|
evicted within a day of reload cycles → user's edit is **unrecoverable**.
|
|
|
|
The fix: put every `-prj/` XML under git **before** each reload.
|
|
|
|
## Step 1: Gather inputs
|
|
|
|
Ask the user for:
|
|
1. **Project root** — e.g. `C:\Users\...\MyProject\`. Must contain the QVW and the
|
|
reload BAT.
|
|
2. **QVW filename** — e.g. `MyProject_v3.qvw`. (If multiple QVWs, ask which one.)
|
|
3. **Reload BAT filename** — e.g. `Reload_MyProject.bat`. (Often in `8.BAT\`.)
|
|
|
|
Read the project layout to confirm those exist before proceeding.
|
|
|
|
## Step 2: Enable QlikView's native auto-backup
|
|
|
|
Check `%APPDATA%\QlikTech\QlikView\Settings.ini` for these keys:
|
|
```ini
|
|
[Settings 7]
|
|
BackupBeforeReload=1
|
|
BackupEnable=1
|
|
BackupKeepCopies=4 ; QV default; user can raise
|
|
AlwaysGenerateProject=1 ; required so -prj/ is populated on save
|
|
```
|
|
If any are missing, add them. Explain to the user that
|
|
`AlwaysGenerateProject=1` is essential — without it the `-prj/` folder
|
|
doesn't get the XML files that git tracks.
|
|
|
|
## Step 3: Initialize git in the project root
|
|
|
|
```bash
|
|
cd <PROJECT_ROOT>
|
|
git init
|
|
git config user.email "<user email>"
|
|
git config user.name "<user name>"
|
|
```
|
|
|
|
## Step 4: Write the `.gitignore`
|
|
|
|
Critical: **Windows git is case-insensitive by default**, so `*.qvw` would
|
|
match the folder `4.Apps.QVW/` and ignore everything inside it (including
|
|
the precious `-prj/` subfolders). Use the `.gitignore` template
|
|
`templates/.gitignore` from this skill, which has the case-insensitive fix:
|
|
|
|
- Ignores `**/*.qvw`, `**/*.qvf`, `**/*.qvd`, `**/*.qvw.bak*` (actual binary files)
|
|
- Ignores `/4.Apps.QVW/backups/**` and `/4.Apps.QVW/_recovery/**`
|
|
- **Re-includes** `/4.Apps.QVW/**/*-prj/` and its contents (the `!` rules come
|
|
AFTER the ignore rules)
|
|
- Ignores logs, `.DS_Store`, `Thumbs.db`, `*.tmp`
|
|
- Ignores `4.Apps.QVW/Version * of *` (QV's native backup files, too big)
|
|
|
|
Copy the template to `<PROJECT_ROOT>/.gitignore` and adapt paths if the
|
|
project doesn't follow the QQinfo `4.Apps.QVW/` convention — ask the user.
|
|
|
|
## Step 5: Install `Backup_QVW.ps1` (rolling buffer)
|
|
|
|
Copy `templates/Backup_QVW.ps1` into `<PROJECT_ROOT>/8.BAT/` (or wherever
|
|
BATs live). Default retention is **20 slots** (parameter `-Keep`), so a day
|
|
of reloads can't evict a good edit. This runs BEFORE each reload as a
|
|
fallback safety net in case git isn't enough (e.g. if the user forgot
|
|
to enable `AlwaysGenerateProject`).
|
|
|
|
## Step 6: Wrap the reload BAT with git commits
|
|
|
|
The reload BAT must do, in order:
|
|
1. **Pre-reload `git add -A && git commit`** — captures whatever manual
|
|
edits the user made since the last reload.
|
|
2. Backup QVW to rolling buffer (`Backup_QVW.ps1 -Keep 20`).
|
|
3. `qv.exe /r <APP_PATH>` — the actual reload.
|
|
4. **Post-reload `git add -A && git commit`** — captures script-side
|
|
changes so you can diff "user edits" vs "reload output".
|
|
|
|
Use the template `templates/Reload_wrapped.bat`. Substitute:
|
|
- `%PROJECT_ROOT%` — the project root
|
|
- `%APP_PATH%` — the QVW to reload
|
|
- `%LOG_FILE%` — where to append reload log (usually `10.QQlog\`)
|
|
|
|
Warn user: all `git commit` commands use `--allow-empty` so they never
|
|
fail even when nothing changed.
|
|
|
|
## Step 7: Changing the script include path (if needed)
|
|
|
|
If the QVW's embedded script points at an old `9.QVSvN` folder and needs
|
|
to target a new one (e.g. during a version bump), use COM script
|
|
injection via `GetProperties / SetProperties`. The legacy `SetScript()`
|
|
method does NOT exist on modern QV Document COM. Template at
|
|
`templates/inject_include.ps1`. Usage:
|
|
|
|
```powershell
|
|
powershell -File inject_include.ps1 `
|
|
-QvwPath "C:\path\to\app.qvw" `
|
|
-NewInclude "C:\path\to\9.QVSv9\0100.MustInclude.qvs"
|
|
```
|
|
|
|
The script calls `$doc.GetProperties()` → sets `.Script` → `$doc.SetProperties($props)` → `.Save()`.
|
|
|
|
## Step 8: Make the initial commit
|
|
|
|
```bash
|
|
cd <PROJECT_ROOT>
|
|
git add -A
|
|
git commit -m "Initial commit: QVS/config/-prj tracked; binaries excluded"
|
|
git tag initial
|
|
```
|
|
|
|
Then verify with `git log --oneline` and confirm the `-prj/*.xml` files
|
|
made it into the commit (not just `.qvs`/`.csv`). Run
|
|
`git check-ignore -v 4.Apps.QVW/<app>-prj/TB01.xml` to confirm NOT ignored.
|
|
|
|
## Step 9: Tell the user what to do when disaster strikes
|
|
|
|
If a reload destroys an object:
|
|
1. `git log --oneline --all -- 4.Apps.QVW/<app>-prj/` — find the last
|
|
commit that had it.
|
|
2. `git show <commit>:4.Apps.QVW/<app>-prj/TB05.xml` — recover the XML.
|
|
3. Paste the XML back into the `-prj/` folder and "Import from project"
|
|
in QlikView, OR restore the whole QVW from the rolling buffer:
|
|
`cp 4.Apps.QVW/backups/<name>_<ts>.qvw 4.Apps.QVW/<name>.qvw`.
|
|
|
|
## Step 10: Post-install verification
|
|
|
|
Run the reload BAT once end-to-end. Confirm:
|
|
- Two new git commits appear (`pre-reload` + `post-reload`).
|
|
- A new `.qvw` lands in `4.Apps.QVW/backups/`.
|
|
- The `-prj/` folder is populated with fresh XML timestamps.
|
|
- `git check-ignore -v` on any `-prj/*.xml` returns empty (NOT ignored).
|
|
|
|
If any of those fail, diagnose before declaring success.
|
|
|
|
## Common gotchas
|
|
|
|
- **Filename with spaces/typos** (e.g. `QQpo_v2 inerface preps.qvw`) — QV COM
|
|
`OpenDoc` returns null silently. Rename to a clean path before scripting.
|
|
- **`.qvw.bak.qvf`** is QV's native one-off backup (same content, renamed).
|
|
Safe to keep — gitignore already excludes.
|
|
- **`Version N of <app>.qvw`** — also QV native backups. Gitignored.
|
|
- **Tableboxes in "show all fields of table" mode** self-heal after field
|
|
renames. Tableboxes with explicit field lists do NOT — user has to re-edit.
|
|
- **Branch protection** — the local-only setup has no remote by design.
|
|
If the user wants off-site backup, run `git remote add origin ...` as a
|
|
follow-up step (Gitea / GitHub / Forgejo).
|