Buscar en este blog

jueves, 12 de diciembre de 2013

Reportes SSRS en Dynamics Ax 2012 basados en RDP (Report data provider)

 
Existen escenarios donde la consulta de un query no nos basta para sacar la información de ax y presentarla en un reporte, en esas ocasiones donde necesitamos procesar la información antes para ponerla de cierta forma en el reporte es cuando debemos usar en conjunto con el query una clase RDP que contenga la lógica; ya que tenemos la información como queremos la guardamos en una tabla temporal y esta tabla temporal es la que usamos como fuente de datos para nuestro reporte, sencillo no?
Bueno, yo se que a la primera no suena taaaan sencillo, así que vamos al ejemplo. 
En el primer post les mostré cómo crear un reporte, hicimos un query que consultaba todos los campos de la tabla de cliente "CustTable" con el parametro de Cust Account (código de cliente). Basandonos en ese query, anexemos al datasource la tabla CustTrans, entonces nuestro query debe verse así:

Image(11)

Y si dejamos unos segundos el cursor sobre la tabla "padre" que es CustTable podemos ver el query que ahora tenemos formado con CustTrans.
Y no olviden poner la propiedad Dynamic de los campos en Yes, igual que como se hizo con la tabla CustTable. Sino lo hacen les va a marcar error. (En este paso, piensen si requieren toooodos los campos de la tabla, si solo va a querer unos cuantos agréguenlos a mano y no modifiquen la propiedad Dynamic).

Image(12)
Ahora, como les mencione en el primer párrafo, los 3 elementos que necesitamos para hacer un reporte basado en RDP son:
  • Una clase RDP
  • Un query
  • Una tabla temporal
Como vamos a usar nuestro query del post anterior (sino lo tienes pues crealo, solo arrastrando las tablas CustTable y CustTrans a los datasources del query, igualito que como se ve en la imagen de arriba), entonces ahora nos falta crear la tabla y la clase RDP.
Imaginemos que nuestro reporte debe mostrar el monto de transacciones en pesos mexicanos únicamente cuando el cliente sea el 2121, entonces como todas las transacciones estan en dolares, nuestra lógica debe indicar que solo para el cliente 2121 el monto de transacciones debe multiplicarse por el tipo de cambio, en este caso tomaremos $13 pesos.

Vamos creando nuestra clase y la vamos a llamar: ClaseEjemploRDP, la vamos a extender de SRSReportDataProviderBase. Después necesitamos decirle con cuál query vamos a trabajar en conjunto, esto lo hacemos poniendo antes de la declaración el atributo : [SRSReportQueryAttribute(querystr(EjemploQueryClientes))]

Dentro de la declaración de la clase, vamos a declarar las variables que necesitamos guardar sus valores, o sea, que vamos a poner todos los campos que queremos que se muestren en nuestro reporte
Image(13)
La primera línea la comente porque aun no creamos nuestra tabla temporal, así que vamos a crearla y descomentamos la línea. La tabla la vamos a crear para guardar los datos que vamos a usar en el reporte, entonces debe tener todos los campos que vamos a usar en nuestro reporte. Muuuy importante: en la propiedad de TaleType seleccionar "InMemory".
Actualización: Para Ax R2, esta tabla si debe ser tabla regular.

Image(14)

No olviden poner los EDTs (Extended Data Type) a cada campo, son los mismos que los nombres de los campos de ejemplo.
Lo siguiente es descomentar la línea que dejamos comentada en la declaración de la clase y crearnos un método público en esa misma clase, que nos retorne toda la información de la tabla temporal, ponemos también el atributo SRSReportDataSetAttribute, con este atributo le indicamos a Ax cuál es nuestra tabla temporal con la que vamos a trabajar en conjunto. El método debe verse así:

Image(15)

En seguida vamos a crear un método para insertar los registros que vayamos formando en la lógica a nuestra tabla temporal. Nuestro método debe quedar:

Image(16)

En la imagen anterior solo falto la última línea que es la que hace la magia, o sea, tablaTemporalRDP.insert();
Luego, tenemos que crear la lógica que debe implementar la clase, esto lo vamos a hacer sobrescribiendo el método processReport o en nuestras versiones de Ax en español "cancelado el método processReport", ustedes me entienden. Por qué aquí? porque es el punto donde el proceso de reporte comienza, este método es llamado desde el framework de reporteo. Entonces, la lógica debe ser escrita aquí, para nuestro caso, este método debería quedar como sigue:

Image(17)

public void processReport()
{
    QueryRun        qr;    
    ;
   
    qr = new QueryRun(this.parmQuery());
   
    While (qr.next())
    {        
        custTable = qr.get( tableNum(custTable));
        custTrans = qr.get( tableNum(custTrans));
        amountCur = custTrans.Amount;
 voucher = custTrans.voucher;
 transDate = custTrans.transDate;

        this.insertTablaTemporlRDP();       
    }

}

Con esto ya tenemos nuestra fuente de datos que se va a usar en nuestro reporte, ahora si nos vamos a Visual Studio y creamos un nuevo proyecto del tipo Microsoft Dynamcs AX, lo llamamos ReporteBasadoEnRDP. Agregamos al proyecto un elemento del tipo "Report" y lo renombramos como ReportePruebaRDP. Creamos un nuevo DataSet (clic derecho en datasets -> nuevo) lo renombramos como DatosRDPDS y en la propiedad de este dataset llamada "Data Source Type" elegimos "Report Data Provider" y en la propiedad "Query" seleccionamos nuestra clase RDP (ClaseEjemploRDP) que creamos en Ax.
En este caso el processReport de este ejemplo:

Image(18)
Image(19) Image(20)
Image(21)
Solo nos falta el diseño, en la parte de "Designs" agregamos el AutoDesign y arrastramos nuestro dataset "DatosRDP" al diseño creado, debe verse así:
Image(22)
Listo!!! es todo!
Ahora solo agregamos el reporte al AOT, click derecho sobre el proyecto, elegimos "Add ReporteBasadoEnRDP to AOT" y despues implementamos, click derecho sobre proyecto y seleccionamos "Deploy" o "Implementar".
Image(23)
Para verlo en Ax, ahora solo creamos un objeto "Output" y en sus propiedades "ObjectType" seleccionamos "SSRSReport", en 2Object" seleccionamos nuestro reporte "ReportePruebaRDP", guardamos y hacemos clic derecho sobre el objeto Output, elegimos "Abrir" y veremos nuestro reporte!!!
Nota: Si no nos gusta como se ve nuestro reporte porque solo se ven las columnas sin ningún formato, le podemos aplicar un estilo para que al menos nos presente la fecha y hora de impresión, la compañía a la que pertenece y datos básicos. Esto lo hacemos en Visual Studio, eligiendo:
Image(24)
y en la tabla que se crea cuando arrastramos el dataset:
Image(25)
Con estos cambios tendríamos un reporte como este:
Image(26)
Resumen:
Diseñar nuestro reporte en papel para saber qué campos necesitamos
Crear nuestro query con los campos necesarios
Crear una clase que herede de SRSReportDataProviderBase
En la declaración de la clase poner el atributo SRSReportQueryAttribute indicando el nombre de nuestro query al que será enlazada la clase RDP
Crear la tabla temporal con todos los campos que vayamos a usar en el reporte
Crear el método que regrese toda la información de nuestra tabla temporal con el atributo SRSReportDataSetAttribute
Crear método en clase para insertar en nuestra tabla temporal
Sobreescribir el método processReport con la lógica y manejo de nuestros datos e insertar en nuestra tabla temporal



Y por cierto, acuerdate de darle click a algún anuncio si el post te sirvio de algo.

Por último, te invito a que te unas a la página de facebook recién creada para estar al día con las actualizaciones del blog y que podamos tener más comunicación. La meta? es hacer la comunidad de habla hispana mas grande sobre Dynamics Ax en cuestiones de desarrollo.





<< Anterior - Filtrar reportes                                         Siguente - Clase controladora (controller) >>


<<<<<     Indice de tutorial de Reportes SSRS....




4 comentarios:

  1. Amigo, una cosnulta como hago para que mi reporte este parametrizado en un rngo de fechas, por ejemplo poner como parametros una fecha "desde" y otra "hasta"

    ResponderEliminar
  2. cambia "desde" y "hasta" por fechas validas

    ResponderEliminar
  3. Hola, esta muy útil el post, gracias, oye pero ya no se pueden visualizar las imagenes :-( ...

    ResponderEliminar
  4. si, no se pueden visualizar las imagenes apoyo :(

    ResponderEliminar