Динамическая рассылка отчетности средствами Crystal Reports

от автора

Этот пост для тех, кто столкнулся с задачей динамической рассылки отчетов или каких либо аналитических материалов.

Допустим, в вашей компании есть сеть филиалов и вам необходимо наладить еженедельную рассылку отчетов с результатами работы руководителям филиалов. Отчет должен содержать результаты деятельности филиала за прошедшую неделю – таблицы, графики, аналитическую информацию. Соответственно для каждого филиала информация в отчете уникальная.

Расскажу, как это можно сделать быстро и просто.
Для решения задачи нам необходимы Crystal Reports 2008 и Visual Studio 2010 (можно использовать и более ранние версии продуктов).
Для автоматизации рассылки отчетов необходимо, что бы вся аналитическая информация для составления отчетов содержалась в базах данных. В итоге хорошо перед рассылкой отчетов получить данные по каждому филиалу в одном или нескольких запросов к базе.
Пример результата запроса:

Используя Crystal Reports мы можем сформировать отчет, содержащий данные о продажах, расходах и других показателях по отдельному филиалу. В качестве источника данных в отчете используем результаты данного запроса, а в Record Selection Formula используем фильтр по одному филиалу. Например, номер филиала равен 1:

{data.branch} = 1 

Поскольку Crystal Reports достаточно гибкий инструмент, используя такие его инструменты как формулы и cуботчеты можно сформировать любой формат документа: от простого одностраничного отчета до объемного аналитического исследования с таблицами и графиками.

Далее меняя Record Selection Formula мы можем выводить в отчете информацию по любому филиалу.
Все что нам нужно сделать дальше, это выполнить экспорт отчета в один из форматов (pdf, xls, rtf) и отправить его по электронной почте.

Рассмотрим каким образом это можно автоматизировать

В первую очередь нам потребуется таблица, содержащая номера филиалов и электронную почту получателя отчета. Нам необходимо реализовать цикл по строчкам этой таблицы. Далее для каждой строки мы берем номер филиала и подставляем его в Record Selection Formula нашего отчета. Далее экспортируем отчет в pdf файл и присоединяем этот файл к письму. Письмо отправляем на соответствующий адрес.

Crystal Reports предоставляет не только среду для разработки отчетности но и компоненты для разработки для платформы NET.
Ниже пример кода на Visual Basic:

Imports System.Net.Mail Imports System.IO Imports System.Net.NetworkCredential Imports CrystalDecisions    Module Module1      Sub Main()                  'Инициализируем необходимые переменные и источники данных         Dim Rows1 As DataRow         Dim Table1 As New myData.MailListDataSet.Query1DataTable         Dim myDA As New myData.MailListDataSetTableAdapters.Query1TableAdapter         Dim strDate = Format(CDate(Today()), "ddMMyyyy")         Dim myBranch As Integer         Dim myBranchMail As String         Dim myAppPath As String         Dim myLogFilePath As String         Dim myLogStr As String         myAppPath = My.Application.Info.DirectoryPath                           'Создаем папку, которая будет содержать файлы отчетов         Dim myDirInf As New DirectoryInfo(myAppPath + "\" + strDate)         If Not myDirInf.Exists() Then             myDirInf.Create()         End If                  'Создаем файл лога для отслеживания результатов формирования и отправки отчетов         myLogFilePath = myAppPath + "\" + strDate + "\log.txt"         Dim fs As StreamWriter = File.CreateText(myLogFilePath)          'Заполняем таблицу данных (номер филиала, почта получателя отчета)         myDA.Fill(Table1)          'Инициализируем объект ReportDocument из нашего файла отчета         Dim myReport As New CrystalDecisions.CrystalReports.Engine.ReportDocument         myReport.FileName = myAppPath + "\report1.rpt"          'Цикл по филиалам           For Each Rows1 In Table1.Rows                          'Опеределяем номер филиала и почту             myBranch = Rows1.Item(0)             myBranchMail = Rows1.Item(1)                          'Изменяем Record Selection Formula              myReport.RecordSelectionFormula = "{data.branch}  = " + CStr(myBranch)                          'Обновляем отчет             myReport.Refresh()                          Try                                  'Экспортируем отчет в pdf (для каждого филиала - файл с уникальными именем)                 myReport.ExportToDisk([Shared].ExportFormatType.PortableDocFormat, myAppPath + "\" + strDate + "\Report for Branch " +           CStr(myBranch) + " " + strDate + ".pdf")                                  'Пишем в лог информацию об успешной операции                 myLogStr = CStr(Now()) + ": " + "generate file for Branch " + CStr(myBranch) + Chr(13) + Chr(10)                 Console.Write(myLogStr)                 fs.Write(myLogStr)              Catch exp As Exception                  'Пишем в лог информацию об ошибке                   Console.WriteLine("Erorr:" & exp.Message)                 myLogStr = CStr(Now()) + ": Erorr" & exp.Message & " when generate file for Branch " + CStr(myBranch) + Chr(13) + Chr(10)                 Console.Write(myLogStr)                 fs.Write(myLogStr)              End Try                    'Инифиализируем  Smtp Client для отправки пистма с отчетом                 Dim mySmtp As New System.Net.Mail.SmtpClient("company.com")                 mySmtp.Credentials = New System.Net.NetworkCredential("user", "password")                                                  'Указываем отправителя, тему и текст письма                 Dim myMsg As New System.Net.Mail.MailMessage("mail@example.com", myBranchMail, "Аналитическая рассылка компании X", _                "Уважаемый руководитель филиала " + CStr(myBranch) + ", во вложении находится файл аналитической рассылки.")                                  'Вкладываем в письмо ранее сформированный pdf файл                 Dim myAtt As New System.Net.Mail.Attachment(myAppPath + "\" + strDate + "\Report for Branch " + CStr(myBranch) + " " + strDate + ".pdf")                 myMsg.Attachments.Add(myAtt)                                  Try                     'Отправляем письмо                     mySmtp.Send(myMsg)                                          'Пишем в лог информацию об успешной операции                     myLogStr = CStr(Now()) + ": " + "sending file for Branch " + CStr(myBranch) + ", on " + myBranchMail + Chr(13) + Chr(10)                     Console.Write(myLogStr)                     fs.Write(myLogStr)                  Catch exp As Exception                                        'Пишем в лог информацию об ошибке                      Console.WriteLine("Erorr:" & exp.Message)                     myLogStr = CStr(Now()) + ": Erorr" & exp.Message & " when sending file for Branch " + CStr(myBranch) + Chr(13) + Chr(10)                     Console.Write(myLogStr)                     fs.Write(myLogStr)                                  End Try           Next Rows1          fs.Close()      End Sub  End Module 

Используя код можно сделать консольное приложение и запускать его по расписанию, а можно использовать его в ETL пакете SSIS (MS SQL Server Integration Services).

ссылка на оригинал статьи http://habrahabr.ru/post/158225/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *