programación

Microsoft Dynamics AX, ¿Por dónde empiezo?

Introducción

La documentación existente en la red sobre desarrollo en Microsoft Dynamics AX es abundante, aunque a menudo mal estructurada, lo que puede ser un problema al principio, si alguien decide aprender a programar AX por su cuenta.

Como introducción se puede consultar el artículo correspondiente de Wikipedia, donde se encuentra una breve historia del producto (antes llamado Axapta), un resumen de los módulos funcionales mas importantes, versiones, arquitectura, y una introducción a su IDE de desarrollo: MorphX y su lenguaje de programación: X++

 

Libros

El libro Morph IT es probablemente el primer libro sobre desarrollo en AX, escrito bajo la version AX 3.0 SP4 prácticamente todo el contenido sigue siendo válido en AX 4 y 2009, salvo pequeños detalles fácilmente identificables. Es para mi opinión el mejor para empezar, y es gratis.

La serie "Inside Microsoft Dynamics AX" está escrita directamente por los desarrolladores de AX, tiene un nivel mas alto que el primero y es un libro ideal para consolidar los conocimientos de cualquier desarrollador AX, muy recomendables. El primero se puede descargar gratuítamente en PDF, el segundo sólo existe en versión papel y es prácticamente imposible encontrarlo en librerías españolas.

 

Recursos Web

 

comunidades, blogs, foros, ...

 

PartnerSource, CustomerSource y certificación

El acceso a PartnerSource/CustomerSource da acceso a la descarga de materiales de los cursos oficiales de certificación de Microsoft que es, probablemente, la mejor documentación disponible para el aprendizaje de AX, así como el acceso a toda la documentación que Microsoft publica sobre el producto (WhitePapers, Manuales, herramientas, etc, ...).

El acceso a estos portales depende del contrato de licencia del que se disponga con Microsoft tanto si se es Cliente, como Partner.

Sin votos aún

AX 2009 EP Development CookBook

Ayer, el equipo del Enterprise Portal Blog publicó un resumen-guía de desarrollo en Enterprise Portal. que han llamado AX 2009 EP Development CookBook Un completo artículo en formato imprimible de casi 40 páginas muy interesante y gratuíto para su descarga desde aquí:

Sin votos aún

HOWTO: AX - Distribuir ficheros con SysFileDeployment

A veces es util poder distribuir a los clientes de AX ficheros auxiliares que van a necesitar para la ejecución del programa, por ejemplo, controles ocx, librerias dll, iconos, imágenes, etc.

Gracias a André Arnaud, que amablemente respondió a una duda mía en los foros de la Microsoft Dynamics Community he descubierto el framework de AX SysFileDeployment que viene perfecto para esta tarea.

La idea de este framework es heredar clases para indicar a AX qué ficheros deben copiarse a la parte cliente cada vez que se realiza una nueva instalación de AX. Este framework tiene bastantes limitaciones pero la ventaja es que en su código se gestiona bastante bien el tema de permisos para copiar ficheros situados en el servidor hacia el cliente.

Comparto las pruebas que yo he realizado por si a alguien le pudieran servir. En primer lugar, hay que generar una nueva clase heredada de SysFileDeploymentFile indicando a AX qué fichero hay que copiar, dónde esta y hacia donde copiarlo. Esta es la estructura básica de la clase heredada, que esta bien autodocumentada por si se necesita mas personalización:

class SysFileDeploymentFileJAEEIcon extends SysFileDeploymentFile
{
	public Filename filename()
	{
		return 'jaestevan.png';
	}
 
	//AOSRunMode::Server
	protected FilenameOpen sourcePath()
	{
		return "C:\\Archivos de programa\\Microsoft Dynamics AX\\50\\Application\\Share\\Include\\";
	}
 
	//AOSRunMode::Client
	protected FilenameSave destinationPath()
	{
		return xInfo::directory(DirectoryType::Include);
	}
}

Una de las limitaciones de este framework es que sólo se ejecuta la primera vez que se ejecuta el cliente en un equipo determinado. Por tanto para distribuir nuevos ficheros o para hacer pruebas, como es mi caso, habría que modificar el método applBuildNo() de la clase ApplicationVersion, para forzar al sistema a actualizar la versión. Haciéndolo de este modo, AX detectará que tenemos ficheros pendientes de actualizar en el servidor y nos mostrará el siguiente diálogo:

SysFileDeploymentFile

Como no me apetecía andar modificando la build de mi entorno de pruebas, he hecho un pequeño Job que simula el código que se ejecutaría automáticamente de manera normal:

static void JAEE_SysFileDeployment(Args _args)
{
    container           classes;
    SysFileDeployment   sysFileDeployment;
    container           classVersion;
    classId             classId;
    ;
 
    classId = classNum(SysFileDeploymentCesserIcon);
    sysFileDeployment = classfactory.createClass(classId);
    classes += [[classId,sysFileDeployment.getServerVersion()]];
 
    classVersion = conpeek(classes, 1);
    classId = conpeek(classVersion, 1);
 
    sysFileDeployment = classfactory.createClass(classId);
    sysFileDeployment.setServerVersion(conpeek(classVersion, 2));
    sysFileDeployment.run();
}

Otra de las desventajas es que parece que esta clase no funciona demasiado bien en AX 4. Yo las pruebas que acabo de hacer en 2009 SP1 sí han funcionado, salvo un pequeño problema con las rutas de origen/destino, supongo que por ejecutar todo el entorno en la misma máquina (cliente, aplicación, AOS, ..).

A partir de aquí que cada uno investigue lo que necesite.

Sin votos aún

HOWTO: AX - Expandir LMAT por código

AX nos deja expandir, o explotar, una línea de lista de materiales (L.MAT, o BOM en inglés) de manera que podamos manejar sus elementos al mismo nivel que el artículo L.MAT. La funcionalidad se llama Expandir L.MAT y la podemos ver, por ejemplo, en las líneas de un pedido:

Explode BOM | Expandir L.MAT

Esta función nos presenta un formulario para elegir las líneas que queremos "Explotar" fuera de la lista de materiales para su tratamiento:

Explode BOM | Expandir L.MAT

El código que este formulario ejecuta para realizar la expansión de la L.MAT se encuentra, en el caso de líneas de pedido de venta, en la tabla SalesLine) concretamente en el método: SalesLine.expandBOM(), por tanto para simular esta funcionalidad en X++, el mínimo código que podemos utilizar es el siguiente:

static void expandirLineaLMAT(Args _args)
{
    TmpFrmVirtual       tmpFrmVirtual;
                                          // Línea de la LMAT que se quiere expandir
    BOM                 tmpBOM          = BOM::findRecId(5637146401, false);    
                                          // Línea de venta desde la que expandir
    SalesLine           auxSalesLine    = SalesLine::find('00000003_050', 3, true);
    ;
 
    // Registro temporal que marca la línea a expandir
    tmpFrmVirtual.TableNum = tablenum(BOM);
    tmpFrmVirtual.RecordNo = tmpBOM.RecId;
    tmpFrmVirtual.write();
 
    // Expande la LMAT y genera la línea de venta nueva (función estándar)
    auxSalesLine.expandBOM(tmpFrmVirtual, tmpBOM);
 
    // la nueva línea de venta puede necesitar modificaciones despues de este proceso
}

y digo mímino porque la línea se insertará con la mayoría de sus opciones por defecto, por lo que es seguro que habra que añadir código extra para completar los datos necesarios según las necesidades.

Sin votos aún

Traducción automática de etiquetas con BING

El pasado viernes Arijit Basu publicó en su blog un experimento, mediante el cual explicaba brevemente como utilizar el servicio web publicado por Microsoft de su producto BING para traducir cadenas de texto desde AX.

Este artículo me llevo a una idea propia de como sacarle utilidad a esa funcionalidad. Cuando uno trabaja en un entorno con varios idiomas, puede ser útil que al generar una etiqueta en nuestro idioma, se generen automáticamente el resto de idiomas ya traducidos.

Yo no he llegado tan lejos (todavía) pero he hecho una pequeña aproximación que paso a compartir, este es el resultado:

InfoLog Result

despues de ejecutar el Job:

/*
    JAEE - www.jaestevan.com
 
    @created 10/10/2009 tested in AX2009 SP1
*/
static void MicrosoftTranslatorTest(Args _args)
{
    MicrosoftTranslator msTrans = new MicrosoftTranslator();
    ;
    msTrans.createLabel("Ahora axapta puede traducir etiquetas! (jaestevan.com)", "es");
}

Desde aquí (AX class is documented in english too) se puede descargar un fichero XPO con la clase que paso a comentar. En la construcción de la clase indicamos nuestro código de BING (el cual se solicita en su web de forma gratuíta e instantanea) así como una lista de los idiomas que queremos traducir, indicando el código de idioma de AX así como el código del idioma en BING (usualmente el mismo). Por ultimo y de manera opcional podemos indicar el fichero de etiquetas donde se generarán, aunque por defecto utilizaremos el módulo por defecto por lo que este parámetro es opcional. Este es el método en cuestión:

 

void new(LabelModuleId _modulo = SysLabel::defaultModuleId())
{
    // Axapta Label Module Id
    moduleId = _modulo;
 
    // Microsoft BING AppID - http://www.bing.com/developers
    appId = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
 
    // List of languages to translate (AX lang, BING lang) (Idiomas a traducir)
    transLang = new Map(Types::String, Types::String);
    transLang.insert('de','de');
    transLang.insert('ru','ru');
    transLang.insert('en-us','en-us');
    transLang.insert('fr','fr');
}

Esta es la manera de configurar la clase para su uso (si bien está construida para ser un ejemplo, no para servir de cualquier utilidad real).

El kit de la cuestión lo encontramos en el siguiente método, el cual genera la etiqueta (si no existe) en el idioma predeterminado y luego busca la traducción en BING para todos los idiomas configurados en la clase:

public void createLabel(str _txt, str _txtLang)
{
    MapEnumerator       langEnum;
    Label               l;
    str                 res;
 
    LabelId             labelId;
    SysLabelEdit        labelEd     = new SysLabelEdit();
    SysLabel            sysLabel    = new SysLabel('es');
    ;
 
    // Find or create the label (busca la etiqueta y si no existe la crea)
    labelId = labelEd.findLabel(_txtLang, _txt);
    if (!labelId)
    {
        sysLabel.insert(_txt, _txt, this.parmModuleId());
        labelId = labelEd.findLabel(_txtLang, _txt);
    }
 
    //Log
    InfoLog.add(Exception::Info, strfmt("Traduciendo: (%1) %2", _txtLang, _txt));
 
    // Update the label for each language (actualiza la etiqueta para cada idioma)
    langEnum = new MapEnumerator(this.parmLangs());
    while (langEnum.moveNext())
    {
        // Call to translate (función de traducir)
        res = this.strTranslate(_txt, _txtLang, langEnum.currentValue());
 
        // Modify label with new translated text (modifica la etiqueta con el texto traducido)
        labelEd.labelModify(langEnum.currentValue(), labelId, res, _txt, SysLabelApplModule::None, true);
 
        // Log
        InfoLog.add(Exception::Info, strfmt("(%1) %2", langEnum.currentKey(), res));
    }
 
}

El trabajo de integrar esta funcionalidad con el editor de etiquetas estándar queda pendiente para otra entrega.

Enlaces

* Proyecto XPO de ejemplo
* BING Developer Centre
* Arijit Basu's blog

Sin votos aún

X++ y MSIL

Publicaba en este blog el mes pasado que en la próxima versión de AX, el desarrollo de Enterprise Portal pasa a realizarse exclusivamente sobre Visual Studio. En la actual versión de AX, la 2009, ya podemos usar Visual Studio para desarrollar reports integrados en SQL Server Reporting Services, y desde varias versiones atrás AX publica cubos OLAP sobre servidores SQL Server Analysis Services. Lo que viene a confirmar la intención de integrar AX en el resto de sus productos de area empresarial, así como consolidar tecnologías concretas para trabajos concretos. Es inevitable mirar atrás y acordarse del "Proyect Green"

En otro paso mas en el acercamiento de la tecnología AX hacia .NET, hace unas semanas se publicó un video en Channel 9  mostrando el trabajo del equipo de desarrollo de AX orientado a la generación de código intermedio MSIL (Microsoft Intermediate Language). Si bien anuncian que este trabajo no se verá implementado en la próxima versión de AX, de llegar a completarse sería un avance importante en cuanto al rendimiento y a las posibilidades de integración de futuras versiones del producto.

Sin votos aún

Se acaba X++ en Enterprise Portal

Microsoft anuncia retirar en la siguiente versión de Axapta el interfaz X++ para el desarrollo de Enterprise Portal, sustituido en la última version AX 2009 por el interfaz ASP.NET.

Se puede consultar el anuncio en Partner Source y Customer Source

Aprovecho la entrada para enlazar un documento interesante sobre el mismo tema publicado recientemente: White Paper: Overview of Enterprise Portal

Sin votos aún

HOWTO: AX - Modificar el menu contextual de un objeto

Al hacer "click derecho" sobre un objeto en Dynamics Axapta se ejecuta el metodo showContextMenu, el cual como siempre, podemos sobrecargar. Esta es la pinta que tiene inicialmente:

 

public int showContextMenu(int MenuHandle)
{
    int ret;
 
    ret = super(MenuHandle);
 
    return ret;
}

 

No tiene ningún misterio, es como la mayoría de métodos sobrecargados. Vamos a sustituirlo por este otro código:

 

int showContextMenu(int MenuHandle)
{
    int         ret;
    PopupMenu   menu;
    int         menuItem;
    ;
 
    // Crea un nuevo menú utilizando el manejador recibido por parámetros
    menu = PopupMenu::create(MenuHandle, this.hWnd());
 
    // Añade un nuevo Menu Item al menú recién creado
    menuItem = menu.insertItem("Mi nuevo menú");
 
    // Abre el menú
    ret = menu.draw();
 
    // Comprueba el Menu Item que se ha pulsado
    if (ret == menuItem)
    {
        // Si es el mío, pongo código aqui
 
        Box::info('Pon tu código aquí!');
 
        return 0;
    }
 
    // Si ha pulsado alguno que no es el mío, se lo devuelvo al estándar
    return ret;
}

 

Como se puede ver en el ejemplo, podemos añadir por código un nuevo MenuItem al menu contextual y a la vez, capturar la pulsación del mismo para poder ejecutar nuestro propio código de respuesta.

Sin votos aún

Nadie odia el software mas que los programadores

Hace unos dias Jeff Atwood publicó un artículo tan curioso como interesante en su blog Coding Horror (el cual ya he recomendado alguna vez), reflexionando sobre temas como la necesidad y la calidad del software que nos rodea. Parte de la base de que nadie está mas capacitado para odiar el software como los propios programadores, cito lo que me ha parecido mas divertido:



Let me share a recurring nightmare I have with you. In this dream, I'm sitting down in front of a computer which boots up, running an operating system I've written. I then launch a web browser I've created from scratch, all by myself, and navigate to a website I've constructed. I click on the first link and the whole thing bluescreens. And the bluescreen itself bluescreens and begins to fold in on itself, collapsing into a massive explosion that destroys an entire city block.


Una lectura muy entretenida, yo me quedo con una frase que hago mía:



[...] the best choice of software is often no software [...]


Leyendo este artículo he ido a parar a otro sobre la misma temática pero mas extenso y quizás mas profundo sobre el por qué todos odiamos tanto el software (incluso, si no más, el que nosotros mismos desarrollamos), que también recomiendo: why software sucks

Sin votos aún

Futuros cambios en X++

Desde un blog publicado por el personal de desarrollo de Microsoft, publican una serie de cambios (no necesariamente los únicos cambios) que se van a realizar en el lenguaje X++ (el lenguaje de Microsoft Dynamics AX) en la próxima versión del producto (de momento, Dynamics AX 6)


Se puede ver el artículo aquí: Forhcoming changes to the X++ language


La mayoría son cambios orientados a mejorar la seguridad del código, dejando ver el esmero con el que mejoran la calidad tanto del compilador como de los desarrollos que pueden salir de él.

Sin votos aún