Limitación de X++

Si bien es muy probable que ya muchos lo sepan, pero me gustaría comentar ciertas limitaciones del entorno de programación lenguaje X++ que en un comienzo yo no conocía y que pueden ser muy útiles de saber para otros desarrolladores.

Debe existir unas cuantas más, así que conocen bienvenido el comentario.

No se puede reutilizar el código de un formulario por el siempre hecho de que los formularios no son verdaderas clases

Es decir si hacen la simple prueba de cambiar el extends ObjectRun por object, implementar un interfaz o cambiar nombre no verá ningún resultado palpable.

Tampoco se puede implementar un comportamiento genérico para cierto formulario, aunque hay algunos trucos para lograrlo.

En fin, resumiendo, los forms no son clases, sino simplemente un esquema de árbol que especifica como debe construirse una interfaz grafica a partir de objetos concretos con botones, cajas de texto, etc.

Estas limitaciones también aplican a los formularios que tienen el mismo comportamiento.

Esta forma de construcción de estos elementos me hace recordar un poco a la programación orientada a prototipos, claro que es una versión simplificada y muy práctica.

Ciertas clases no son accesibles al programador X++

Si bien gran parte de la lógica del sistema está escrita en X++, existen clases de kernel que no pueden ser modificadas.
Un ejemplo de ellas son todas las que empiezan con x*. XRecord, XSession, etc.

El límite no es del todo claro. Algunas veces y se pueden llegar a encontrar puertitas para introducir código en procesos centrales del sistema.

Todas las tablas comparten una definición común (Common)

Esta definición permite que todas las tablas, por ejemplo, puedan llevar un campo que identifique la empresa, fecha y hora de creación, modificación, ect.

Pero a pesar de que ayudaría mucho, no existe un mecanismo para agregar campos por defecto a nuestras tablas modificando la tabla base common.

Un formulario/reporte es un objeto indivisible

Usando el comparador se pueden detectar algunas limitaciones en la detección de cambios.
Por ejemplo si modificamos un método dentro de una tabla, funcio no distinge capas.

El lenguaje X++ no es 100% orientado a objetos


No existe el polimorfismo.

Bug: Compilación en cadena

Supongamos que tenemos un proyecto modificaciones sobre PurchFormLetter que es una clase base sobre la que heredan otras y modificamos en método Update.

Si exportamos el proyecto y lo importamos en otro ambiente entoces puede dar error, porque AX no recompila correctamente las clases hijas

Pararse sobre el objeto y utilizar compilación en cadena.

Funciones incorporadas útiles

curExt()
daraAreaId()

changeCompany()
{
}

Programar pensando en migrar I

Una buena forma de evitarse problemas al momento de migrar...

Si se definen nuevos valores en los base enums tamar en cuenta que en una proxima versión pueden existir nuevos valores.

Por eso como política siempre conviente sumar 100 al Id del último enum existente.

Lo pequeño puede ser grabe!

Si alguna vez reciben un error del estilo "Pequeño error de importación"

Hay que estar atento, pero seguramente se trate de un campo en un formulario que perdió su referencia el campo de la tabla que tiene en la propiedad "DataSource"

Esto sucede por un error en el órden de importación de los elementos dentro de un proyecto.



La "solución" es volver a importar el proyecto en cuestión.

El error fue comprobado en AX3 y AX4

Compilación en cadena

Cuando modificamos una clase base del sistema y a su vez una clase que la hereda. En algunas ocacciones el compilador no respete la secuencia de compilación generando errores al usuario cuando un proceso intenta utilizar metodos de la clase hija.

Esto fue comprobado en AX3 y AX4 esperemos no ocurra en AX2009

La solución que adoptamos para este problema es incluir en los proyectos que tengan esta característica un Job de compilado en cadena.

Este tipo de Job se ejecutan automáticamente al importar el proyecto en el que están contenidos

(Funcionalidad que será descripta es otra entrada)

Ej:


static void MPH_AUTORUN_20090630_000_CF(Args _args)
{
;
SysCompilerOutput::compileForward(className2Id('InventMovement'));
}

Best Practices de Desarrollo II

Tratar de evitar

* Guardar datos de estructura en la base de datos como por elemplo FieldId, TableId, ect.
Estos pueden cambiar el futuras versiones del estándar o pueden gererarse diferentes errores por numeraciones dispares al momento de migrarar datos cuando se mantienen dos versiones de AX simultáneamente.

* Referencias a RecId, ya que puede ser reenumerado. (Especial cuidado en Axapta 3.0)