martes, 13 de marzo de 2018

TIP | [X ++] Mejorar procesamiento de datos en Reportes SSRS

Cuando un reporte procesa una gran cantidad de datos y se considera que toma un tiempo considerable durante su ejecución, entonces se puede decidir incorporar preprocesamiento. Sigue estos pasos para habilitar el preprocesamiento en RDP y mejorar el procesamiento de datos en reportes:
Espero sea de su ayuda.


1. Extendemos la clase RDP de la clase SrsReportDataProviderPreProcess.


class HAVendPaymentDP extends SrsReportDataProviderPreProcess
{   
 

     //Tabla temporal utilizada por el RDP
     HAVendPaymentTmp   vendPaymentTmp;
}



2.  Establecemos las siguientes propiedades en la tabla temporal utilizada por el RDP.




3. Lo importante dentro del preprocesamiento en el RDP es insertar registros en las tablas que generen automáticamente un TransactionId al principio del proceso del reporte y establecer una conexión con el usuario.

El campo TransactionId permite que el reporte identifique los registros creados únicamente para la sesión del usuario.


public void processReport()
{
   
    vendPaymentTmp.setConnection(this.parmUserConnection());
   


    //super();
}


4. Adicionalmente para nuestro ejemplo en el ingreso de registros, hacemos uso de la clase RecordInsertList.

Esta clase permite insertar más de un registro en la base de datos a la vez, lo que reduce la comunicación entre la aplicación y la base de datos.


public void processReport()
{
   
    RecordInsertList    recordInsertList;

    vendPaymentTmp.setConnection(this.parmUserConnection());

    recordInsertList = new
RecordInsertList(tableNum(HAVendPaymentTmp),
                                            false,
                                            false,
                                            false,
                                            false,
                                            false,
                                            vendPaymentTmp);

    //Ingreso de registros en la tabla

    ttsbegin;
    vendPaymentTmp.clear();
    vendPaymentTmp.VendAccount = "VA00001";
     .
     .
     .
    recordInsertList.add(vendPaymentTmp);
    //

    recordInsertList.insertDatabase();
    ttsCommit;
    //super();
} 



Los registros se insertan solo después de la llamada al método insertDatabase. 
RecordInsertList.insertDatabase() devuelve los registros acumulados por el método add().


5. Recordamos actualizar el DataSource del Reporte SSRS en Visual Studio, para refrescar el campo TransactionId.
   

viernes, 23 de febrero de 2018

X++ | USO DEL SysExtension Framework

USO DEL SysExtension Framework

El SysExtension Framework es incorporado en Dynamics AX para solventar el diseño de extensión de clases (jerarquías). En el siguiente ejemplo motraremos el uso de esta solución.
Espero sea de su ayuda.

1. Lo primero que necesitamos es un diseño de jerarquía de clases. De manera sencilla, para este ejemplo se crearán las clase HACustInvoice y HACustInvoice_Sales.


class HACustInvoice
{
}


public void run()
{
    info("clase HACustInvoice");
}


 
class HACustInvoice_Sales extends HACustInvoice
{
}


public void run()
{
    info("clase HACustInvoice_Sales");
    //super();
}


2. Ahora, creamos una clase que extiende de SysAttribute. Donde definiremos el atributo que en el contructor nos retorne la clase derivada.


 Esta clase almacena un valor recibido por parámetros y lo devuelve por un método parm.

class HACustInvoiceTypeAttribute extends SysAttribute
{
    str     classType;
}


public void new(str     _classType)
{
    super();

    if(_classType == "")
        throw error(error::missingParameter(this));

    classType = _classType;
}
 


public str parmClassType(str    _classType = classType)
{
    classType = _classType;

    return classType;
}


3. Editamos la classDeclaration de la clase (HACustInvoice_Sales)derivada para añadir este atributo.

[HACustInvoiceTypeAttribute("Sales")]
class HACustInvoice_Sales extends HACustInvoice
{
}


4. Por ultimo, editamos el constructor de la clase HACustInvoice con una nueva definición que utilice el atributo de la clase derivada.
 
public static HACustInvoice construct(str _classType)
{
    HACustInvoiceTypeAttribute     custInvoiceTypeAttribute;
    HACustInvoice                  custInvoice;

    custInvoiceTypeAttribute = new HACustInvoiceTypeAttribute(_classType);

    custInvoice = SysExtensionAppClassFactory::getClassFromSysAttribute(classStr(HACustInvoice),
                                                                        custInvoiceTypeAttribute);

    return custInvoice;
}


Segun éste diseño, no tendremos que modificar en absoluto nuevamente el constructor para añadir nuevas clases derivadas. Bastaría con indicar un nuevo atributo en la declaración de las nuevas clases derivadas.

5. Ejecutamos nuestro ejemplo de la siguiente manera:

static void JobHMAE(Args _args)
{
    HACustInvoice   custInvoice;

    custInvoice = HACustInvoice::construct("Sales");
    custInvoice.run();
}