j.a.estevan

Si no eres parte de la solución, eres parte del problema

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í:

06 de enero de 2010 | deja un comentario

Optimización de rendimiento para Product Builder

El configurador de producto de AX es uno de los módulos que personalmente mas me gustan de este ERP. Su potencia y utilidad son innegables pero también lo és que no resulta demasiado eficiente en algunos casos. Uno de sus puntos débiles es el rendimiento al mostrar los formularios configurables y para ello se ha publicado en el blog Dynamics AX Live un interesante y sencillo truco para reducir el tiempo de carga de los formularios del PB.

La idea es no forzar a AX a aplicar propiedades de estos formularios que ya están aplicadas, cosa que el estándar sí hace, y con esto se reducirán muchísimas llamadas al formulario sobre todo en los que dispongan de muchas variables.

Para ello iremos al método SetControlProperties de las clases PBAFrontEndControl y PBAFrontEndControlWin y buscamos el siguiente código:

dataSource.object(valueTmpBuildForm.activeField()).enabled(enabled);
dataSource.object(valueTmpBuildForm.activeField()).mandatory(mandatory);
dataSource.object(valueTmpBuildForm.activeField()).visible(visible);

y sustituimos por este:

if(dataSource.object(valueTmpBuildForm.activeField()).enabled() != enabled)
    dataSource.object(valueTmpBuildForm.activeField()).enabled(enabled);
if(dataSource.object(valueTmpBuildForm.activeField()).mandatory() != mandatory)
    dataSource.object(valueTmpBuildForm.activeField()).mandatory(mandatory);
if(dataSource.object(valueTmpBuildForm.activeField()).visible() != visible)
    dataSource.object(valueTmpBuildForm.activeField()).visible(visible);

Mientras escribía este post he recordado que tengo un documento en alguna parte de mi disco duro con un par de bugs localizados en el estándar del Product Builder. En cuanto lo encuentre los publicaré.

08 de diciembre de 2009 | deja un comentario

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.

06 de diciembre de 2009 | deja un comentario

Statement of Direction for MS Dynamics AX

Microsoft publicó hace unos dias un completísimo e interesante documento de 44 páginas explicando el pasado, presente y futuro de su producto Dynamics AX. Una lectura casi obligatoria para los que estamos dentro o esten pensando entrar en este mundo.

En el documento se analizan las soluciones ya implementadas recientemente en el SP1 de la version 2009 así como futuras funcionalidades de la próxima versión 6 y la dirección en la que se orientan las nuevas versiones sucesivas hasta 2018, así como los planes de mantenimiento y soporte actualizados.

Descargar desde PartnerSource (requiere login)

22 de noviembre de 2009 | deja un comentario

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

11 de octubre de 2009 | hay 3 comentarios

Backup Assistant Tool for AX 2009

Microsoft ha publicado una herramienta que permite analizar todos los componentes de un sistema Dynamics AX 2009 para localizar los componentes que deben ser protegidos. Le da el interesante y sencillo de recordar nombre de “System Center Data Protection Manager Backup Assistance Tool for Microsoft Dynamics AX 2009

Se puede desacargar de Partner Source (requiere login)

18 de agosto de 2009 | deja un comentario

Consumir Servicios Web desde AX

Leo en el blog de axaptafreak” la publicación de un interesantísimo White Paper del mismo autor en MSDN con un ejemplo práctico de cómo consumir un servicio web externo desde AX 2009.


En el artículo explica paso a paso como hacer que axapta lea información de un servicio web externo que publica tablas de conversión de divisas en un desarrollo nuevo dentro de AX, muy interesante.


Descargar White Paper (Inglés): Microsoft o MS Dynamics AX Developer Center

10 de mayo de 2009 | deja un comentario

Gestión Documental: AX2009 + Sharepoint Services

Arijit Basu ha publicado en su web un “experimento” mediante el cual intenta ampliar la funcionalidad (bastante limitada, aunque muy escalable) estandard de AX2009 para la gestión de documentos mediante el uso de los servicios de Sharepoint (WSS y MOSS).


Describe paso a paso su intento y publica el código de qué y cómo lo ha hecho asi que es un intento interesante para empezar a trabajar en una posible ampliación de AX en este campo interesante de la gestión documental. Incluso publica un video para ver como funciona finalmente.


Una lectura interesante y un buen punto de partida para jugar.

24 de marzo de 2009 | deja un comentario