Nachtrag 2018: Beim Einsatz von Docker geht dieses mit nur einem Container jetzt wesentlich einfacher als direkter Export mittels des Cmdlets Convert-ModifiedObjectsToAL.
In dem alten Artikel vom Mai 2017 noch nicht erwähnt: Um eine Grundlage für eine Extension zu haben, müssen nach dem Zwischenexport DELTA-Dateien gebildet werden, erst dann entstehen beim txt2al-Lauf Modification-Dateien in AL für Table- oder Pageextensions im Bezug auf die Standardobjekte (aus der Base App). Die Fähigkeit, DELTA-Dateien überhaupt zu verarbeiten, bekam txt2al.exe ja auch erst einen Monat später .
Der Anfang der ersten Datei oben für eine neue Action in der Bankkontokarte sieht dann bspw. so aus
- Code: Alles auswählen
pageextension 70000002 pageextension70000002 extends "Bank Account Card"
{
// version NAVW111.00,MyExt01
actions
{
addafter("Bank&konto")
…
Hier neue Schlüssel in Tabelle 21 Cust. Ledger Entry (
Docs:
- Code: Alles auswählen
tableextension 70000009 tableextension70000009 extends "Cust. Ledger Entry"
{
// version NAVW111.00,MyExt01
keys
{
key(Key1;"Customer No.","Document No.")
{
}
key(Key2;"Customer No.",Open,"Document Date")
{
}
key(Key3;Open,"Customer No.","Document Date")
{
}
}
}
Ablauf
- Objekte aus der MODIFIED-DB (mit der Extension) über Versionslistenfilter in der temporären Zwischensyntax exportieren ( Schalter -ExportToNewSyntax)
- Die modifizierten Base App-Objekte der MODIFIED-Datenbank aus der ORIGINAL-Datenbank über eine temporäre Indexliste ebenfalls in der Zwischensyntax exportieren
- DELTA-Dateien für diese Objekte bilden. DELTA-Dateien für Objekte außerhalb der Base App sind identisch mit einem normalem Objektexport in Zwischensyntax, enthalten also jeweils den kompletten Code des Objekts da es ja kein Ausgangsobjekt in der ORIGINAL-Datenbank dazu gibt.
- DELTA-Dateien mit txt2al.exe in AL umwandeln
Dieses Skript erledigt das automatisch. Ich gehe dabei beim Export direkt auf die Datenbanken und nicht wie Waldo über die Dienste an diese heran, das geht weiterhin auch bzw. hier noch. In VS Code bzw. AL geht es dann aber nur noch mit dem laufenden Dienst, da man sich hier nur noch so mit der Datenbank verbinden kann.
Im Skript müssen MyServer, MyDatabase,Versionslistenfilter usw. natürlich an die eigenen Umgebungen angepasst werden. Bei uns habe ich das so umgesetzt, dass diese Skripte automatisch mit den richtigen Parametern generiert werden und die AL-Dateien somit per Mausklick erzeugt werden können.
Der Arbeitsordner sieht dann bspw. so aus, in AL liegen die fertigen .al- und .rdlc-Dateien.
Die BaseAppObjects.txt sind die Standardobjekte für Kontrollzwecke gebenüber dem Extensionobjektpaket in normaler C/AL-Syntax.
Links C/AL, rechts die Zwischensyntax, die über den Schalter -ExportAsNewSyntax erzeugt wird.
In ORIGINAL die gleichen Objekte der Base App, aber einzeln zerlegt und dort dann ebenfalls in Zwischensyntax. Hierauf setzt das Compare-Cmdlet an, um die Grundlage für txt2al.exe zu liefern.
- Code: Alles auswählen
[string]$MyEnviron = [Environment]::OSversion.Version.ToString(3) ; [bool]$OldEnviron = ($MyEnviron.substring(0,3) -eq '6.1')
$ParentWorkingFolder = "C:\MyFolder"
IF (!(Test-Path $ParentWorkingFolder)) {New-Item $ParentWorkingFolder -type directory}
IF (!(Test-Path $ParentWorkingFolder\ORIGINAL)) {New-Item $ParentWorkingFolder\ORIGINAL -type directory -force}
IF (!(Test-Path $ParentWorkingFolder\MODIFIED)) {New-Item $ParentWorkingFolder\MODIFIED -type directory -force}
IF (!(Test-Path $ParentWorkingFolder\DELTA)) {New-Item $ParentWorkingFolder\DELTA -type directory -force}
Import-Module "${env:ProgramFiles(x86)}\Microsoft Dynamics NAV\110\RoleTailored Client\Microsoft.Dynamics.Nav.Model.Tools.psd1" -force -DisableNameChecking | out-null
$IndexFolder = "$ParentWorkingFolder\TEMPINDEX"
IF (Test-Path $IndexFolder) {Remove-Item $IndexFolder\*.txt -recurse}
Export-NAVApplicationObject -DatabaseServer MyServer -DatabaseName MyDatabase -ExportToNewSyntax -path $ParentWorkingFolder\OPPobjectsNewSyntax.txt -Filter "Version List=*OPP*" -ExportTxtSkipUnlicensed -Force
Split-NAVApplicationObjectFile -Source $ParentWorkingFolder\OPPObjectsNewSyntax.txt -Destination $ParentWorkingFolder\MODIFIED -Force
Export-NAVApplicationObject -DatabaseServer MyServer -DatabaseName MyDatabase -path $ParentWorkingFolder\BaseAppObjects.txt -Filter 'ID=..49999;"Version List=*OPP*"' -ExportTxtSkipUnlicensed -Force
Split-NAVApplicationObjectFile -Source $ParentWorkingFolder\BaseAppObjects.txt -Destination $ParentWorkingFolder\TEMPINDEX -Force
Get-ChildItem -Path $IndexFolder\*.txt |
ForEach-Object `
(
{
Write-host "Trying to export object:" $_.Name
$IDbasename = [System.IO.Path]::GetFileNameWithoutExtension($_.Name)
$IDobject = $IDbasename.Substring(3)
$ShortObjectType = $IDbasename.Substring(0,3)
$IDobject = "ID=" + $IDobject
Switch ($ShortObjectType)
{"TAB" {$ObjectFilter = "Type=Table;" + $IDobject + '"'}
"PAG" {$ObjectFilter = "Type=Page;" + $IDobject + '"'}
"REP" {$ObjectFilter = "Type=Report;" + $IDobject + '"'}
"XML" {$ObjectFilter = "Type=XMLport;" + $IDobject + '"'}
"COD" {$ObjectFilter = "Type=Codeunit;" + $IDobject + '"'}
"MEN" {$ObjectFilter = "Type=MenuSuite;" + $IDobject + '"'}
"QUE" {$ObjectFilter = "Type=Query;" + $IDobject + '"'}}
$ExportFile = $_.Name
$LogFile = "$ParentWorkingFolder\ORIGINAL\Log_$ExportFile"
$ExportFile = "$ParentWorkingFolder\ORIGINAL\$ExportFile"
if (Test-Path "$ParentWorkingFolder\navcommandresult.txt") {Remove-Item "$ParentWorkingFolder\navcommandresult.txt"}
if (test-path $ExportFile) {remove-item $ExportFile}
if ($OldEnviron) {$NAVFolder = '"C:\Program Files (x86)\Microsoft Dynamics NAV\110\RoleTailored Client'} else {$NAVFolder = 'C:\Program Files (x86)\Microsoft Dynamics NAV\110\RoleTailored Client'}
$exportfinsqlcommand = """$NAVFolder\finsql.exe"" command=ExportToNewSyntax,file=$ExportFile,servername=MyServer,database=MyDatabase,Logfile=$LogFile"
if ($ObjectFilter -ne ""){$exportfinsqlcommand = "$exportfinsqlcommand,filter=$ObjectFilter"}
$Command = $exportfinsqlcommand
Write-Debug $Command
cmd /c $Command
$ExportFileExists = Test-Path "$ExportFile"
If (-not $ExportFileExists) {
write-error "Error on exporting to $ExportFile. Look at the information below."
if (Test-Path "$ParentWorkingFolder\navcommandresult.txt"){Get-Content "$ParentWorkingFolder\navcommandresult.txt"}
if (Test-Path $LogFile) {Get-Content $LogFile}
}
else{
$NAVObjectFile = Get-ChildItem $ExportFile
if ($NAVObjectFile.Length -eq 0) { Remove-Item $NAVObjectFile }
if (Test-Path "$ParentWorkingFolder\navcommandresult.txt") {Get-Content "$ParentWorkingFolder\navcommandresult.txt"}
}}
)
if (Test-Path "$ParentWorkingFolder\ORIGINAL\navcommandresult.txt") {Remove-Item "$ParentWorkingFolder\ORIGINAL\navcommandresult.txt"}
IF (Test-Path $IndexFolder) {Remove-Item -path $IndexFolder\*.txt -recurse}
IF (Test-Path $IndexFolder) {Remove-Item -path $IndexFolder}
$NAVFolder = "${env:ProgramFiles(x86)}\Microsoft Dynamics NAV\110\RoleTailored Client"
Compare-NAVApplicationObject -DeltaPath $ParentWorkingFolder\DELTA -ModifiedPath $ParentWorkingFolder\MODIFIED -OriginalPath $ParentWorkingFolder\ORIGINAL -Force -IgnoreDocumentation
$Convertcommand = """$NAVFolder\txt2al.exe"" --source=""$ParentWorkingFolder\DELTA"" --target=""$ParentWorkingFolder\AL"" --rename"
$Command = $Convertcommand
Write-Host -ForegroundColor Green 'Convert objects with:'
Write-host -ForegroundColor Gray " $Command"
cmd /c $Command