lunedì 20 maggio 2013

Microsoft Dynamics nav 2013: La nuova gestione delle Dimensioni



Breve introduzione

Volevo dare una breve spiegazione di cosa fosse le dimensioni in Nav e a cosa servono, come introduzione, per chi non avesse esperienza in Nav.

Le dimensioni sono delle entità che ci permettono di analizzare i dati in modi diversi. A ciascun movimento contabile è possibile associare un valore di una quantità indefinita di dimensione analitica. Questo ci permette di analizzare i valori contabili incrociando due entità analitica.

Ad esempio un società potrebbe usare la dimensioni “Reparti” (Amministrazione, Produzione, Imballaggio, Vendite, Acquisti etc ..) ed analizzare i costi e ricavi generati durante il periodo contabile per questi valori. Si potrebbe anche usare una dimensione “Linea di prodotto” (Modello A, Modello B etc ..) ed analizzare gli stessi costi e ricavi per Reparti e Linea di prodotto. Per le aziende che possiedono più sedi si può optare per un valore dimensione per ciascuna sede ed analizzare i profitti per sede. Le aziende di servizi possono usare una dimensione per progetto o tipologia di servizio etc ..

Per poter costruire queste analisi dimensionali e necessario associare a ciascun documento attivo e passivo, a ciascuna registrazione d’incasso e pagamento, a ciascuna scrittura di prima nota, consuntivazione per commessa, timesheet, ma in generale a ciascun movimento contabile un valore di dimensione analitica di una o più dimensioni.


La vecchia gestione

Nelle versioni precedenti di Nav, le dimensioni collegate a movimenti o documenti provvisori si consolidavano nella tabella “Ledger Entry Dimension” una volta i movimenti o documenti registrati. In questo modo le analisi si potevano costruire sulla medesima tabella che conteneva il riferimento al Nr. movimento Contabile, al codice dimensione ed al suo valore.

Questa concezione permetteva l’elaborazione di analisi molto accurate ma era poco performante, in effetti per chi usava tanti dimensioni e generava tante scritture, non solo la tabella “Ledger Entry Dimension” si riempiva a dismisura in pochissimo tempo, ma le prestazioni del software durante il processo di registrazione di documenti o scritture contabili potevano diminuire pericolosamente. Basta pensare che un azienda che usava le dimensioni precedentemente citate poteva associare a ciascuna riga di una fattura di vendita un valore dimensionale, se la fattura era composta di 10 righe, le dimensioni associate potevano essere 3 volte di più quindi 30 righe, che dovevano essere consolidate. Ma questo è solo un esempio, una volta capito come usare le dimensioni, ci si prende gusto e si abusa quasi, definendo decine di dimensioni da collegare, i casi di scarsa prestazioni dovuti alle dimensioni sono stati tanti e ben peggio dell’esempio illustrato precedentemente.


La nuova gestione, il concetto

Per migliorare le prestazioni mantenendo la flessibilità di questo strumento di analisi, bisognava diminuire la quantità di righe da storicizzare durante la registrazione di scritture contabile.

Nella nuova gestione si storicizzano i set di dimensioni, (quando dico Set intendo una certa quantità di copia “codice dimensione” e “valore dimensione”), una volta sola, dandoli un Id univoco che ci permette l’associazione dei valori al movimento contabile. In questo modo tutti i movimenti contabili successivi che possiedano le stesse copie di “Codice dimensione” e “Valore dimensione” possono essere collegati allo stesso set di dimensioni tramite lo stesso Id univoco, evitando così di duplicare records nella tabella dei movimenti dimensioni “Ledger Entry Dimension”.

Durante l’associazione di una o più dimensioni ad un movimento o ad un documento, la procedura verifica se il set di dimensione che si sta associando esiste già identificato tramite un Id univoco, in quel caso lo userà, nel caso contrario, ne creerà uno nuovo e storicizzerà la combinazione di dimensioni.

Naturalmente, l’implementazione di questa nuova gestione ha portato tanti cambiamenti nella struttura degli oggetti di Nav ed in particolare nella codeunit 408 DimensionManagment e nelle tabelle dei documenti e dei movimenti. In generale è stato aggiunto il campo “Dimension Set ID” in tutte le tabelle di movimenti o documenti provvisori a qui si possono associare dimensioni come ad esempio la tabella 36 “Sales Header”, 37 “Sales Line”, 81 “Gen. Journal Line” (etc ..), ma anche nelle tabelle definitive come la tabella 112 “Sales Invoice Header”, 113 “Sales Invoice Line”, 17 “G/L Entry” (etc ..).

Per chi cancella documenti registrati in assistenza per i propri clienti non avrà più bisogno di cancella i movimenti contabili dimensioni ed i Posted document dimension!


In pratica

Da un documento di tipo ordine di acquisto ad esempio, in testata cliccando sul pulsante Dimensioni succede questo:

  1. Il codice nella voce “Dimension” nelle PageAction della pagina 50 “Purchase Order” richiama una Funzione chiamata “ShowDocDim” presente in tabella 38 “Purchase Header”.
  2. il  codice nella funzione “showDocDim” richiama la funzione “EditDimensionSet2” presente in Codeunit 408 “DimensionManagement” passandoli come argomento l’Id Set di dimensione corrente presente in testata del documento (passa 0 se non ci sono dimensioni associate al documento), il secondo argomento è un valore testo descrittivo di dove si apre la finestra (sarà usato per il titolo della finestre delle dimensioni del documento), il terzo argomento è il valore della dimensione 1 presente in testata del documento ed il quarto argomento è il valore della dimensione 2 presente in tabella.La funziona torna un Id Set Di dimensione, se le fasi successive lo trovano restituisce quel Id seno restituisce l’id creato dalle fasi successive.
  3. Il codice nella codeunit 408 restituisce l’ Id set di dimensioni trovato o creato dal richiamo alla funzione “GetDimensionSetID” presente in tabella 480 “Dimension Set Entry”, passandoli il set di dimensione corrente. Per quanto mi riguarda avrei evitato questo passaggio che trovo superfluo, si poteva richiamare direttamente la funzione della tabella 480 o riportare il suo codice nella codeunit 408 nella medesima funzione “EditDimensionSet2”. Ma è un mio punto di vista personale.
  4. Ecco dove la vera gestione del set di dimensione si effettua.
    1. Per cominciare si fa una copia del set corrente nella variabile DimSetEntry2.
    2. Se il set corrente possiede un ID “Dimension Set Id” la procedura filtra il set corrente per quel ID.
    3. Per non prendere in considerazione i possibili valori blank si filtra (Dimension Code e Dimension Value code diverso da Blank) per escluderli.
    4. Se il set corrente è vuoto restituisce l’id 0 che sarà assegnato al documento di acquisto in alto allo stack di chiamate.
    5. Per ricercare la combinazione di dimensione nella tabella “Dimension Set Entry”, la procedura usa la tabella 481 “Dimension Set Tree Node” che nidifica le dimensioni tra di loro. A questo proposito, l’identificazione di una copia Codice Dimensione e Valore dimensione avviene tramite il nuovo campo “Dimension Value Id”, di tipo intero creato nella tabella “Dimension Value”, il campo si autoincrementa assegando così un valore univoco alla copia Codice Dimensione Valore dimensione, agevolandone la ricerca. Si può dire anche che il medesimo campo definisce l’ordine di creazione delle dimensioni in modo generale, se un utente crea il valore dimensione PROGETTO12 della dimensione COMMESSA, il sistema assegnerà un ID progressivo ad esempio 34, se successivamente un utente crea un valore dimensione AMMINISTRAZIONE della dimensione REPARTO il sistema assegnerà il valore di ID 35.
      La procedura cicla il Set di dimensioni corrente ordinato per “Dimension Value Id” (ordine di creazione dei valori dimensioni), e per ciascun record ne cerca la sua presenza nella tabella “Dimension Set Tree Node” cominciando dal livello di nidificazione più basso, 0.
      1. La tabella “Dimension Set Tree Node” contiene i collegamenti di dimensioni a più livelli. La chiave primaria definisce il livello di collegamento “Parent Dimension Set ID” ed il valore di copia Codice dimensione e valore dimensione “Dimension Value ID”.
      2. Basta quindi cercare il primo figlio del valore dimensione corrente nell’albero usando il proprio “Dimension Set ID”, ricordo che la prima volta è uguale a 0 per poter trovare il livello più basso della combinazione dimensioni.
      3. Se non viene trovato il valore nell’albero, la procedura lo crea assegnandoli un valore progressivo al campo “Dimension Set ID”. La procedura inserisce la combinazione di dimensione corrispondente al set di dimensione nella tabella 480 solo se il ciclo dell’intero set di dimensioni è concluso e non è stato trovato un ID di set nella tabella 481. Questo significa che se non esistevano gli ID Set di dimensioni delle combinazioni intermedie, la procedura le crea nella tabella 481 ma inserisce solo l’ultimo livello nella tabella 480 contrassegnandolo come “In Uso”.
    6. Alla fine del ciclo la funzione restituisce l’Id di set di dimensione Trovato come ultimo livello nella tabella 481 o l’ultimo Id di Set di dimensione creato ed inserito in tabella 480.




Esempio di ricerca nella tabella 481

Supponiamo di avere il set di dimensione seguente associato ad un ordine di vendita, ordinato per Id di Valore dimensione:
Dimension Value ID
Dimension Code
Dimension Value
Dimension No.
34
COMMESSA
PROGETTO12
Global Dim. 2
35
REPARTO
AMMINISTRAZIONE
Dimensione 2
39
PRODOTTO
HONEY
Dimensione 4

Vediamo come la funzione GetDimensionSetId trova o crea l’Id del Set per poterlo associare al documento.
Prima di tutto impostiamo il livello 0 al primo record della tabella 481:
DimSetTreeNode."Dimension Set ID" := 0;

  1. Cominciamo il ciclo sul set di dimensioni ordinato per Dimension Set ID.
  2. Per ciascun record si cerca la sua presenza in tabella 481
    La ricerca viene fatta per “Parent Dimension Set ID” e “Dimension Value ID”.
    1. La prima volta l’Id Padre sarà uguale a 0 mentre l’id valore dimensione sarà uguale a 34.
      1. Se è presente il record, sapremo il suo id di set dimensione (vedere campo Dimension Set ID) dove la copia COMMESSA e PROGETTO12 è presente da sola, senza altre dimensioni. In pratica dove la copia rappresenta un set di dimensione. Non è detto che quel set è presente in tabella 480 dato che può essere un set di dimensione intermedio mai usato, in quel caso il Flag “In Use” non è contrassegnato.
      2. Se non è presente il record viene creato assegando il valore di 0 al campo autoincrementato "Dimension Set ID", ed il valore dell’id padre che in questo caso è 0 perché è il primo giro.
    2. Dal secondo giro, l’Id padre è uguale a 34 (ID valore dimensione della prima riga del set corrente) mentre l’id valore è uguale a 35. Cerchiamo il collegamento della dimensione REPARTO AMMINISTRAZIONE alla DIMENSIONE COMMESSA PROGETTO12.
      1. Se è presente il record, sapremo l’Id del set costituito dalla copia REPARTO AMMINISTRAZIONE e DIMENSIONE COMMESSA PROGETTO12.
      2. Se non è presente viene creato assegando il valore dell’id di set Precedentemente creato dal campo autoincrementato al primo giro e non in uso come padre, 35 come Id valore dimensione ed incrementando l’id del set corrente.
    3. A fine ciclo è restituito l’ultimo Id creato o trovato come ID del Set di dimensione corrente e vengono copiate le righe del set nella tabella 480 identificate tramite quel ID.


La tabella Dimension Set TreeNode dopo il processo:
Parent Dimensiojn Set ID
Dimension Value Id
Dimension Set ID (Auto Increment)
In Uso (Sì = Set prensente in 481, = No Set intermedio)
0
34
120 (Esempio)
No
120
35
134
No
134
39
210

In quest’esempio l’Id sarà 210.

La tabella 480 dopo il processo:
Dimension Set Id
Dimension Code
Dimension Value
Dimension Value ID
210
COMMESSA
PROGETTO12
34
210
REPARTO
AMMINISTRAZIONE
35
210
PRODOTTO
HONEY
39






Petrantoni Virgile
MCTS – Dynamics
MCSD.Net
MCTS – Sql Server 2008
http://www.novalysis.it/Software/Dynamics%20Nav/
http://www.linkedin.com/pub/virgile-petrantoni/1a/66a/b9a

Nessun commento:

Posta un commento