RS First Dynamics NAV Blog


...from NAV 3.60 to NAV 2013
Archivio Posts
Anno 2015

Anno 2014

Anno 2013

Anno 2012

Anno 2011

Anno 2010

Anno 2009

Anno 2008

Anno 2007

Unicode Support from NAV 310 to NAV 2009

Unicode Support from NAV 3.10 to NAV 2009

 

Microsoft Issues

- The double-byte character set, code page ‘XXX’ à (ex: 932 Japanese), is not supported by this version of Microsoft Dynamics NAV: Microsoft Dynamics NAV 2009, Microsoft Dynamics NAV 5.0, Microsoft Dynamics NAV 4.0, Microsoft Business Solutions–Navision 3.70, Navision Attain 3.6, or Navision Attain 3.10.

-   Supported only on NAV 2013, native support

Double-Byte Character Set (DBCS) code page error when you start Microsoft Dynamics NAV

- It is known that NAV CC (Classic Client) does not support natively DBCS (Double-Byte Character Set) and so does the new NAV 2009 RTC (Roled Tailored Client)

- Due to differences in how the CC and RTC check the code page isn’t still possible to enable DBCS in the RTC but this is possible for the CC by implementing new fin.stx file.

 

Workaround to handle unicode chars

How to enable and to display double-byte character sets in Microsoft Dynamics NAV https://mbs.microsoft.com/knowledgebase/KBDisplay.aspx?scid=kb;EN-US;915374

 

WHAT TYPE OF ENCODING?

Roughly speaking regarding what we have done is merely enabling theJ apanese characters to be stored into SQL Server but… not directly!

The Japanese code page is 932 (Shift-JIS) while we are using the Latin1 code page 1252 to store the data. To know more about Windows Collation Designators you can check: http://msdn.microsoft.com/en-s/library/aa176553.aspx

This means that while we are typing Japanese chars in the NAV classic Client (using code page 932), this have been reverted (translation encoded) in their respective characters using code page 1252 and stored in this way in the SQL Server field.

 

This means that while we are seeing this in NAV :

 

Support

- Note XXXX (ex. 932) is the placeholder for the one of the following code pages: http://msdn.microsoft.com/en-us/library/aa176553.aspx

932: Japanese Shift-JIS 936: Simplified Chinese GBK 949: Korean 950: Traditional Chinese Big5

- All windows languages are supported

SOLUTION

- Then the solution can come out clearly: use C# encoding function to manage the ‘translation’ between one set of character to another.

      SUPPORTO LINGUE CINESE TRADIZIONALE, GIAPPONESE etc.

SPIEGAZIONE SUPPORTO UNICODE PER NAV 2009 e NAV 2013

NAV 2009 non supporta unicode

NAV 2013 supporta unicode nativo

NAV 2013 Sample

On Page Chin2 field is visible with Chinese Char

Unicode & Chinese Data

 

NAV 2009 Sample, Classic Client

Only unicode, no Chinese

 Cosa significa:

Se sarebbe già possibile (con la modifica sopra illustrata) inserire un dato in cinese (es: su Word) ciò non è sarebbe possibile su NAV in quanto il client non riconosce i caratteri e li scrive in formato “?????????”

In pratica NAV (e SQL Server) non riescono a memorizzare il dato in cinese anche se sembra che possa essere inserito

Su un database SQL Server (con collaction CS o CI latin general_1) non è possibile inserire caratteri cinesi (non li fa scrivere nel db, mette ‘???????’ unknow data value)

Le possibilità di gestione sarebbero 3:

1 - Creare e scrivere direttamente in un db cinese (chinese collaction) > è un nuovo db NAV\SQL

2 - Convertire il db attuale in unicode support (raddoppia lo spazio su disco, rallenta il database, non sappiamo quanto ci metterebbe a convertirlo, potrebbe non convertire il tutto e bloccarsi durante la conversione; gestirebbe correttamente la scrittura del dato cinese sul db ma non lo potrebbe visualizzare comunque in NAV (cioè scrive nel db ma non visualizza in NAV)

3 - Modificare il db attuale modificando un parametro che permetta di inserire il dato in formato unicode metadato (cioè non in cinese ma nel suo unicode) dicendo a SQL di non scartare il dato; con questa soluzione in sostanza potremmo importare dati da file esterni : TXT, XLS in unicode format su SQL  

Gestirebbe correttamente la scrittura del metadato unicode (creato da alcune procedure di Codifica\Decodifica da installare basate su windows) che rappresenta il cinese ; non lo potrebbe visualizzare comunque in NAV (cioè scrive nel db un dato che potremmo OnDemand convertire in cinese ma non visualizza in NAV)

 Soluzione meno invasiva

Opzione 3”

Cosa si può fare:

Supportiamo la scrittura del metadato sul database (unicode corrispondente al cinese)

E’ possibile caricare tramite batch input (file TXT, XLS salvato in unicode) nel database

E’ possibile creare ed esporre delle viste che visualizzano sia il metadato che la lingua cinese (da esporre al web)

E’ possibile dal web scrivere il metadato di ritorno al db utilizzando le stesse funzioni usate

Come funziona: tramite 2 funzioni custom su SQL viene fatto Encode \ Decode del dato per permettere di scrivere \ leggere il dato in unicode e di visualizzarlo in cinese.

Come lo facciamo:

Visualizzazione, esposizione dati, importazione\esportazione dati

Modifica ed aggiunta dati: - Per visualizzare i dati in cinese (o modificarli \ aggiungerli etc.) è necessario creare alcune “Windows Forms” da lanciare da Nav per visualizzare\modificare i dati; queste maschere sembrano NAV ma son NAV; sono fatte in Visual Studio. Sarà possibile aggiungere dati salvando in metadati ma visualizzando in cinese 

Esposizione dati per Web: - Saranno create delle viste SQL che richiamando le funzioni Encode \ Decode e visualizzeranno in dati in cinese

Es: Vista con dati unicode

/****** Script for SelectTopNRows command from SSMS  ******/

SELECT TOP 1000 [Code]

      ,[DescrReconverted]

      ,[Descr]

      ,[Chinese]

FROM [Demo Database NAV (7-0)].[dbo].[CRONUS Italia S_p_A_$V_ART_CINESE_NAV]

 

Descr = METADATO (unicode), Chinese = dati in cinese (trascodificato da procedura)

 

Import\Export dati: Saranno creati dei DTS che utilizzando i sistemi di codifica visti sopra  permetteranno l’inserimento del metadato unicode.

ES SQL DTSX: COMPLETE FLOW

FLAT FILE (OR UNICODE OR CHINESE COLLACTION TABLE)

OBJECT SCRIPT

Ø  Lo script component converte il dato NAV da Chinese in unicode e lo scrive su SQL in unicode (cosa non possibile da NAV)

Ø  Input Columns (unicode data from SQL Unicode Table or Unicode TXT or EXCEL files)

DT_WSTR  > double bytes for Chinese chars

Output Columns (string format to handle unicode data DT_STR)

 

 C# code in Script Component

/* Help:  Introduction to the Script Component */

/* The Script Component allows you to perform virtually any operation that can be accomplished in a .Net application within the context of an Integration Services data flow.

* Expand the other regions which have "Help" prefixes for examples of specific ways to use

* Integration Services features within this script component. */

 

Namespaces

using System;

using System.Data;

using Microsoft.SqlServer.Dts.Pipeline.Wrapper;

using Microsoft.SqlServer.Dts.Runtime.Wrapper;

using System.Text;

 

// RS, 20130531, Encode\Decode Integrated Script (C#)

// This is the class to which to add your code.  Do not change the name, attributes, or

// parent of this class.

 

[Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute]

public class ScriptMain : UserComponent

{

Help:  Using Integration Services variables and parameters

     * Example of reading from a variable or parameter:

     *  DateTime startTime = Variables.MyStartTime;

     *

     * Example of writing to a variable:

     *  Variables.myStringVariable = "new value";

     */

Help:  Using Integration Services Connnection Managers

     *

     * If the component needs to hold a connection open while processing rows, override the

     * AcquireConnections and ReleaseConnections methods.

     *

     * Example of using an ADO.Net connection manager to acquire a SqlConnection:

     *  object rawConnection = Connections.SalesDB.AcquireConnection(transaction);

     *  SqlConnection salesDBConn = (SqlConnection)rawConnection;

     *

     * Example of using a File connection manager to acquire a file path:

     *  object rawConnection = Connections.Prices_zip.AcquireConnection(transaction);

     *  string filePath = (string)rawConnection;

     *

     * Example of releasing a connection manager:

     *  Connections.SalesDB.ReleaseConnection(rawConnection);

     */

Help:  Firing Integration Services Events

    /* This script component can fire events.

     *

     * Example of firing an error event:

     *  ComponentMetaData.FireError(10, "Process Values", "Bad value", "", 0, out cancel);

     *

     * Example of firing an information event:

     *  ComponentMetaData.FireInformation(10, "Process Values", "Processing has started", "", 0, fireAgain);

     *

     * Example of firing a warning event:

     *  ComponentMetaData.FireWarning(10, "Process Values", "No rows were received", "", 0);

     */

   

    ///

    /// This method is called once, before rows begin to be processed in the data flow.

    /// You can remove this method if you don't need to do anything here.

    ///

   

Public override void PreExecute()

    {

        base.PreExecute();

        /*

         * Add your code here

        */

    }

 

    /// This method is called after all the rows have passed through this component.

    ///

    /// You can delete this method if you don't need to do anything here.

   

Public override void PostExecute()

    {

        base.PostExecute();

        /*

         * Add your code here

         */       

    }

 

    /// This method is called once for every row that passes through the component from     

//  Input0.

    /// Example of reading a value from a column in the the row:

    /// string zipCode = Row.ZipCode

    ///

    /// Example of writing a value to a column in the row:

    /// Row.ZipCode = zipCode

   

   

Public override void Input0_ProcessInputRow(Input0Buffer Row)

    {

        /*

         * Add your code here

        */

       

        // Create a new variable of type Encoding and

        // assign it the Latin *** code page 1252 ***

        // To know more about it

        // http://msdn.microsoft.com/en-us/library/system.text.encoding_members.aspx

 

        Encoding nav = Encoding.GetEncoding(1252);

 

        // Create a new variable of type Encoding and assign it the Japanese

        // *** Code page 932 Japanese

        // Encoding unicode = Encoding.GetEncoding(932);

 

        Encoding unicode = Encoding.GetEncoding(936);

 

        // Assign Rowdata Values

        byte[] unicodeCod = unicode.GetBytes(Row.Cod);

        byte[] unicodeDescription = unicode.GetBytes(Row.Description);

        byte[] reconverted = nav.GetBytes(Row.Description);

 

        // Assign Added Output Fields

        this.Output0Buffer.AddRow();     

               

        Output0Buffer.CodNav = nav.GetString(unicodeCod);

        Output0Buffer.DescriptionNav = nav.GetString(unicodeDescription);

        Output0Buffer.Reconverted = unicode.GetString(reconverted);

 

 

        // **

 // ComponentMetaData.FireInformation(10, "Process Values",     

 unicode.GetString(reconverted), "", 0, true);       

        // Row.Cod = nav.GetString(unicodeCod);

        // Row.Description = nav.GetString(unicodeDescription);

        // **       

    }

}

  

SQL Destination Preview

Code = converted from Chiese to Unicode

Descr = converted from Chiese to Unicode

Cosa non si può fare nel db attuale (non unicode e non in cinese):

Su Nav non è possibile visualizzare i dati i cinese dal client classic > ‘???????’

Non è possibile stampare il documento in cinese (stesso problema del client) > ‘???????’

Non è possibile fatturare in cinese (e contabilizzare fatture in cinese)

Se servisse fatturare su NAV occorre creare un “DB Cinese”

Importare tramite viste sql e stored procedures i dati dal db attuale sul db cinese trascodificando tramite le funzioni sopra descritte e scrivendo il dato in cinese

Non è possibile eseguire una fatturazione in NAV poiché ci sono dei vincoli nelle localizzazioni cinesi, giapponesi etc.; sulla cinese viene messo un oggetto che collegato al tel. stacca il protocollo di fatturazione cinese che deve validare le fatture

 

SUPPORT UNICODE IN NAV – PROCEDURA

WINDOWS INPUT DATA

Come indicato nella documentazione Microsoft, Dynamics NAV 2009 non è direttamente abilitato all’utilizzo diretto dei caratteri Unicode. Il sistema operativo(windows) permette di utilizzare i caratteri Unicode anche per la visualizzazione e l’inserimento dei dati con programmi non abilitati utilizzando una particolare impostazione del menu [Region and Language] in ITA [Paese e Lingua] (in questo documento facciamo riferimento ad un client Windows 7). Si suppone che il computer sia già impostato per utilizzare i caratteri cinesi.

MODIFICHE WINDOWS

Come si imposta:

L’impostazione è [Language for non-Unicode programs], che si trova nel tab [Advanced] di [Region and Language]:

Dal menu visualizzato, selezionare Chinese Simplified, PRC,oppure Chinese Traditional (es: Taiwan). Questa impostazione richiede il riavvio del pc.

Fatta questa prima modifica, il client è abilitato all’inserimento dei caratteri Unicode in Dynamics NAV; lo farebbe però solo su un db con collaction cinese

 

MODIFICA A PARAMETRO NAV (su SQL SERVER) per SUPPORT INPUT UNICODE DATA

Prima di poter effettivamente utilizzare questa caratteristica, è necessario modificare un parametro del server Dynamics NAV che se impostato impedisce l’inserimento nel database di caratteri non compatibili con la collation indicata per il database SQL: per modificare questo parametro è necessario impostare il database in Single User Mode (), effettuare la modifica ed uscire dal Single User Mode.

Il campo [Convalida regole di confronto] in [Confronto] deve essere impostato a FALSE

Cosa fa questo flag : permette a NAV di scrivere i dati senza chiedere la validazione della collaction SQL Server (bypass input)

Gli altri parametri di questa pagina non devono essere modificati.

 

MY TEST CASE

La principale difficoltà segnalata da Microsoft Italia era relativa all’impossbilità di inserire direttamente i caratteri cinesi nel database Dynamics NAV, in quanto i campi rimangono di tipo VARCHAR mentre i campi contenenti dati Unicode sono di tipo NVARCHAR. Ne deriva che un dato visualizzato in Dynamics NAV come scritto con caratteri cinesi (due bytes) viene in effetti salvato nel database nelle sue componenti costitutive in byte.

Poiché sono presenti alcune procedure di scambio automatico dei dati, è stata implementata nell’ambiente di sviluppo e test una possibile soluzione per questo problema.

Si tratta di una serie di metodi esposti da una classe scritta in C# per .NET 3.5, che forniscono le funzionalità di conversione dalla codifica Unicode cinese e giapponese verso la codifica utilizzata da Dynamics NAV, e viceversa.

Per installare ed utilizzare queste funzioni è necessario abilitare il server nel quale verranno richiamate le funzioni all’utilizzo di CLR, mediante i seguenti comandi:

 

Da console SQL (new query)

       -- attivazione CLR per supporto Assembly --

sp_configure 'clr enable', 1  

GO

RECONFIGURE  

GO

  

Codeunit Parser “UnicodeConverter.dll”

Cosa fa: gestisce la trascodifica unicode tramite DLL Windows

Copiare la DLL UnicodeConverter.dll nella cartella del server SQL (normalmente in C:\Program Files\Microsoft SQL Server\MSSQL10.MSSQLSERVER\MSSQL\Binn\) per l’utilizzo in SQL, tramite il comando

Da console SQL Server (new query)

C# Code per DLL

// ** Code, Encode ** /

// ** RS, 20130531 ** /

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Data.SqlClient;

using Microsoft.SqlServer.Server;

using System.Data.SqlTypes;

using System.Text;

 

// PUBLIC CLASS ** CONVERTER **   

public class Converter

    {

        [SqlFunction(IsDeterministic = true)]

        public static SqlString Chinese2NAV(SqlString ChineseString)

        {

            /* Encode es: 1252 Non Unicode*/

            Encoding NotUnicode = Encoding.GetEncoding(1252);

            /* Encode es: 936 Unicode*/

            Encoding Chinese = Encoding.GetEncoding(936);

 

            return (NotUnicode.GetString(Chinese.GetBytes((string)ChineseString)));

        }

 

        [SqlFunction(IsDeterministic = true)]

        public static SqlString NAV2Chinese(SqlString NotUnicodeString)

        {

            /* Encode es: 1252 Non Unicode*/

            Encoding NotUnicode = Encoding.GetEncoding(1252);

            /* Encode es: 936 Chinese*/

            Encoding Chinese = Encoding.GetEncoding(936);

 

            // Return Chinese

            return (Chinese.GetString(NotUnicode.GetBytes((string)NotUnicodeString)));

        }

 

        [SqlFunction(IsDeterministic = true)]

        public static SqlString Japanese2NAV(SqlString JapaneseString)

        {

            /* Encode es: 1252 Non Unicode*/

            Encoding NotUnicode = Encoding.GetEncoding(1252);

            /* Encode es: 932 Chinese*/

            Encoding Japanese = Encoding.GetEncoding(932);

 

            return (NotUnicode.GetString(Japanese.GetBytes((string)JapaneseString)));

        }

 

        [SqlFunction(IsDeterministic = true)]

        public static SqlString NAV2Japanese(SqlString NotUnicodeString)

        {

            /* Encode es: 1252 Non Unicode*/

            Encoding NotUnicode = Encoding.GetEncoding(1252);

            /* Encode es: 932 Chinese*/

            Encoding Japanese = Encoding.GetEncoding(932);

 

            // Return Japanese

            return (Japanese.GetString(NotUnicode.GetBytes((string)NotUnicodeString)));

        }

 

    }

  

REGISTRAZIONE ASSEMBLY PER DLL SU SQL SERVER

Registrazione DLL ‘UnicodeConverter.dll'

 

CREATE ASSEMBLY UnicodeConverter from 'C:\Program Files\Microsoft SQL Server\MSSQL10.MSSQLSERVER\MSSQL\Binn\UnicodeConverter.dll' WITH PERMISSION_SET = SAFE

 

 Mio test case:

 

 

-- attivazione CLR per supporto Assembly --

sp_configure 'clr enable', 1  

GO

RECONFIGURE  

GO

 

-- Creazione ASSEBLY per pubblicare la DLL a SQL --

CREATE ASSEMBLY UnicodeConverter from 'C:\Program Files\Microsoft SQL Server\MSSQL10_50.SQL2008R2\MSSQL\Binn\UnicodeConverter.dll' WITH PERMISSION_SET = SAFE

  

Infine devono essere create le funzioni su SQL utente da richiamare per la conversione:

CREATE Function Chinese2NAV(@matchString nvarchar(max)) returns nvarchar(max)

AS EXTERNAL NAME UnicodeConverter.Converter.Chinese2NAV

 

CREATE Function Japanese2NAV(@matchString nvarchar(max)) returns nvarchar(max)

AS EXTERNAL NAME UnicodeConverter.Converter.Japanese2NAV

 

CREATE Function NAV2Chinese(@matchString nvarchar(max)) returns nvarchar(max)

AS EXTERNAL NAME UnicodeConverter.Converter.NAV2Chinese

 

CREATE Function NAV2Japanese(@matchString nvarchar(max)) returns nvarchar(max)

AS EXTERNAL NAME UnicodeConverter.Converter.NAV2Japanese

 

Queste funzioni potranno quindi essere utilizzate per la scrittura e la lettura dei dati nel formato Dynamics NAV.

Si noti che queste funzioni convertono le stringhe senza porre limitazioni circa la lunghezza della stringa stessa: devono quindi essere verificate e confrontate rispetto alla lunghezza effettiva dei campi disponibili in Dynamics NAV tenendo presente il fatto che non c’è corrispondenza tra la lunghezza delle stringhe Unicode e quelle Dynamics NAV equivalenti.

 

Il test del corretto funzionamento delle funzioni può essere fatto tramite le seguenti chiamate:

Code\Encode Functions

Encoding nav = Encoding.GetEncoding(1252);

Encoding unicode = Encoding.GetEncoding(932);

byte[] unicodeBytes = unicode.GetBytes(textBox1.Text);

textBox2.Text = nav.GetString(unicodeBytes);

 

Select with Functions

select dbo.NAV2Chinese(N'²ÊƼ Îâ')

 

example

  

Riferimenti:

Microsoft Officials

http://blogs.msdn.com/b/nav/archive/2009/06/16/how-to-manage-nav-dbcs-data-using-c.aspx

https://mbs2.microsoft.com/Knowledgebase/KBDisplay.aspx?scid=kb$EN-US$915374&wa=wsignin1.0

http://blogs.msdn.com/b/freddyk/archive/2008/11/04/transferring-data-to-from-com-automation-bjects-and-webservices.aspx

 

Encoding code page (ex: 1252 ITA)

http://msdn.microsoft.com/en-us/library/system.text.encoding_members.aspx

 

Blog Kekunda

http://petrescent5.kekunda.com/chan-4194086/all_p1.html

Referencing a custom assembly inside a Script Task

http://microsoft-ssis.blogspot.it/2011/05/referencing-custom-assembly-inside.html

http://microsoft-ssis.blogspot.it/

 

NAV 2013 SOAP Web Services on a multilanguage environment

http://blogs.msdn.com/b/nav/archive/2012/11/07/nav-2013-soap-web-services-on-a-multilanguage-environment.aspx

Pillole di programmazione C#, C++

http://www.aino.it/Attivita/Appunti_C_Sharp/Programmazione.htm

 

by Roberto Stefanetti

Categoria: Dynamics NAV ALL
venerdì, 31 mag 2013 Ore. 15.51
Statistiche
  • Views Home Page: 468.968
  • Views Posts: 885.818
  • Views Gallerie: 0
  • n° Posts: 343
  • n° Commenti: 0
Copyright © 2002-2007 - Blogs 2.0
dotNetHell.it | Home Page Blogs
ASP.NET 2.0 Windows 2003