PowerShell: Bereinigte Add-on-Translationsdatei erzeugen

15. September 2015 00:33

Bei der Verarbeitung von Sprachdateien, die über Extras>Translate>Export erzeugt wurden, sind außer den erwünschten Änderungen je nach Zieldatenbank u.U. auch viele Zeilen dabei, die beim Import in die Zielobjekte zu Konflikten führen können.

Szenario 1: Eine DEU-Sprachlayer soll in eine NA-Datenbank importiert werden. Außer den erwünschten ENU-Übersetzungen sind auch ENU-Captions für Standardfelder oder Textbausteine dabei, die in einer NA-Datenbank die dort abweichenden ENU-Inhalte überschreiben können. Das lässt sich weitgehend durch einen nachträglichen Zusatzimport der NA-ENU-Basislayer beheben. Dabei können allerdings Optionswert- oder Registererweiterungen, die das eigene Addon im Standardbereich mit sich brachte, wiederum auch erneut falsch überschrieben werden. Ohne manuelles Nacharbeiten in den Objekten ist das saubere Einfügen einer Sprachlayer hier nicht möglich.

Szenario 2 : Eine DEU-Layer soll nach Änderung des Sprachcodes in eine CH-Datenbank als DES oder AT-Datenbank als DEA importiert werden (oder umgekehrt :wink: ). Die DEU-Inhalte weichen aber bei Standardfeldern oder Textbausteinen ebenfalls ab.

Mit dem Skript kann man eine Translationsdatei erstellen (diese wird mit "AddonExtr"-Suffix im gleichen Ordner wie die Quelldatei erzeugt), die nur noch die Add-on-Captions enthält und dadurch beim Import in die Objekte keine Konflikte verursacht. Das erfolgt durchgehend in der notwendigen Codepage 850, gelesen und geschrieben wird daher über .NET-Methoden.

Die Nummernbereiche (im Bildbeispiel 515xxxx, im Code noch ergänzt um 54832xx) müssen in dem Skript an das jeweils verwendete Add-on angepasst werden. Zeilen, die nur den Quellcode, Codekommentare oder Variablen außerhalb der Captions betreffen, werden ebenfalls aussortiert, das kann ggf. über die Bool-Variablen angepasst werden. Änderungen, die ggf. in Standardbereichen an ganz bestimmten Objekten vorgenommen wurden, können hier ebenfalls ergänzt werden.
CaptionÄnderungStandard5.png

Links die Quelldatei, rechts die extrahierten Captionzeilen.
ExtractlangLayer2.jpg


Falls das Add-on aufgrund der funktionalen Erweiterungen auch Änderungen von Captions im Standardbereich verursacht, müssen unter Angabe der Objekt-und Feld-ID im Skript als Einschlusskriterium ergänzt werden.
Hier wurden z.B. in Tabelle 300 die Felder 9 und 13 modifiziert. Die notwendigen Codeerweiterungen dazu sind hier.
CaptionÄnderungStandard.png




Code:
function ExtractAddonFromNAVtransFile
        {
        param (
              [parameter(Mandatory=$true)]
              [string] $NAVTranslationFile)
        $WorkingFolder = (get-item $NAVTranslationFile).Directory
        $ExtractedFileName =
         [System.IO.Path]::GetFileNameWithoutExtension($NAVTranslationFile) +"AddonExtr" +
         [System.IO.Path]::GetExtension($NAVTranslationFile)
        $OutPathFile = "$WorkingFolder\$ExtractedFileName"
        if (Test-path $OutPathFile) {Remove-item $OutPathFile}
        write-host $ExtractedFileName

        foreach ($line in [System.IO.File]::ReadLines($NAVTranslationFile,[System.Text.Encoding]::GetEncoding(850)))
        {
        $ObjectTypeOneChar = $line.Substring(0,1)
        [int]$PosDash = $line.IndexOf("-")
        [int]$PosColon = $line.IndexOf(":")
        $lineStart = $line.Substring(0,$PosColon)
        $RawObjectID = $line.Substring(0,$posDash-1)
        $ObjectID = $line.Substring(1,$posDash-1)
        $line2 = $line.Substring($posDash+1)
        $CaptionTypeOneChar = $line2.Substring(0,1)
        [int]$PosDash2 = $line2.IndexOf("-")
        $RawFieldOrTextID = $line.Substring($posDash + 1,$PosDash2)

       
        if ($ObjectTypeOneChar -ne 'M')
         {[int]$FieldOrTextID = $line.Substring($posDash + 2,$PosDash2 - 1)}
        else
         {[int]$FieldOrTextID = 1}
       
        [bool]$IsAction = ($RawFieldOrTextID -eq "P55242")
     
        if ($ISAction)
        {
         # Addon page actions in standard pages
         [int]$ActionID = 1
         $line3 = $line2.Substring($posDash2+1)
         [int]$PosDash3 = $line3.IndexOf("-")
         $RawActionID = $line3.Substring(0,$PosDash3-1)
         if ($ObjectTypeOneChar -ne 'M')
          {$ActionID = $line3.Substring(1,$PosDash3 - 1)}
         else
          {$ActionID = 1}
        }
        [bool]$IsAddonFieldText = (($FieldOrTextID -ge 5157800) -and ($FieldOrTextID -lt 5158100)) -or (($FieldOrTextID -ge 5483200) -and ($FieldOrTextID -lt 5483299))
        [bool]$IsAddonObject = (($ObjectID -ge 5157800) -and ($ObjectID -lt 5158100)) -or (($ObjectID -ge 5483200) -and ($ObjectID -lt 5483299))
        [bool]$IsAddonAction = (($ActionID -ge 5157800) -and ($ActionID -lt 5158100)) -or (($ActionID -ge 5483200) -and ($ActionID -lt 5483299))       
        [bool]$IsSourceCode = ($CaptionTypeOneChar -eq 'V')
        [bool]$IsComment = ($lineStart.IndexOf("-X") -gt 0)
        [bool]$IsCaption = ($lineStart.IndexOf("-A") -gt 0)
       
        [bool]$IsMenu = ($ObjectTypeOneChar -eq 'M')

        [bool]$IsModifiedStandard1 = $Collection1 -contains $line.Substring(0,8)
        [bool]$IsModifiedStandard2 = $Collection2 -contains $line.Substring(0,9)

        [bool]$IsModifiedStandard = ($IsModifiedStandard1 -or $IsModifiedStandard2)
       
        if (-not$IsSourceCode -and -not$IsComment -and$IsCaption)
         {
         if (-$IsAddonFieldText -or -$IsAddonObject -or$IsAddonAction -or$IsMenu)
          {
           Write-host $line
           [System.IO.File]::Appendalltext($OutPathFile,$line,[System.Text.Encoding]::GetEncoding(850))
           [System.IO.File]::AppendAllText($OutPathFile,[Environment]::NewLine);
          }
          }
         }
        }
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.

Re: PowerShell: Bereinigte Add-on-Translationsdatei erzeugen

15. September 2015 17:34

Kleine Korrektur:
Die 2. Option für $IsSourceCode
Code:
-or ($CaptionTypeOneChar -eq 'U')

habe ich oben aus dem Beispiel entfernt, da sonst die Captions innerhalb von Funktionen (lokale Textkonstanten) fehlen.

Ergänzungen bei Veränderung von Standardcaptions

16. September 2015 10:04

Die folgenden Ergänzungen sind nur notwendig, falls das Add-on auch Captions im Standardbereich verändert.

Durch Angabe der konkreten Objekt- und Feldnummer als Arraywert kann man die diese als Suchkriterium mit einschließen und in der extrahierten Datei mit ausgeben.
Hier wären das Feld 6 in Tabelle 85, Feld 4 in Tabellen 296 und 298, sowie Feld 9 und 13 in Tabelle 300 (das ist ein durchaus praktisches Beispiel :wink: ).
Diese Änderungen sind in dem u.a. Skript dazugekommen:
Code:
$Collection0 = @("T85-F6-")
$Collection1 = @("T296-F4-","T298-F4-","T300-F9-")
$Collection2 = @("T300-F13-")

Code:
[bool]$IsModifiedStandard0 = $Collection0 -contains $line.Substring(0,7)
[bool]$IsModifiedStandard1 = $Collection1 -contains $line.Substring(0,8)
[bool]$IsModifiedStandard2 = $Collection2 -contains $line.Substring(0,9)

Code:
[bool]$IsModifiedStandard = ($IsModifiedStandard0 -or $IsModifiedStandard1 -or $IsModifiedStandard2)

In dieser Zeile kommt noch $IsModifiedStandard dazu:
Code:
if (-$IsAddonFieldText -or -$IsAddonObject -or $IsModifiedStandard) …


Links die Ausgabe ohne die Erweiterungen, rechts mit.
CaptionÄnderungStandard2.png

Code:
     function ExtractAddonFromNAVtransFile2
            {
            param (
                  [parameter(Mandatory=$true)]
                  [string] $NAVTranslationFile)
            $WorkingFolder = (get-item $NAVTranslationFile).Directory
            $ExtractedFileName =
             [System.IO.Path]::GetFileNameWithoutExtension($NAVTranslationFile) +"AddonExtr" +
             [System.IO.Path]::GetExtension($NAVTranslationFile)
            $OutPathFile = "$WorkingFolder\$ExtractedFileName"
            if (Test-path $OutPathFile) {Remove-item $OutPathFile}
            write-host $ExtractedFileName
            $Collection0 = @("T85-F6-")
            $Collection1 = @("T296-F4-","T298-F4-","T300-F9-")
            $Collection2 = @("T300-F13-")
            foreach ($line in [System.IO.File]::ReadLines($NAVTranslationFile,[System.Text.Encoding]::GetEncoding(850)))
            {
            $ObjectTypeOneChar = $line.Substring(0,1)
            [int]$PosDash = $line.IndexOf("-")
            [int]$PosColon = $line.IndexOf(":")
            $lineStart = $line.Substring(0,$PosColon)
            $RawObjectID = $line.Substring(0,$posDash-1)
            $ObjectID = $line.Substring(1,$posDash-1)
            $line2 = $line.Substring($posDash+1)
            $CaptionTypeOneChar = $line2.Substring(0,1)
            [int]$PosDash2 = $line2.IndexOf("-")
            $RawFieldOrTextID = $line.Substring($posDash + 1,$PosDash2)

            if ($ObjectTypeOneChar -ne 'M')
             {[int]$FieldOrTextID = $line.Substring($posDash + 2,$PosDash2 - 1)}
            else
             {[int]$FieldOrTextID = 1}
           
            [bool]$IsAction = ($RawFieldOrTextID -eq "P55242")
         
            if ($ISAction)
            {
             # Addon page actions in standard pages
             [int]$ActionID = 1
             $line3 = $line2.Substring($posDash2+1)
             [int]$PosDash3 = $line3.IndexOf("-")
             $RawActionID = $line3.Substring(0,$PosDash3-1)
             if ($ObjectTypeOneChar -ne 'M')
              {$ActionID = $line3.Substring(1,$PosDash3 - 1)}
             else
              {$ActionID = 1}
             
            }
            [bool]$IsAddonFieldText = (($FieldOrTextID -ge 5157800) -and ($FieldOrTextID -lt 5158100)) -or (($FieldOrTextID -ge 5483200) -and ($FieldOrTextID -lt 5483299))
            [bool]$IsAddonObject = (($ObjectID -ge 5157800) -and ($ObjectID -lt 5158100)) -or (($ObjectID -ge 5483200) -and ($ObjectID -lt 5483299))
            [bool]$IsAddonAction = (($ActionID -ge 5157800) -and ($ActionID -lt 5158100)) -or (($ActionID -ge 5483200) -and ($ActionID -lt 5483299))
            [bool]$IsSourceCode = ($CaptionTypeOneChar -eq 'V')
            [bool]$IsComment = ($lineStart.IndexOf("-X") -gt 0)
            [bool]$IsCaption = ($lineStart.IndexOf("-A") -gt 0)
            [bool]$IsMenu = ($ObjectTypeOneChar -eq 'M')
            [bool]$IsModifiedStandard0 = $Collection0 -contains $line.Substring(0,7)
            [bool]$IsModifiedStandard1 = $Collection1 -contains $line.Substring(0,8)
            [bool]$IsModifiedStandard2 = $Collection2 -contains $line.Substring(0,9)
            [bool]$IsModifiedStandard = ($IsModifiedStandard0 -or $IsModifiedStandard1 -or $IsModifiedStandard2)
           
            if (-not$IsSourceCode -and -not$IsComment -and$IsCaption)
             {
             if (-$IsAddonFieldText -or -$IsAddonObject -or $IsModifiedStandard -or$IsAddonAction -or$IsMenu)
              {
               Write-host $line
               [System.IO.File]::Appendalltext($OutPathFile,$line,[System.Text.Encoding]::GetEncoding(850))
               [System.IO.File]::AppendAllText($OutPathFile,[Environment]::NewLine);
              }
              }
             }
            }


Edit 23.02.16: $Collection0 für Feld 6 in Tabelle 85 ergänzt
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.

Korrektur für Page Actions in Standardpages

16. September 2015 16:02

Für Add-on Pageactions in Standardpages muss man in der 3. Ebene nach dem Add-on-Nummernbereich suchen, das fehlte noch (Codestellen mit $IsAction und $ActionID), das habe ich oben ergänzt.
CaptionÄnderungStandard3.png

Außerdem habe ich die MenuSuite-Captions mit dazugenommen, die kann man natürlich auch weglassen, wenn man die MenuSuites lieber separat importiert.
Code:
[bool]$IsMenu = ($ObjectTypeOneChar -eq 'M')

Mit einer über die erweiterte Version erzeugten Datei habe ich heute nach einem Testmenge in eine NAV 2015 ohne Sprachlayer alle Add-on-Captions sauber eingebracht, ohne dabei die Standardfelder- oder Controls zu berühren, wo es nicht gewünscht ist. Belastungstest bestanden :wink: .
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.

Korrektur für Indexsuche nach -X -A

21. September 2015 14:17

Ein paar überflüssige Zeilen waren in der erzeugten Datei noch drin, weil nach "-A" und "-X" in der gesamten Zeile gesucht wurde, und nicht nur bis zum Doppelpunkt. Dadurch kamen z.B. für "-A" auch Zeilen mit rein, die keine Captions sind, aber die nach dem Doppelpunkt diese Strings enthalten, bzw. bei "-X" hätten diese gefehlt.
Das ist jetzt oben korrigiert.

Eingefügte Zeilen
Code:
[int]$PosColon = $line.IndexOf(":")
$lineStart = $line.Substring(0,$PosColon-1)

Alter Code
Code:
[bool]$IsComment = ($line.IndexOf("-X") -gt 0)
[bool]$IsCaption = ($line.IndexOf("-A") -gt 0)

Neuer Code
Code:
[bool]$IsComment = ($lineStart.IndexOf("-X") -gt 0)
[bool]$IsCaption = ($lineStart.IndexOf("-A") -gt 0)


Links vor Korrektur , rechts danach.
CaptionÄnderungStandard4.png
Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.