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

miércoles, 24 de julio de 2019

D365FO | Cómo personalizar el diseño de un reporte SSRS

En nuestro ejemplo procederemos con el desarrollo y la personalización de un reporte SSRS en D365FO. El objetivo aquí es agregar un campo de extensión al diseño de un reporte estándar sin over-layering. Utilizaremos el reporte de Confirmación de pedido de venta para agregar el nombre del grupo de venta.

Cree un nuevo proyecto en un nuevo modelo, el mismo que podrá ser utilizado como un nuevo paquete de extensión. Es una buena práctica tener un nuevo modelo para la personalización de reportes. Ya que al usar el concepto de extensiones, este nos permite agregar funcionalidad a los elementos de modelos existentes.


Los reportes, como el de Confirmación de pedido de venta, utilizan tablas temporales para facilitar la escritura del diseño. Por lo que crearemos una extensión de dicha tabla.
- Localice la tabla SalesConfirmHeaderTmp en el Explorador de aplicaciones.
- Haga clic derecho en la tabla y elija Crear extensión.



- Cambie el nombre de la extensión. En nuestro caso SalesConfirmHeaderTmp.HAExtension.
- Abra la tabla en el diseñador y agregue el nuevo campo.


  
- Localice el reporte SalesConfirm en el Explorador de aplicaciones.
- Haga clic derecho en el reporte y elija Duplicar en proyecto.



- Cambie el nombre del reporte. En nuestro caso HASalesConfirm.
- Abra el reporte en el diseñador y expanda el nodo Datasets y SalesConformHeaderDS. Luego, busque el nuevo campo de extensión en el nodo Campos.



- Si este no aparece, haga clic derecho en el Dataset y seleccione Restaurar.



- Ahora puede proceder a diseñar el reporte según sus requisitos.



- Cree una nueva clase de extensión que amplíe la clase de control de reportes estándar.


 class HASalesConfirmControllerExt extends SalesConfirmController  
 {  
   public static HASalesConfirmControllerExt construct()  
   {  
     return new HASalesConfirmControllerExt();  
   }  
 }  

- Agregue el método main, que haga referencia al diseño del reporte personalizado.


 class HASalesConfirmControllerExt extends SalesConfirmController  
 {  
   public static void main(Args _args)  
   {  
     SrsReportRunController formLetterController = HASalesConfirmControllerExt::construct();  
     HASalesConfirmControllerExt controller;  
     controller = formLetterController;  
     controller.initArgs(_args, ssrsReportStr(HASalesConfirm, Report));  
     if (classIdGet(_args.caller()) == classNum(SalesConfirmJournalPrint))  
     {  
       formLetterController.renderingCompleted += eventhandler(SalesConfirmJournalPrint::renderingCompleted);  
     }  
     formLetterController.startOperation();  
   }  
 }  

- Finalmente, agregue el método outputReport.


 class HASalesConfirmControllerExt extends SalesConfirmController  
 {  
   /// <summary>  
   ///  
   /// </summary>  
   protected void outputReport()  
   {  
     SRSCatalogItemName reportDesign;  
     reportDesign = ssrsReportStr(HASalesConfirm,Report);  
     this.parmReportName(reportDesign);  
     this.parmReportContract().parmReportName(reportDesign);  
     formletterReport.parmReportRun().settingDetail().parmReportFormatName(reportDesign);  
     super();  
   }  
 }  

- Necesitará implementar el reporte HASalesConfirm. Para hacer esto, haga clic derecho en el reporte y elija Implementar reportes.

- Cree una nueva clase de control de eventos y añada el evento onInserting de la tabla temporal de la siguiente manera:
Para agregar la lógica que ingresará el dato del campo extendido.

 class HASalesConfirmReportManager  
 {  
   /// <summary>  
   ///  
   /// </summary>  
   /// <param name="sender"></param>  
   /// <param name="e"></param>  
   [DataEventHandler(tableStr(SalesConfirmHeaderTmp), DataEventType::Inserting)]  
   public static void SalesConfirmHeaderTmp_onInserting(Common sender, DataEventArgs e)  
   {  
     SalesConfirmHeaderTmp header = sender;  
     SalesTable salesTable;  
     select SalesPoolId from salesTable  
       where SalesTable.SalesId == header.SalesId;  
     header.HASalesPoolName = SalesPool::find(SalesTable.SalesPoolId).Name;  
   }  
 }  

- Para probar esto, procedemos a confirmar un pedido de venta en D365FO.



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.