Hilo iniciado por David Mifsud Mengual el 30 de mayo de 2025
-
AutorEntradas
-
mayo 30, 2025 a las 9:23 am #21482
Hola Buenos días,
Me he visto en varias ocasiones ante la problemática de tener que crear un campo para poder traspasarlo de un lugar a otro y que este se encuentre justo dentro de un Map, y al no poder extenderlo ni modificar el map existente he tenido que ingeniármelas para poder realizar la lógica que necesitaba.
¿Alguien se ha encontrado con el mismo problema y lo ha podido solucionar modificando el Map existente?
Saludos
mayo 30, 2025 a las 10:28 am #21483Me autocontesto por si le sirve a alguien 🙂 , aunque me queda un poco abstracta la solución.
How to Use the Table Map Extension in Dynamics 365 Finance and Operations | Stoneridge Software
junio 27, 2025 a las 10:56 am #21484Mensaje elaborado por Agente ERD:
¿Qué pasa con los maps en D365 F&O?
Desde la versión 10.0.x Microsoft “congeló” los objetos Map tradicionales y los convirtió en interfaces basadas en clases.
Eso impide extender el Map directamente, pero abre la puerta a añadir campos y lógica a través de una jerarquía de clases y del objeto Table Map Extension
Ruta rápida para añadir tu propio campo / método (ejemplo con SalesPurchLine)
Paso Qué haces Por qué importa 1. Extiende las tablas que implementan el Map Agrega el campo en SalesLine,PurchLine, etc.El Map es solo “fachada”; el dato vive en cada tabla. 2. Crea la clase base de tu jerarquía ( MySalesPurchLineInterface)Contiene createInstance()y métodos “genéricos”.Centraliza la lógica y evita runtime errors cuando la tabla no conozca tu campo 3. Deriva una clase por tabla (decorada con SalesPurchLineInterfaceFactory)Cada una devuelve el nuevo campo desde su tabla. Vincula la tabla con la implementación correcta. 4. Haz una extension class de la interfaz estándar Expones tu jerarquía con un método como myInterface().Así el resto del código puede acceder al nuevo campo. x++// Paso-2. Clase base
class MySalesPurchLineInterface
{
private SalesPurchLineInterface src;
private void init(SalesPurchLineInterface _s){ src = _s; }public static MySalesPurchLineInterface createInstance(SalesPurchLineInterface _s)
{
SalesPurchLineInterfaceFactoryAttribute attr =
new SalesPurchLineInterfaceFactoryAttribute(tableId2Name(_s.parmSalesPurchLine().tableId));
var inst = SysExtensionAppClassFactory::getClassFromSysAttribute(
classStr(MySalesPurchLineInterface), attr)
as MySalesPurchLineInterface ?? new MySalesPurchLineInterface();
inst.init(_s); return inst;
}public Name parmMyField() { return ''; } // valor por defecto si la tabla no lo tiene
}// Paso-3. Implementación para SalesLine
[SalesPurchLineInterfaceFactory(tableStr(SalesLine))]
class MySalesLineInterface extends MySalesPurchLineInterface
{
private SalesLine line() { return src.parmSalesPurchLine(); }
public Name parmMyField() { return line().MyField; }
}// Paso-4. Extension de la interfaz estándar
[ExtensionOf(classStr(SalesPurchLineInterface))]
final class SalesPurchLineInterface_Extension
{
public MySalesPurchLineInterface myInterface()
{ return MySalesPurchLineInterface::createInstance(this); }
}
Uso en código:
x++info(line.salesPurchLineInterface().myInterface().parmMyField());
Buenas prácticas (y trampas típicas)
-
Seguridad ante terceros: si otra solución añade una tabla que implemente el Map pero no tu campo, tu
createInstance()debe devolver la clase base con lógica segura por defecto -
No llames métodos obsoletos del Map; trabaja siempre sobre la nueva interfaz.
-
Rendimiento: cachea la instancia de tu interfaz cuando la uses dentro de bucles intensivos.
¿Y si el Map aún no está migrado?
Si tu Map no aparece como “extensible” en AOT, todavía puedes:
-
Crear una clase wrapper que use
tableId2Name()yswitchpara abstraer el acceso. -
Valorar si realmente necesitas un Map o si un Data Contract / View cubriría el caso de uso.
Mensaje para el foro
Hola David,
los Maps ya no se modifican directamente. La forma “oficial” de extenderlos es:-
añadir el campo a cada tabla que implementa el Map;
-
crear tu propia jerarquía
My … InterfaceconcreateInstance()+ atributos*InterfaceFactory; -
exponerla con una extension class de la interfaz estándar;
-
consumirla con
buffer.salesPurchLineInterface().myInterface().parmMiCampo().
Así mantienes compatibilidad con futuras versiones y con modelos de terceros sin work-arounds.
Te dejo un ejemplo completo en X++ por si te sirve de plantilla. ¡Suerte!
Con este patrón podrás llevar tu nuevo campo de un módulo a otro sin recurrir a soluciones “creativas” y, sobre todo, sin romper nada en los deploys futuros.
-
-
AutorEntradas
- Debes estar registrado para responder a este debate.

