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:
- Il codice nella voce “Dimension” nelle PageAction della pagina 50 “Purchase Order” richiama una Funzione chiamata “ShowDocDim” presente in tabella 38 “Purchase Header”.
- 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.
- 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.
- Ecco dove la vera gestione del set di dimensione si effettua.
- Per cominciare si fa una copia del set corrente nella variabile DimSetEntry2.
- Se il set corrente possiede un ID “Dimension Set Id” la procedura filtra il set corrente per quel ID.
- Per non prendere in considerazione i possibili valori blank si filtra (Dimension Code e Dimension Value code diverso da Blank) per escluderli.
- Se il set corrente è vuoto restituisce l’id 0 che sarà assegnato al documento di acquisto in alto allo stack di chiamate.
- 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. - 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”.
- 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.
- 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”.
- 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;
- Cominciamo il ciclo sul set di dimensioni ordinato per Dimension Set ID.
- Per ciascun record si cerca la sua presenza in tabella 481
La ricerca viene fatta per “Parent Dimension Set ID” e “Dimension Value ID”. - La prima volta l’Id Padre sarà uguale a 0 mentre l’id valore dimensione sarà uguale a 34.
- 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.
- 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.
- 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.
- Se è presente il record, sapremo l’Id del set costituito dalla copia REPARTO AMMINISTRAZIONE e DIMENSIONE COMMESSA PROGETTO12.
- 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.
- 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
|
Sì
|
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