Mostrando entradas con la etiqueta Dynamics. Mostrar todas las entradas
Mostrando entradas con la etiqueta Dynamics. Mostrar todas las entradas

jueves, 18 de julio de 2019

D365FO | Creación de métodos para control de eventos de datos

Los controladores de eventos de datos manejan los delegados expuestos en cada tabla, y estos se activan cuando ocurre el evento.
Hay dos métodos para cada uno: un método presente-continuo (ing) y un método en tiempo pasado (ed). Los métodos ing se invocan antes de que se active el evento, y el método ed se dispara después del evento.  
En nuestro ejemplo, el controlador de eventos se utiliza para asignar, validar y actualizar un campo. Por lo tanto, vamos a colocar estos métodos en una clase de ayuda. 

En nuestro caso, tenemos como escenario de prueba la aplicación para generar Renta de vehículos. Los registros se almacenan en la tabla HAVehicleRentTable.



- Crear una nueva clase. En nuestro caso HAVehicleRentManager.
- Abra el diseño de la tabla en cuestión, expanda el nodo Eventos y ubique onInserting.



- Haga clic derecho en el evento y elija Copiar el método del controlador de eventos.



- Abra la clase HAVehicleRentManager y pegue el código generado anteriormente en el cuerpo de la clase, como se muestra aquí:
 class HAVehicleRentManager  
 {  
   /// <summary>  
   ///  
   /// </summary>  
   /// <param name="sender"></param>  
   /// <param name="e"></param>  
   [DataEventHandler(tableStr(HAVehicleRentTable), DataEventType::Inserting)]  
   public static void HAVehicleRentTable_onInserting(Common sender, DataEventArgs e)  
   {
  
   }  
 }  

- A continuación, tendremos que escribir el código de la siguiente manera:
 class HAVehicleRentManager  
 {  
   /// <summary>  
   ///  
   /// </summary>  
   /// <param name="sender"></param>  
   /// <param name="e"></param>  
   [DataEventHandler(tableStr(HAVehicleRentTable), DataEventType::Inserting)]  
   public static void HAVehicleRentTable_onInserting(Common sender, DataEventArgs e)  
   {  
     HAVehicleRentTable vehicleRentTable = sender;  
     vehicleRentTable.numberDays = vehicleRentTable.toDate - vehicleRentTable.fromDate;  
     info(strFmt("Renta %1",vehicleRentTable.RentId));  
   }  
 }  

- Para probar esto, realice una compilación completa que incluya la sincronización de la base de datos. Y al crear una nueva renta de vehículo, el evento ejecuta nuestro código.



- Asignando el número de días y notificando el número de renta creado.



Al controlar campos en un diseño, también necesitamos controlar eventos como modifiedField y validateFieldPara controlarlos, nos suscribiremos al evento de datos apropiado.

- Considerando lo antes mencionado. Abra el diseño de la tabla HAVehicleRentTable, haga clic derecho en el evento onValidatedField y elija Copiar el método del controlador de eventos.



- Pegue el código generado en el cuerpo de la clase HAVehicleRentManager, y escriba el código del evento de la siguiente manera:
 class HAVehicleRentManager  
 {  
   /// <summary>  
   ///  
   /// </summary>  
   /// <param name="sender"></param>  
   /// <param name="e"></param>  
   [DataEventHandler(tableStr(HAVehicleRentTable), DataEventType::ValidatedField)]  
   public static void HAVehicleRentTable_onValidatedField(Common sender, DataEventArgs e)  
   {  
     ValidateFieldEventArgs fieldArgs = e;  
     HAVehicleRentTable vehicleRentTable = sender;  
     Boolean ok = true;  
     switch(fieldArgs.parmFieldId())  
     {  
       case fieldnum(HAVehicleRentTable,toDate):  
         if(vehicleRentTable.toDate < vehicleRentTable.fromDate)  
         {  
           ok = checkFailed("Fecha");  
         }  
         break;  
     }  
     if(!ok)  
     {  
       fieldArgs.parmValidateResult(false);  
     }  
   }  
 }  

Para probar esto, realice una compilación completa que incluya la sincronización de la base de datos. Y al modificar el valor del campo de fecha "Hasta", el evento ejecuta nuestra validación.



- Finalmente, abra el diseño de la tabla HAVehicleRentTable, haga clic derecho en el evento onModifyingField y elija Copiar el método del controlador de eventos.



Pegue el código generado en el cuerpo de la clase HAVehicleRentManager, y escriba el código del evento de la siguiente manera:
 class HAVehicleRentManager  
 {  
   /// <summary>  
   ///  
   /// </summary>  
   /// <param name="sender"></param>  
   /// <param name="e"></param>  
   [DataEventHandler(tableStr(HAVehicleRentTable), DataEventType::ModifyingField)]  
   public static void HAVehicleRentTable_onModifyingField(Common sender, DataEventArgs e)  
   {  
     ModifyFieldEventArgs fieldArgs = e;  
     HAVehicleRentTable vehicleRentTable = sender;  
     //Boolean ok = true;  
     switch(fieldArgs.parmFieldId())  
     {  
       case fieldnum(HAVehicleRentTable,toDate):  
         vehicleRentTable.numberDays = vehicleRentTable.toDate - vehicleRentTable.fromDate;  
         break;  
     }  
   }  
 }  

Para probar esto, realice una compilación completa que incluya la sincronización de la base de datos. Y al modificar el valor del campo de fecha "Hasta", el evento ejecuta nuestra actualización.



- Otras clases especializadas en DataEventArgs que son útiles son las siguientes:

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.