Hace unos días tuve la necesidad de enviar unos informes por correo desde Reporting Services, pero, no con el nombre por defecto sino con un nombre dinámico. Este nombre consistía en la fecha actual y el nombre del informe. Ej: 22-02-2016_Informe1.
Funcionamiento interno SSRS
Cada vez que creamos una suscripción a un informe en Reporting Services, internamente nos crea un job con su respectivo schedule e inserta los datos necesarios en la base de datos de ReportServer.
Con esta query podemos ver la información que nos va ha hacer falta para modificar el job al que le queremos cambiar el nombre del archivo adjunto.
USE [ReportServer]
GO
SELECT s.LastStatus
,s.LastRunTime
,c.[path]
,rs.subscriptionid
,rs.reportid
FROM reportschedule rs
INNER JOIN subscriptions s ON rs.subscriptionid = s.subscriptionid
INNER JOIN dbo.catalog c ON rs.reportid = c.itemid
El resultado será parecido al siguiente:

- LastStatus: último estado.
- LastRunTime: fecha de la última ejecución.
- Path: indica la carpeta donde está ubicado el informe, en nuestro caso BETA, y el nombre del informe.
- SuscriptionId: este campo hace referencia al id de la suscripción del informe, el cual vincula el job con la suscripción.
- ReportId: este campo indica el nombre del job que deberemos modificar.
Modo de implementación
Abrimos el Job, nos dirigimos a steps, edit y nos aparecerá el siguiente código.

En la parte Command comentamos o borramos el código y pegamos el siguiente script.
USE [ReportServer]
GO
DECLARE @jobName NVARCHAR(100),@subscriptionId UNIQUEIDENTIFIER,@reportId NVARCHAR(100),@pathOld NVARCHAR(100),@newName NVARCHAR(100)
--Nombre del job al que hace referencia la subscripcion
SET @jobName = '01B6F118-7ED5-4DC4-BA6E-D0BDEF5AAB26'
--Especifica la carpeta en la que están desplegados los reports y depues el nombre "/carperta/name"
SET @newName = '/BETA/'+CAST(CAST(GETDATE() AS DATE) AS NVARCHAR(50))+' - Cierre'
SELECT @pathOld = c.[path]
,@subscriptionId = rs.subscriptionid
,@reportId = rs.reportid
FROM reportschedule rs
INNER JOIN subscriptions s ON rs.subscriptionid = s.subscriptionid
INNER JOIN dbo.catalog c ON rs.reportid = c.itemid
WHERE rs.scheduleid = @jobName
--Modifica el nombre del fichero
UPDATE dbo.catalog
SET [path] = @newName
WHERE itemid = @reportId
EXEC dbo.addevent @eventtype = 'TimedSubscription',
@eventdata = @subscriptionId
--Este delay es necesario ya que tiene que crear el correo antes de hacer el update
WAITFOR DELAY '00:01'
--Deja como estaba el fichero para que no de errores en la siguiente ejecución
UPDATE dbo.catalog
SET [path] = @pathOld
WHERE itemid = @reportId
GO
Una vez pegado el script solo tenemos que modificar dos cosas:
- En la parte de set @jobName=” introducir el nombre del job entre las comillas.
- En la parte de set @newName=” es donde especificaremos el nuevo nombre del archivo adjunto. Debemos seguir el formato /carpeta/nombreInforme teniendo en cuenta que la longitud de @newName tiene que ser menor de 50 caracteres.
Cuando tengamos todo modificado debería mandar el archivo adjunto de la siguiente forma:

Comments
Hola, muy bueno el post!
Por alguna razón no me funciona y me sobreescribe el command cada vez que se ejecuta la suscripción.
El ‘reportid’ no me coincide con el nombre del job, no tengo ningun job que coincida. Sé cuál es el job por el ‘subsriptionid’ y la hora de ejecución. Tenés idea por qué puede ser esto?
En el path de la carpeta, va la carpeta donde están publicados los reportes?
Saludos y gracias!
¡Buenas tardes Lucia!
Cada vez que modificamos algún parámetro de la suscripción del informe, se sobrescribe el job. Supongo que modificas la fecha de ejecución de la suscripción, para que se ejecute y así poder hacer pruebas (puedes ejecutar directamente el job).
El reportid no tiene que coincidir con el nombre del job sino con ScheduleID de la tabla reportschedule.
Te paso una sentencia por si te sirve de ayuda, en ella aparece también el path donde se encuentra el informe.
SELECT c.Name AS NombreReport
,c.[path]
,rs.ScheduleID AS NombreJobSQL
,rs.subscriptionid
,rs.reportid
,s.Description
,s.LastRunTime
,s.LastStatus
FROM
reportschedule rs
INNER JOIN subscriptions s ON rs.subscriptionid = s.subscriptionid
INNER JOIN dbo.catalog c ON rs.reportid = c.itemid
Cualquier duda, coméntenoslo
¡Un saludo!
¡Muchísimas gracias! El tema era ese: al editar la suscripción se sobreescribía el job.
¡Saludos!
Hola Xesco, te hago una consulta para ver si me puedes orientar: Tengo que enviar un reporte mediante SSRS pero solo cuando la consulta recupere resultados (es un email de cumpleaños, solo quiero que se envíe cuando alguien cumple años). Tienes idea cómo puedo hacerlo? Ya que si genero una suscripción se envía todos los días que detallo en la misma. Muchas gracias por tu ayuda!!
Hola Lucia, intento darte una idea, espero te sirva de ayuda.
Creas el informe con la felicitación en ssrs y haces que se ejecute una vez solo y de esta forma se te creará el job de la suscripción. Una vez tienes el job de la suscripción añades otro job en el que con T-SQL sript, creas una condición y dependiendo de esta condición ejecute el job. Ej:
IF SELECT COUNT(*) FROM EMPLEADOS WHERE MONTH(fecha_nacimiento)=month(getdate()) and day(fecha_nacimiento)=day(getdate()) BEGIN
USE msdb;
GO
EXEC dbo.sp_start_job N’92E2F35F-F4E6-450E-8E04-FF776B60B2BE’;–Reemplazalo por job de la suscripción
GO
END
Si lo que necesitas es que envíe el correo específicamente cada vez a un destinatario distinto deberías hacerlo desde ssis.
Espero nos comentes que tal ha ido.
Saludos
Hola Xesco, una consulta: tienes idea de como sería para que al descargar el archivo lo nombre con un parámetro? Ejemplo: nombre del reporte (ventas), entonces al descargar según el parámetro (mes del reporte) el archivo excel resultante sea de nombre: ventas_junio.