Las dimensiones analiticas de MS Dynamics AX no tienen exactamente el mismo funcionamiento que las dimensiones de un data warehouse, pero comparten el objetivo analítico, y la clasificación de los hechos, que en el ERP son transacciones.

Por tanto, las dimensiones analíticas de AX pueden aportar información muy interesante a aplicaciones de Business Intelligence, que además aportan más flexibilidad a la hora de analizar hechos y datos agrupados.

En el foro de QlikView he encontrado este script que comparto aquí para importar en QlikView las dimensiones de MS AX directamente a partir de las tablas de datos del ERP.

Dimensiones
LOAD DESCRIPTION AS [Dimension1],
NUM AS [DIM1];
SQL SELECT DESCRIPTION,
NUM
FROM "AXBD_Soporte".dbo.DIMENSIONS
WHERE (DIMENSIONCODE = 0);

LOAD DESCRIPTION AS [Dimension 2],
NUM AS [DIM2];
SQL SELECT DESCRIPTION,
NUM
FROM “AXBD_Soporte”.dbo.DIMENSIONS
WHERE (DIMENSIONCODE = 1);

LOAD DESCRIPTION AS [Dimension 3],
NUM AS [DIM3];
SQL SELECT DESCRIPTION,
NUM
FROM “AXBD_Soporte”.dbo.DIMENSIONS
WHERE (DIMENSIONCODE = 2);

LOAD DESCRIPTION AS [Dimension 4],
NUM AS [DIM4];
SQL SELECT DESCRIPTION,
NUM
FROM “AXBD_Soporte”.dbo.DIMENSIONS
WHERE (DIMENSIONCODE = 3);

LOAD DESCRIPTION AS [Dimension 5],
NUM AS [DIM5];
SQL SELECT DESCRIPTION,
NUM
FROM “AXBD_Soporte”.dbo.DIMENSIONS
WHERE (DIMENSIONCODE =4);

LOAD DESCRIPTION As [Dimension 6],
NUM AS [DIM6];
SQL SELECT DESCRIPTION,
NUM
FROM “AXBD_Soporte”.dbo.DIMENSIONS
WHERE (DIMENSIONCODE = 5);

LOAD DESCRIPTION AS [Dimension 7],
NUM As [DIM7];
SQL SELECT DESCRIPTION,
NUM
FROM “AXBD_Soporte”.dbo.DIMENSIONS
WHERE (DIMENSIONCODE = 6);

LOAD DESCRIPTION AS [Dimension 8],
NUM AS [DIM8];
SQL SELECT DESCRIPTION,
NUM
FROM “AXBD_Soporte”.dbo.DIMENSIONS
WHERE (DIMENSIONCODE = 7);

LOAD DESCRIPTION AS [Dimension 9],
NUM AS [DIM9];
SQL SELECT DESCRIPTION,
NUM
FROM “AXBD_Soporte”.dbo.DIMENSIONS
WHERE (DIMENSIONCODE = 8);

LOAD DESCRIPTION AS [Dimension 10],
NUM AS [DIM10];
SQL SELECT DESCRIPTION,
NUM
FROM “AXBD_Soporte”.dbo.DIMENSIONS
WHERE (DIMENSIONCODE = 9);

Transacciones Contables:
LOAD ACCOUNTNUM AS [CÛdigo de cuenta contable],
TRANSDATE AS [Fecha de la transacciÛn],
AMOUNTCUR,
DIMENSION AS DIM1,
“DIMENSION2_” AS DIM2,
“DIMENSION3_” AS DIM3,
“DIMENSION4_” AS DIM4,
“DIMENSION5_” AS DIM5,
“DIMENSION6_” AS DIM6,
“DIMENSION7_” AS DIM7,
“DIMENSION8_” AS DIM8,
“DIMENSION9_” AS DIM9,
“DIMENSION10_” AS DIM10,
DOCUMENTDATE AS [Fecha del documento],
CORRECT AS [CorrecciÛn],
CREDITING AS [TransacciÛn de crÈdito],
PERIODCODE AS [CÛdido de tipo de transacciÛn],
PAYMMODE,
upper(DATAAREAID) AS [CÛdigo de empresa];
SQL SELECT ACCOUNTNUM,
TRANSDATE,
AMOUNTCUR,
DIMENSION,
“DIMENSION2_”,
“DIMENSION3_”,
“DIMENSION4_”,
“DIMENSION5_”,
“DIMENSION6_”,
“DIMENSION7_”,
“DIMENSION8_”,
“DIMENSION9_”,
“DIMENSION10_”,
DOCUMENTDATE,
CORRECT,
CREDITING,
PERIODCODE,
PAYMMODE,
DATAAREAID
FROM “AXBD_Soporte”.dbo.LEDGERTRANS
ORDER BY TRANSDATE ASC;

Para poder utilizar la página principal del role center sin instalar sharepoint y conectarnos a otra web, por ejemplo google.es
Captura_I

Debemos crear un registro en las siguentes tablas “EPWebSiteParameters” y “EPGlobalParameters”, esto lo haremos a través del AOT.

Al registrar la URL principal usaremos este valor “http:/” el sistema por defecto nos colocara la siguiente barra “/” y el link de nuestro role center completando la dirección final con la empresa.

El aspecto de la url seria “http://www.google.es/webhp?WCMP=001”, podemos incluso reciclar los parámetros de entrada.

web_configprofilesEP_XPO

Al instalar la versión 2012 R2 debemos tener cuidado y configurar todo la funcionalidad de países y de módulos antes de generar las empresas. Si no lo hacemos así pueden crearse valores NULL en la companyinfo(DirpartyTable) en esta nueva versión y provocar un error de lectura que no podemos solventar con el control standard que existe en configuración. La única solución es limpiar estos NULL una vez se ha configurado la aplicación.

UPDATE DBO.DIRPARTYTABLE
SET DIRPARTYTABLE.QUIEDIES = ” ,
DIRPARTYTABLE.VATNUM = ”,
DIRPARTYTABLE.IMPORTVATNUM = ”,
DIRPARTYTABLE.INTRASTATCODE = ”,
DIRPARTYTABLE.PACKMATERIALFEELICENSENUM = ”,
DIRPARTYTABLE.TAXREPRESENTATIVE = ”,
DIRPARTYTABLE.ISELIMINATIONCOMPANY = ”,
DIRPARTYTABLE.ACCOUNTINGPERSONNEL_JP = ”,
DIRPARTYTABLE.COMPANYREPRESENTATIVE_JP = ”,
DIRPARTYTABLE.TAXAUTHORITY_RU = ”,
DIRPARTYTABLE.OMOPERATINGUNITTYPE = ”,
DIRPARTYTABLE.HCMWORKER = ”,
DIRPARTYTABLE.ISCONSOLIDATIONCOMPANY = ”

WHERE DIRPARTYTABLE.DATAAREA IS NOT NULL

SELECT * FROM DBO.DIRPARTYTABLE
WHERE DIRPARTYTABLE.DATAAREA IS NOT NULL

Las Dimensiones analíticas de Microsoft Dynamics AX son básicas para la parte analítica del ERP, especialmente en el área financiera.

Se pueden utilizar hasta 10 dimensiones, aunque normalmente sólo se utilizan 3. Una vez definidas, las transacciones ya se registran con el identificador de la/s dimensión/es que correspondan, y después se pueden realizar analíticas agrupando por estas dimensiones.

No son exactamente las mismas dimensiones que conocemos en entornos de Data warehouse, pero el objetivo es parecido.

Para informar correctamente las tablas de dimensiones se puede utilizar un fichero csv que defina las dimensiones analíticas que se van a utilizar, y el código de ejemplo que se adjunta a continuación para realizar la carga:

Carga desde un fichero CSV

Import Dynamics Ax dimensions 2012 R2 from csv file

/*

Canal;a-110;Directo;XXX
Canal;b-210;Nets;XXX
Canal;c-220;Retail;XXX

*/

server static void axl_CargaDimension(Args _args)
{
#define.RMode(‘R’)
container     line;
#define.LineBreak(‘\r\n’)
asciiio asciiFile;
str typoD;
str descD;
str dimD;
str LedgerDimension_1= “”;
str LedgerDimension_2= “”;
str LedgerDimension_3=””;
str LedgerDimension_4=””;
str LedgerDimension_5=””;
str LedgerDimension_6=””;
str LedgerDimension_7=””;
LedgerJournalAC LedgerJournalAC;
container  defaultdim;

#AXLDimensions
RecId                               ret;

DimensionAttributeValueSetStorage   dimStorage;
DimensionAttributeValue             dimensionAttributeValue;
DimensionAttribute                  dimensionAttribute;

DimensionAttributeValue CreateifNotExist(dimensionAttribute _dimensionAttribute, dimensionvalue LedgerDim, str Description)
{
dimensionAttributeValue dimensionAttributeValue_ins;
DimensionFinancialTag DimensionFinancialTag;
;
select firstOnly1 * from DimensionFinancialTag
where DimensionFinancialTag.Value == LedgerDim
&& DimensionFinancialTag.FinancialTagCategory == _dimensionAttribute.financialTagCategory();
if (!DimensionFinancialTag)
{
DimensionFinancialTag.Value = LedgerDim;
DimensionFinancialTag.Description = Description;
DimensionFinancialTag.FinancialTagCategory= _dimensionAttribute.financialTagCategory();
DimensionFinancialTag.insert();
}
else
{
DimensionFinancialTag.Description = Description;
DimensionFinancialTag.skipTTSCheck(true);
DimensionFinancialTag.doUpdate();
}

return DimensionAttributeValue::findByDimensionAttributeAndEntityInst(_dimensionAttribute.RecId, DimensionFinancialTag.RecId, true, true);
}

;

//BP Deviation Documented
asciiFile = new AsciiIo(‘C:\\\\Dimensiones Analíticas.csv’,’r’);

if (asciiFile)
{
if (asciiFile.status())
{
throw error(“@SYS95706”);
}
else
{
asciiFile.inFieldDelimiter(‘;’);
asciiFile.inRecordDelimiter(‘\r\n’);

while (asciiFile.status() == IO_Status::Ok)
{
line = asciiFile.read();

if (conlen(line) != 0 )
{
typoD = conpeek(line,1);
dimD  = conPeek(line,2);
descD = conPeek(line,3);
LedgerDimension_1= “”;
LedgerDimension_2= “”;
LedgerDimension_3=””;
LedgerDimension_4=””;
LedgerDimension_5=””;
LedgerDimension_6=””;
LedgerDimension_7=””;
switch (typoD)
{
case “Canal”:
LedgerDimension_4 = dimD;
break;
case “Producto”:
LedgerDimension_3 = dimD;
break;
case “ZonaGeográficaGeográfica”:
LedgerDimension_7 = dimD;
break;
case “CentroDeCoste”:
LedgerDimension_2 = dimD;
break;
case “Cliente”:
LedgerDimension_5 = dimD;
break;
case “Proyecto”:
LedgerDimension_6 = dimD;
break;

}

if ( LedgerDimension_2 ||
LedgerDimension_3 ||
LedgerDimension_4 ||
LedgerDimension_5 ||
LedgerDimension_6 ||
LedgerDimension_7
)
{
dimStorage              = new DimensionAttributeValueSetStorage();

if (LedgerDimension_4)
{
dimensionAttribute      = AxdDimensionUtil::validateFinancialDimension(#Canal);
DimensionAttributeValue = CreateifNotExist(dimensionAttribute,LedgerDimension_4,descD);
dimensionAttributeValue = AxdDimensionUtil::validateFinancialDimensionValue(dimensionAttribute, LedgerDimension_4);
dimStorage.addItem(dimensionAttributeValue);
}
if (LedgerDimension_2)
{
dimensionAttribute      = AxdDimensionUtil::validateFinancialDimension(#CentroCoste);
DimensionAttributeValue = CreateifNotExist(dimensionAttribute,LedgerDimension_2,descD);
dimensionAttributeValue = AxdDimensionUtil::validateFinancialDimensionValue(dimensionAttribute, LedgerDimension_2);

dimStorage.addItem(dimensionAttributeValue);
}
if (LedgerDimension_5)
{
dimensionAttribute      = AxdDimensionUtil::validateFinancialDimension(#Cliente);
CreateifNotExist(dimensionAttribute,LedgerDimension_5,descD);
dimensionAttributeValue = AxdDimensionUtil::validateFinancialDimensionValue(dimensionAttribute, LedgerDimension_5);

dimStorage.addItem(dimensionAttributeValue);
}
if (LedgerDimension_3)
{
dimensionAttribute      = AxdDimensionUtil::validateFinancialDimension(#Producto);
CreateifNotExist(dimensionAttribute,LedgerDimension_3,descD);
dimensionAttributeValue = AxdDimensionUtil::validateFinancialDimensionValue(dimensionAttribute, LedgerDimension_3);

dimStorage.addItem(dimensionAttributeValue);
}
if (LedgerDimension_6)
{
dimensionAttribute      = AxdDimensionUtil::validateFinancialDimension(#Proyecto);
CreateifNotExist(dimensionAttribute,LedgerDimension_6,descD);
dimensionAttributeValue = AxdDimensionUtil::validateFinancialDimensionValue(dimensionAttribute, LedgerDimension_6);

dimStorage.addItem(dimensionAttributeValue);
}
if (LedgerDimension_7)
{
dimensionAttribute      = AxdDimensionUtil::validateFinancialDimension(#ZonaGeografica);
CreateifNotExist(dimensionAttribute,LedgerDimension_7,descD);
dimensionAttributeValue = AxdDimensionUtil::validateFinancialDimensionValue(dimensionAttribute, LedgerDimension_7);

dimStorage.addItem(dimensionAttributeValue);
}
ret = dimStorage.save();
}
}//if
}//while
}//if
}//if
pause;
}

Para corregir este problema en la visualización de los informes para AX 2012

Install_BID

Sqlserver2008_express

Es necesario instalar esta opción del sqlserver, en mi caso desde la versión express .

 

 

 

Create or update dimensiodefault for ledger account

public refrecid CreateBudgerDimension()
{
#AXLDimensions
str parm;
container _dimensionValue, c;
RefRecId dimensiondefault;
int Ndims = 0;
int Nline;
;
Parm =  strFmt(‘%1-%2-%3-%4-%5-%6-%7’,this.LedgerAccount,
this.LedgerDimension_4,
this.LedgerDimension_2,
this.LedgerDimension_5,
this.LedgerDimension_3,
this.LedgerDimension_6,
this.LedgerDimension_7
);

// Main account
/*
_dimensionValue =  [Parm,this.LedgerAccount,
1,#Canal,this.LedgerDimension_4,
2,#CentroCoste,this.LedgerDimension_2,
3,#Cliente,this.LedgerDimension_5,
4,#Producto,this.LedgerDimension_3,
5,#Proyecto, this.LedgerDimension_6,
6,#ZonaGeografica,this.LedgerDimension_7];
*/
_dimensionValue = conNull();
_dimensionValue = conIns(_dimensionValue,1, Parm,this.LedgerAccount);

if(this.LedgerDimension_4 != “”)
{
Ndims ++;
_dimensionValue = conIns(_dimensionValue,4 ,#Canal,this.LedgerDimension_4);
}
if(this.LedgerDimension_2 != “”)
{
Ndims++;
_dimensionValue = conIns(_dimensionValue,6, #CentroCoste,this.LedgerDimension_2);
}
if(this.LedgerDimension_5 != “”)
{
Ndims++;
_dimensionValue = conIns(_dimensionValue,8, #Cliente,this.LedgerDimension_5);
}
if(this.LedgerDimension_3 != “”)
{
Ndims++;
_dimensionValue = conIns(_dimensionValue,11, #Producto,this.LedgerDimension_3);
}
if(this.LedgerDimension_6 != “”)
{
Ndims++;
_dimensionValue = conIns(_dimensionValue,14, #Proyecto, this.LedgerDimension_6);
}
if(this.LedgerDimension_7 != “”)
{
Ndims++;
_dimensionValue = conIns(_dimensionValue,17, #ZonaGeografica,this.LedgerDimension_7);
}
_dimensionValue = conIns(_dimensionValue,3, Ndims);

//dimensiondefault = AxdDimensionUtil::getDimensionAttributeValueSetId(_dimensionValue);
dimensiondefault= AxdDimensionUtil::getLedgerAccountId(_dimensionValue);

this.LedgerDimension = dimensiondefault;
return dimensiondefault;
}

 

Solución RFID completa en español, permite la recepción de pallets completos, reabastecimientos, picking, desplazar pallets completos y salidas de pallets completos.

El sistema arranca de forma automática la pantalla inicial marcando un valor en las opciones de usuario.

Está diseñada para funcionar a través de terminal server y lectores rfid psion

 

RFID

 

SharedProject_AXL_RFID

Como crear up popup contextual en Ax 2009

 

.

 

popup.rar

 

[singlepic id=2 w=320 h=240 float=]

 

http://twit88.com

 

QR_code

La api de google nos permite la instalación de forma sencilla de vistosos cuadros de mando.

[singlepic id=1 w=320 h=240 mode=web20 float=center]

example AX2009 – Google_charts.rar

http://code.google.com/intl/es-ES/apis/chart/