Nachtrag: Mein Splitter für AL-Pakete ist hier zu finden. Falls nur bestimmte Objekte aus dem Paket benötigt werden, kann man den C/AL-Paketkonfigurator auf das Ausgangspaket anwenden.
Zerlegt wird automatisch in den Unterordner SPLITNAVOBJ in dem Verzeichnis, wo die Ausgangsdatei liegt, dieser wird also jeweils vor dem Start gelöscht.
Am Ende des Laufs wird eine Objektstatistik angezeigt und ein Ordnerfenster mit den gesplitteten Objektdateien automatisch geöffnet. Wenn man letzteres nicht braucht, die letzte Zeile mit INVOKE-ITEM löschen. Den aktuellen Ordner als Fensteransicht aus der PowerShell heraus bekommt man übrigens am schnellsten über den Alias dieses Cmdlets mitsamt einem Punkt gestartet.
- Code: Alles auswählen
ii .
Durchaus performant, ein Testlauf mit 6569 Objekten in einer 147 MB groĂźen Datei dauert auf meinem Notebook nicht einmal eine Minute (siehe Bild).
Das Objektpaket auswählen…
…und kurze Zeit später schon erledigt .
- Code: Alles auswählen
function Split-NAVObjectFile
{
$ErrorActionPreference = "Stop"
$PSDefaultParameterValues['*:ErrorAction']='Stop'
Function Get-FileName($initialDirectory)
{
[System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") | Out-Null
$OpenFileDialog = New-Object System.Windows.Forms.OpenFileDialog
$OpenFileDialog.initialDirectory = $initialDirectory
$OpenFileDialog.filter = "NAV Object Files (*.txt)|*.txt"
$OpenFileDialog.ShowDialog() | Out-Null
$OpenFileDialog.filename
}
$inputfile = Get-FileName "C:\temp" # This is the default path in OpenFile window.
if ($inputfile -eq "") {throw 'Please select a file'}
[decimal]$filesize = ((Get-Item $inputfile).length/1MB)
$filesize =[math]::round($filesize,2)
$inputfile = resolve-path $inputfile
$WorkingFolder = Split-Path -Parent $inputfile
if (Test-path "$WorkingFolder\SPLITNAVOBJ\")
{Remove-Item -path "$WorkingFolder\SPLITNAVOBJ\" -Recurse -Force}
Write-Host "Splitting NAV objects from $inputfile (Size: $filesize MB) to $WorkingFolder\SPLITNAVOBJ\, this may take a while..." -ForegroundColor Yellow
$starttime = date
$Sr = new-object System.IO.StreamReader($inputfile,[system.text.encoding]::GetEncoding(850))
[int]$ObjCnt = 0
[int]$TabCnt = 0
[int]$PagCnt = 0
[int]$RepCnt = 0
[int]$CodCnt = 0
[int]$XmlCnt = 0
[int]$ForCnt = 0
[int]$DatCnt = 0
[int]$QueCnt = 0
[int]$MenCnt = 0
while (-not $Sr.EndOfStream)
{
$Currline = $sr.ReadLine()
if ($Currline.StartsWith('OBJECT'))
{
[String]$ObjectChar = $Currline.Substring(7,1)
$ObjectLine = $currline.Split(' ')
$ObjCnt++
Switch ($ObjectChar)
{
'T' {$TabCnt++}
'P' {$PagCnt++}
'R' {$RepCnt++}
'C' {$CodCnt++}
'X' {$XmlCnt++}
'F' {$ForCnt++}
'D' {$DatCnt++}
'Q' {$QueCnt++}
'M' {$MenCnt++}
}
$ObjectFileName = $ObjectLine[1].Substring(0,3).ToUpper() + $ObjectLine[2] + ".TXT"
$Objectfile = New-Item -path "$WorkingFolder\SPLITNAVOBJ\$ObjectFileName" -type file -force
IF (Test-Path $ObjectFile) {Remove-Item $ObjectFile}
$sw = new-object System.IO.Streamwriter($Objectfile,$false,[system.text.encoding]::GetEncoding(850))
}
if (-not $Currline.StartsWith('}'))
{$sw.writeline($Currline)}
else
{
$sw.writeline($Currline)
$sw.writeline()
$sw.Flush()
}
}
$endtime = date
$time = $endtime - $starttime
Write-Host "$ObjCnt NAV objects splitted to $WorkingFolder\SPLITNAVOBJ\ in $($time.Minutes)m:$($time.Seconds)s:$($time.Milliseconds)ms" -ForegroundColor Yellow
Write-Host "Tables: $TabCnt" -ForegroundColor Yellow
Write-Host "Pages: $PagCnt" -ForegroundColor Yellow
Write-Host "Reports: $RepCnt" -ForegroundColor Yellow
Write-Host "Codeunits: $CodCnt" -ForegroundColor Yellow
Write-Host "XMLPorts: $XMLCnt" -ForegroundColor Yellow
Write-Host "Queries: $QueCnt" -ForegroundColor Yellow
Write-Host "MenuSuites: $MenCnt" -ForegroundColor Yellow
if ($ForCnt -gt 0)
{Write-Host "Forms: $ForCnt" -ForegroundColor Yellow}
if ($DatCnt -gt 0)
{Write-Host "Dataports: $DatCnt" -ForegroundColor Yellow}
$sr.Close()
$sr.Dispose()
$sw.close()
$sw.Dispose()
Invoke-item "$WorkingFolder\SPLITNAVOBJ\"
}
Split-NAVObjectFile