qvw-preserve-interface/templates/populate_tablebox.ps1

97 lines
3.4 KiB
PowerShell

# populate_tablebox.ps1 — create a new sheet with a populated TableBox on a QVW.
#
# IMPORTANT: use TableBox.AddField($fieldName) — NOT TableBoxProperties.Fields.Add()
# (which fails on modern QV Document COM with "null-valued expression").
#
# Usage:
# powershell -File populate_tablebox.ps1 `
# -QvwPath "C:\path\to\app.qvw" `
# -SheetName "Cash Flow (v9)" `
# -Fields @("%ProdPODateKey","cf_category","cf_payment_date","cf_amount_ron","ext_supplier_code")
#
# The sheet is CREATED if it doesn't match `$SheetName` (case-insensitive substring).
# A fresh TableBox is always created on the sheet. Existing TBs are NOT deleted —
# pass -ReplaceExisting $true to remove old TBs on the sheet first.
param(
[Parameter(Mandatory=$true)][string]$QvwPath,
[Parameter(Mandatory=$true)][string]$SheetName,
[Parameter(Mandatory=$true)][string[]]$Fields,
[bool]$ReplaceExisting = $false
)
$ErrorActionPreference = "Continue"
if (-not (Test-Path $QvwPath)) { throw "QVW not found: $QvwPath" }
$qv = New-Object -ComObject QlikTech.QlikView
$doc = $qv.OpenDoc($QvwPath, "", "")
if (-not $doc) { throw "OpenDoc returned null for $QvwPath" }
Start-Sleep -Seconds 2
# Find or create the sheet
$targetSheet = $null
$targetSheetId = $null
for ($i=0; $i -lt $doc.NoOfSheets(); $i++) {
$s = $doc.GetSheet($i)
$sp = $s.GetProperties()
$nm = $null
try { $nm = $sp.Name } catch { try { $nm = $sp.Name.v } catch {} }
if ($nm -and ($nm -like "*$SheetName*" -or $nm -eq $SheetName)) {
$targetSheet = $s
$targetSheetId = $sp.SheetId
Write-Host "sheet exists: $nm (id=$targetSheetId)"
break
}
}
if (-not $targetSheet) {
$targetSheet = $doc.CreateSheet()
$sp = $targetSheet.GetProperties()
try { $sp.Name = $SheetName } catch { try { $sp.Name.v = $SheetName } catch {} }
$targetSheet.SetProperties($sp)
$targetSheetId = $targetSheet.GetProperties().SheetId
Write-Host "sheet created: $SheetName (id=$targetSheetId)"
}
# Optionally remove existing TBs on the sheet (reads -prj XML to find them)
if ($ReplaceExisting) {
$prjPath = [System.IO.Path]::GetDirectoryName($QvwPath) + "\" + [System.IO.Path]::GetFileNameWithoutExtension($QvwPath) + "-prj"
$prjXml = Join-Path $prjPath "QlikViewProject.xml"
if (Test-Path $prjXml) {
$xml = [xml](Get-Content $prjXml)
$sheetNode = $xml.PrjQlikViewProject.SHEETS.PrjSheetProperties | Where-Object { $_.SheetId -eq "Document\$targetSheetId" }
if ($sheetNode) {
foreach ($ch in $sheetNode.ChildObjects.PrjFrameParentDef) {
if ($ch.ObjectId -like "Document\TB*") {
$tbId = $ch.ObjectId.Replace("Document\","")
try {
$tb = $doc.GetSheetObject("Document\$tbId")
if ($tb) { $tb.Close() | Out-Null; Write-Host " - removed $tbId" }
} catch {}
}
}
}
}
}
# Create fresh tablebox
$tb = $targetSheet.CreateTableBox()
Start-Sleep -Milliseconds 400
# Populate via AddField (THIS is the working pattern)
$added = 0; $failed = @()
foreach ($f in $Fields) {
try {
$tb.AddField($f) | Out-Null
$added++
} catch {
$failed += $f
}
}
Write-Host "populated $added/$($Fields.Count) fields"
if ($failed.Count) { Write-Host "missed: $($failed -join ', ')" }
$doc.Save()
Start-Sleep -Milliseconds 500
$doc.CloseDoc()
$qv.Quit()
Write-Host "DONE"