Добавление отчетов профессионального качества в приложение
|
(07:38) 16.07.2004
|
|
Для понимания статьи требуется знание среды Visual Studio
.NET. Аннотация Генератор отчетов Crystal Reports for Visual Studio .NET предлагает
комплексное решение по организации отчетности для .NET-разработчиков, которое
полностью интегрируется с такими операционными средами, как Visual Studio
.NET IDE и .NET Framework. Crystal Reports поддерживает технологии
ADO.NET и XML Web Services, серверные ASP.NET элементы управления и кэширования.
Он "бесшовно" интегрируется с Visual Studio .NET Server Explorer, набором
инструментальных средств и средой разработки. Crystal Reports имеет богатую
модель программирования и располагает гибкими возможностями настройки и
развертывания отчетов. Перечисленные основные возможности Crystal Reports, как и
другие, рассматриваемые здесь, позволяют выполнять сложную рутинную работу над
представлением данных в приложениях пользователя. Используя технологии Microsoft, разработчики долго и тесно сотрудничали с
Crystal Reports еще во время внедрения Visual Basic 1.0. Теперь, с появлением
платформы .NET и Visual Studio .NET, Crystal Reports снова установил стандарт
для интеграции сторонних программных продуктов с инструментальными средствами
Microsoft. Генератор отчетов Crystal Reports for Visual Studio .NET был
разработан совместно с инженерами Microsoft с целью наиболее полной интеграции
Crystal Reports с операционными средами .NET Framework и Visual Studio .NET. Он
выполняет функции встроенного разработчика, позволяющего создавать новые отчеты,
импортировать любые существующие отчеты Crystal Reports (или отчеты данных на
языке Visual Basic 6.0) в формате .rpt, а также предоставляет ряд других
возможностей, которые будут описаны ниже. В этой статье я сначала рассмотрю процедуру создания приложения Windows
Forms, затем технологию ASP.NET Web Service и построение клиентского приложения
ASP.NET. Попутно я расскажу о некоторых полезных приемах программирования для
решения таких задач, как создание документов Acrobat (PDF) из имеющихся отчетов,
формирование отчетов на базе параметризованных хранимых процедур SQL Server
передача отчетов с помощью учетных данных текущего пользователя базы данных.
Загружаемый пример программы для этой статьи включает приложения Windows Forms,
ASP.NET Web Forms и ASP.NET Web Services. Начнем с чего-нибудь простого. Я создам отчет из таблицы Customers (Клиенты)
базы данных SQL Server Northwind и открою его в приложении Windows Forms. Для
этого нужно создать новое приложение для Windows в Visual Studio .NET. (Я буду
работать с языком Visual Basic, хотя эта концепция переносима на любой язык
.NET.) После того, как приложение будет создано, щелкните правой кнопкой мыши по
имени проекта в окне Solution Explorer и выберите в контекстном меню Add | Add
New Item (Добавить | Добавить новый элемент). Затем в списке шаблонов Templates
диалогового окна Add New Item выберите Crystal Report, укажите в строке Name
отчет CustomersBasic.rpt и щелкните по кнопке Open (см. рис. 1). Рис. 1. Создание простого отчета После того, как откроется диалоговое окно Crystal Report Gallery, вы можете
принять настройки по умолчанию (радиокнопка Using the Report Expert и строка
Standard) и щелкнуть по кнопке OK. Когда откроется диалоговое окно Report
Expert, перейдите к ветке OLE DB (ADO) древовидного списка на вкладке Data. В
появившемся диалоговом окне OLE DB (ADO) выберите Microsoft OLE DB Provider for
SQL Server, укажите сервер SQL Server и информацию для входа в этот сервер,
затем выберите базу данных Northwind и щелкните по кнопке Finish. Вернитесь к
диалоговому окну Standard Report Expert, открыв узел Northwind иерархического
дерева, перейдите к узлу Tables, затем дважды щелкните по узлу Customers. На
вкладке Fields щелкните по кнопке Add All, чтобы добавить в отчет все поля
таблицы Customers. Далее, убедитесь в том, что на вкладке Style для создаваемого
отчета указан соответствующий заголовок в поле Title и выбран стиль в списке
Style, затем щелкните по кнопке Finish. После этого активируется разработчик Crystal Reports for Visual Studio .NET и
появится созданный отчет. Также появится окно Field Explorer, состыкованное с
окнами Server Explorer и Toolbox. В последнем из них находится палитра Crystal
Reports. Кроме того, в левом верхнем углу панели инструментов Visual Studio .NET
появится панель инструментов Crystal Reports. Я воспользуюсь этим отчетом для иллюстрации примеров, содержащихся в этой
статье. В качестве первого примера рассмотрим отображение отчета в окне.
Выполнить это довольно легко. Просто перенесите CrystalReportViewer из палитры
Windows Forms окна Toolbox в среду разработчика для формы по умолчанию в проекте
и установите для атрибута Name значение cvwMain, для атрибута Dock значение
Fill, для атрибута ReportSource - мой отчет (используя опцию Browse) и затем
запустите приложение. После того, как я спроектирую отчет, войдя в базу данных с
пустым паролем, этот отчет сразу появится на экране. При наличии непустого
пароля для отображения отчета потребуется снова войти в базу данных. Далее я
покажу, как написать небольшую программу, автоматизирующую вход в базу данных, с
помощью которой пользователи, уже прошедшие процедуру аутентификации, не будут
повторно входить в базу данных для запуска отчетов. Теперь, когда я кратко изложил основные принципы создания простых отчетов,
давайте перейдем к более сложным вопросам. Подобно тому, как создаются строго
типизированные наборы DataSets со своими атрибутами и методами, можно создать
строго типизированные отчеты. По своему существу все отчеты, созданные с помощью
Crystal Reports и Visual Studio .NET, составляют класс строго типизированных
отчетов в качестве побочного продукта самого процесса разработки. Чтобы в этом
убедиться, щелкните по кнопке Show All Files (Показать все файлы) в Solution
Explorer, перейдите по иерархическому дереву к CustomersBasic.rpt и убедитесь в
существовании файла класса, созданного Visual Studio .NET. Я могу создать
экземпляр этого класса в программе и назначить его атрибуту ReportSource объекта
CrystalReportViewer, содержащегося в моей форме. Для этого я добавлю следующую
строку текста программы к событию формы Load (установив атрибут ReportSource
формы cvwMain в None в первом окне Properties). cvwMain.ReportSource = New CustomersBasic() Подобно строго типизированным наборам DataSets, которые используют
разработчик компонентов DataSet, строго типизированные отчеты также имеют
соответствующий разработчик компонентов. Если щелкнуть по палитре компонентов
Components окна Toolbox в Visual Studio .NET, появится объект под названием
ReportDocument. Перетащив его на свою форму, вы увидите имя класса вашего отчета
в раскрывающемся списке Name диалогового окна Choose a ReportDocument. Выберите
его и щелкните по кнопке OK. Вы получите исполняемый доступный экземпляр класса
вашего отчета. Переименуйте этот объект в cbsMain (cbs является префиксом
CustomersBasic) и замените следующей строкой текста программы в событии формы
Load: cvwMain.ReportSource = cbsMain Если вы сейчас снова запустите приложение, то ваш отчет запустится, как и
прежде. Этот запуск отличается от предыдущего тем, что, не ссылаясь на
конкретный файл, находящийся в конкретном физическом месте, ReportViewer
обращается непосредственно к объекту, который может выступать в качестве
экземпляра, полученного из соответствующего класса в сборке приложения, внешней
сборке или, как вы увидите далее, в XML Web Service. Как я уже упоминал, если вы для создания отчета предоставили информацию о
подключении с идентификатором пользователя и пустым паролем, то этот отчет после
своего создания будет открыт немедленно. В любых других случаях генератор
отчетов Crystal Reports for Visual Studio .NET предложит вам зарегистрироваться,
поскольку вся информация о подключении, кроме пароля, сохраняется отчетом. Если
вам потребуется предоставить пароль во время выполнения программы или другой
набор информации о подключении, кроме той, которая уже была предоставлена во
время создания отчета (что случается довольно часто), используйте программу,
приведенную на рисунке 2 перед установкой cvwMain.ReportSource. For Each tbCurrent In cbsMain.Database.Tables Рис. 2. Запись Crystal Reports в базу данных В программе на рисунке 2 я произвольно задал сервер, идентификатор
пользователя и пароль, т.е. localhost, ReportUser и msdn соответственно. В
большинстве приложений вам, вероятно, придется использовать глобальные
переменные или атрибуты класса, или даже переменные сеанса в случае приложения
ASP.NET, чтобы в любой момент можно было предъявить имя базы данных и учетные
данные пользователя вашего приложения, введенные при первоначальной регистрации.
Обратите внимание на цикл For Each в программе. Поскольку в моем отчете
содержится только одна таблица, этот цикл по большому счету необязателен (я мог
бы просто сделать ссылку на cbsMain.Database.Tables(0)), однако, эта программа
будет работать с любым отчетом Crystal Reports for Visual Studio .NET, поэтому я
предпочел его оставить, сделав программу более функциональной. Теперь рассмотрим другие способы конфигурации элементов управления объекта
CrystalReportViewer. Одним из таких способов на этапе разработки является
использование проводника Server Explorer. В связи с последними изменениями в
.NET Framework данная функция генератора отчетов Crystal Reports for Visual
Studio .NET некорректно устанавливается инсталлятором Visual Studio. Чтобы ее
настроить и продолжить выполнение следующих шагов, описанных в статье,
убедитесь, что все права доступа для папки Crystal Reports в каталоге Visual
Studio .NET установлены и осуществляется полное управление пользовательской
средой ASPNET. (Кстати, по умолчанию эта папка находится в C:\Program
Files\Microsoft Visual Studio .NET\Crystal Reports). Проверить права доступа
можно с помощью вкладки Security в окне свойств папки. Чтобы открыть вкладку
Security, пользователи Windows XP должны выбрать пункт меню Tools | Folder
Options в окне Explorer, щелкнуть по вкладке View и снять флажок "Use simple
file sharing", который является последним пунктом в списке Advanced settings.
После выполнения этих шагов все последующие шаги должны выполняться
корректно. Щелкните по узлу Servers иерархического дерева, затем по узлу с именем вашего
локального компьютера, далее по расположенному под ним Crystal Services и,
наконец, по Server Files. Под этим узлом появятся две папки, в каждой из которых
будут содержаться несколько файлов отчетов (см. рис.3). Любой из этих
.rpt-файлов можно перетащить в среду разработчика формы, который завершит
создание объекта разработчика компонентов ServerFileReport, указывающего на
правильный .rpt-файл. Теперь нашим следующим шагом будет установление связи
между этим объектом и вашим отчетом. Рис. 3. Server Explorer Таким образом, все папки и файлы отчетов, отображаемые в этом
разделе Server Explorer, будут расположены в отдельном каталоге на жестком диске
сервера. По умолчанию эта папка содержится в подкаталоге Samples\Reports
основной папки Crystal Reports, о которой я уже говорил. Две упомянутые прежде
папки являются подкаталогами основной папки Crystal Reports и в них физически
содержатся все персональные .rpt-файлы. Чтобы ваш отчет появился в Server Explorer, скопируйте его в
родительскую папку, либо в одну из его дочерних папок, либо в вашу собственную.
Например, в папке Samples\Reports вы можете создать папку MSDN и скопировать в
нее CustomersBasic.rpt. Затем, если вы щелкните правой кнопкой мыши по узлу
Server Files в Server Explorer и выберите Refresh в контекстном меню, то
появится папка MSDN с дочерним узлом для CustomersBasic.rpt. Перетащите его на
вашу форму и переименуйте конечный объект sfrCustomersBasic. В окне Properties
задайте атрибут ReportSource формы cvwMain, указав на этот объект.
Закомментируйте каждую строку программы в событии формы Load и запустите
приложение, после чего на экране появится ваш отчет. Позднее я расскажу о дополнительных возможностях разработчика
компонентов ServerFileReport, а сейчас нам нужно рассмотреть следующий шаг,
который заключается в модифицировании отчета с целью получения данных
посредством поставщика DB OLE из ADO.NET DataSet, а не из физической базы
данных. Сначала создадим строго типизированный набор DataSet на основе таблицы
Customers базы данных Northwind. Для этого используем наиболее простой способ,
добавим в проект пустой набор DataSet и присвоим ему имя DataSet
dsNorthwind.xsd, открыв диалоговое окно Add New Item (см. рис.4). Рис.4. Добавление DataSet Откройте дизайнер компонентов DataSet, дважды щелкнув по
соответствующему узлу в Solution Explorer. Перетащите таблицу Customers из
Server Explorer на плоскость разработки DataSet и сохраните файл. Затем откройте
отчет, щелкните правой кнопкой мыши по его плоскости разработки, чтобы открыть
контекстное меню, и выберите Database и Set Location. В диалоговом окне Set
Location разверните узлы Project Data, ADO.NET DataSets и узел для вашего набора
DataSet, затем выберите таблицу Customers. Наконец, в раскрывающемся списке
Current Data Source выберите Customers и щелкните по кнопке Replace. После этого
отчет будет обращаться к вашему строго типизированному набору DataSet для
получения метаданных и будет запускаться при привязке к экземпляру этого набора.
Для продолжения щелкните по кнопке Close. Теперь, когда я модифицировал отчет для работы с экземпляром
dsNorthwind, нужно создать его в моей форме и задать в атрибуте ReportSource
объекта CrystalReportViewer. Для этого перетащите таблицу Customers из Server
Explorer на плоскость разработки формы, тем самым добавив в нее объекты
SQLConnection и SQLDataAdapter, указывающих на базу данных Northwind и на
таблицу Customers этой базы данных соответственно. Переименуйте эти объекты в
scnNorthwind и sdaCustomers и измените атрибут ConnectionString объекта
scnNorthwind, включив в него идентификатор пользователя и пароль. Затем щелкните
правой кнопкой мыши по sdaCustomers и выберите Generate Dataset. В разделе
"Choose a dataset" выберите радиокнопку Existing, а в правом от нее
раскрывающемся списке имя класса вашего строго типизированного набора DataSet
(такой выбор наиболее соответствует настройкам по умолчанию). На рисунке 5 это
показано достаточно ясно. Рис. 5. Создание DataSet Щелкните по кнопке OK, переименуйте новый объект DataSet в
"ndsMain" и замените код события Load на следующий фрагмент: sdaCustomers.Fill(ndsMain) Обратите внимание, что в данном фрагменте фигурирует созданный
мною объект "ndsMain", который является экземпляром класса dsNorthwind строго
типизированного набора DataSet. Далее, этот фрагмент программы задает атрибуту
DataSource объекта "cbsMain" (экземпляр класса строго типизированных отчетов
CustomersBasic) значение "ndsMain". И, наконец, как и в предыдущих примерах,
атрибуту ReportSource формы cvwMain (мой объект CrystalReportViewer) я задаю
значение "cbsMain". Запустите свое приложение и убедитесь, что отчет выполняется и
отображается на экране так же, как и в других случаях. Этот пример отличается
тем, что в нем данные поступают не из базы данных, а от изолированного объекта
DataSet. В моем случае заполнение объекта DataSet осуществлялось с помощью
прямого запроса к таблице Customers. (Чтобы увидеть фактический текст запроса, в
объекте sdaCustomer выберите SelectCommand и затем CommandText.) Я мог бы
построить этот объект DataSet из любого источника данных или из нескольких
выбранных мною источников, поскольку построенный набор данных зависим от
структуры ndsNorthwind. Чтобы проиллюстрировать эту тему, сначала создадим
параметризованную хранимую процедуру для работы с таблицей базы данных
Customers, имеющей имя spCustomers. Эта хранимая процедура забирает параметр
строки, который должен использоваться в операторе WHERE для ограничения
количества возвращаемых записей. После этого в тексте программы я построю объект
набора данных DataSet для этой процедуры и свяжу отчет с этим набором данных.
Вот текст хранимой процедуры. CREATE PROCEDURE dbo.spCustomers Вы можете создать хранимую процедуру любым удобным способом;
например, с помощью Visual Studio .NET, как это показано на рисунке 6. Рис. 6. Создание хранимой процедуры с помощью Visual
Studio .NET Чтобы создать отчет из хранимой процедуры (присвоив параметру
@CustPattern произвольное значение "A"), я изменил текст события формы Load (см.
пример на рисунке 7). Private Sub frmViewReport_Load(ByVal sender As Object, ByVal
e As _ Dim scmCustomersSP As New
SqlClient.SqlCommand("spCustomers",
_ Dim sdaCustomersSP As New
SqlClient.SqlDataAdapter(scmCustomersSP) cbsMain.SetDataSource(dsReport) End Sub Рис. 7. Модифицированный OnLoad Event В этой программе не используется ни один из тех объектов, которые
были созданы на этапе разработки, за исключением объекта scnNorthwind.
Существенно и то, что в этой программе также не используется экземпляр
dsNorthwind строго типизированного набора DataSet в качестве источника данных
для отчета. Вместо него я применил объект ADO.NET DataSet без контроля типов и с
именем dsReport. Это чрезвычайно важно несмотря на то, что этот отчет разработан
для строго типизированного набора DataSet. Во время запуска отчета в качестве
источника данных будет задан универсальный объект DataSet без контроля типов,
структура которого соответствует структуре экземпляра dsNorthwind. Когда
потребуется вызвать метод Fill объекта DataAdapter, я буду использовать
переопределяемую версию, которая должна принять некое табличное имя. Чтобы
гарантировать структурное соответствие dsReport и dsNorthwind, я задам для этого
табличного имени имя Customers. Если я этого не сделаю, то на экране появится
отчет без каких-либо данных. Отчет можно создать не только на основе таблицы базы данных, как
это было продемонстрировано в первом примере, но и на основе хранимой процедуры.
Для установки значения параметра в программе требуется определенная команда,
затрагивающая объекты, атрибуты и методы в разных пространствах имен генератора
отчетов Crystal Reports for Visual Studio .NET. Рассмотрим это более
подробно. Чтобы хранимые процедуры можно было выбирать в качестве источников
данных, требуется настроить генератор отчетов Crystal Reports for Visual Studio
.NET. Для этого щелкните правой кнопкой мыши по пустой области в плоскости
разработки отчета и выберите в контекстном меню пункт Designer | Default
Settings. В диалоговом окне Default Settings откройте вкладку Database,
проверьте, установлен ли флажок Stored Procedures в разделе Show, и щелкните по
кнопке OK. Затем щелкните правой кнопкой мыши по плоскости разработки отчета
и выберите в контекстном меню пункт Database | Set Location. Спуститесь по
иерархическому дереву Replace With к узлу OLE DB (ADO), еще раз щелкните правой
кнопкой мыши, чтобы открылось диалоговое окно OLE DB (ADO), и введите всю
необходимую информацию для подключения к вашей копии базы данных SQL Server
Northwind. Вернувшись к диалоговому окну Set Location, разверните узел
Northwind, затем узел Stored Procedures и выберите узел spCustomers;1. В
комбинированном списке Current Data Source укажите Customers, щелкните по кнопке
Replace и затем по кнопке Close. Теперь, когда вы настроили этот отчет - который был первоначально
разработан на основе таблицы Customers базы данных Northwind и преобразован для
использования строго типизированного набора данных в качестве источника данных -
вы можете использовать для получения данных хранимую процедуру spCustomers.
Поскольку spCustomers является параметризированной хранимой процедурой,
генератор отчетов Crystal Reports for Visual Studio .NET автоматически добавит в
ваш отчет поле для параметров Crystal Reports с именем параметра хранимой
процедуры. Чтобы в этом убедиться, разверните в окне Field Explorer узел
Parameter Fields. Справа под ним вы увидите поле с параметром @CustPattern (см.
рис.8). Рис. 8. Параметры Теперь вы можете установить cvwMain.ReportSource как на этапе
разработки, так и в самой программе, указав на rpt-файл или на экземпляр cbsMain
разработчика компонентов ReportDocument. При запуске приложения генератор
отчетов Crystal Reports for Visual Studio .NET автоматически откроет диалоговое
окно, запрашивающее значение параметра @CustPattern. Введите любую понравившуюся
вам строку, чтобы генератор отчетов подключал только тех клиентов, у которых
значение поля CompanyName будет начинаться с этой строки. Не смотря на то, что генератор отчетов Crystal Reports for Visual
Studio .NET может запросить значения параметров и запустить отчет без написания
программного кода, в большинстве случаев желательно, чтобы эти значения
запрашивались у приложений и передавались в отчет программным путем. На рисунке
9 приведена программа, необходимая для программного присваивания значений
параметров с помощью объектной модели Crystal Reports. В этой программе я снова
использовал произвольное значение "A", присвоив его параметру
pdvCustPattern. Private Sub frmViewReport_Load(ByVal sender As Object, ByVal
e As _ Dim pvCustPattern As New
CrystalDecisions.Shared.ParameterValues() pdvCustPattern.Value =
"A" cvwMain.ReportSource = cbsMain End Sub Рис. 9. Назначение параметров Относительно этой программы необходимо сделать ряд замечаний. Мне
не совсем понятно, почему параметрам T-SQL можно присвоить только одно значение,
в то время как полям параметров генератора отчетов Crystal Reports for Visual
Studio .NET присваивается совокупность значений. Учитывая этот факт, я построил
такую совокупность значений, которая состоит только из одного элемента, и
присвоил ему значение "A". В результате эта программа создает не только
pvCustPattern, экземпляр объекта CrystalDecisions.Shared.ParameterValues,
который допускает использование нескольких значений, но и pdvCustPattern,
экземпляр класса CrystalDecisions.Shared.ParameterDiscreteValue, который
допускает использование только одного значения. Программа присваивает строку "A"
атрибуту Value для pdvCustPattern и загружает его в pvCustPattern посредством
метода суммирования. Затем pvCustPattern присваивается полю параметра
@CustPattern посредством метода ApplyCurrentValues, а экземпляр CustomersBasic
присваивается атрибуту ReportSource в средстве отображения отчетов. Хотя эта
программа может показаться несколько скомканной, она, тем не менее,
работает. Теперь можно рассмотреть, как используется технология XML Web Services в
Crystal Reports for Visual Studio .NET. Значительным достижением в этой области
является удачная разработка достаточно сложных функций с легко реализуемыми
преимуществами; например, отчеты могут публиковаться как Web-службы и
использоваться в качестве ReportSource для элемента управления
CrystalReportViewer. Чтобы создать Web-службу для XML-отчетов из файла CustomersBasic.rpt,
откройте Visual Studio .NET и создайте новый проект ASP.NET Web Service под
именем MSDNCrystalWebService. Удалите файл Service1.asmx, который добавляется к
проекту по умолчанию, и вместо него добавьте CustomersBasic.rpt. Затем щелкните
правой кнопкой мыши по CustomersBasic.rpt в Solution Explorer и выберите в
контекстном меню пункт Publish as Web Service (см. Рисунок 10). Рис. 10.
В результате в проект будет добавлен файл Web-службы,
CustomersBasicService.asmx. Теперь будем компоновать проект. Вернитесь в
приложение Windows Forms и установите для cvwMain.ReportSource URL-адрес Report
Web Service согласно следующей строке текста программы: cvwMain.ReportSource = "http://localhost/MSDNCrystalWebService/" _ В качестве альтернативы вы можете добавить веб-ссылку для этого asmx-файла в
проекте и затем указать cvwMain.ReportSource в экземпляре класса Web
Service. cvwMain.ReportSource = New localhost.stomersBasicService() Можно ли создать интерфейс XML Web Services в Crystal Reports так же легко,
как и Web-службу? Внимательно изучите программу файла класса, который расположен
с небольшим отступом под файлом CustomersBasic.rpt (чтобы увидеть файл, щелкните
по кнопке Show All Files в Solution Explorer). В программе этого файла
содержатся два класса: CustomersBasic и CachedCustomersBasic. CustomersBasic является первичным классом, который необходим для реализации
строго типизированного отчета; если вы посмотрите на процедуры атрибутов этого
отчета, то увидите его со всеми разделами, которые наследуются из ReportClass и
охватывают элементы коллекции ReportDefinition.Sections. В свою очередь,
CachedCustomersBasic реализует интерфейс IcachedReports для создания
кешированного отчета и в своем методе CreateReport создает экземпляр
CustomersBasic (первый класс). С помощью интерфейса, подобного интерфейсу
IcachedReports и использующего WebMethods, можно вывести отчет в виде XML Web
Service. Теперь взгляните на программу файла класса, который расположен под файлом
CustomersBasicService.asmx. Этот файл также содержит два класса, но, в отличие
от предыдущего файла, в нем один класс вложен в другой. CustomersBasicService
наследуется из класса ReportServiceBase, который, в свою очередь, открывает
веб-методы, необходимые для публикации отчета в виде XML Web Service.
CustomersBasicService содержит класс CachedWebCustomersBasic, который, по своему
существу, имеет точно такую же реализацию, что и уже рассмотренный класс
CachedCustomersBasic. Различие можно найти в конструкторе: Public Sub New(ByVal webServiceParam As
CustomersBasicService) Этот конструктор вызывается из конструктора CustomersBasicService, чтобы
указать в нем атрибут webService кешированного отчета: Public Sub New() Подведем итоги: ReportClass в Crystal Report создает возможные строго
типизированные отчеты; интерфейс IcachedReports позволяет создавать кешированные
экземпляры ReportClass; и, наконец, ReportServiceBase создает интерфейс Web
Services для строго типизированных отчетов, который благодаря атрибуту
webService совместим с интерфейсом IcachedReports. Кстати, вы не забыли о компоненте ServerFileReport, который я создал,
перетащив из Server Explorer? В нем также задействуется технология Web Services.
Если вы вернетесь в проект Windows Form, то заметите, что у sfrCustomersBasic
имеется атрибут WebServiceURL указывающий на .asmx-файл общего вида. Адрес URL
будет выглядеть примерно следующим образом:
localhost/crystalreportwebformviewer/ServerFileReportService.asmx. Несмотря на
то, что этот URL-адрес стандартен, атрибут ReportPathProperty класса
sfrCustomersBasic, указывая на \MSDN\ CustomersBasic.rpt, задает относительный
путь и имя отчета, который требуется запустить. С первого взгляда кажется странным, что компонент ServerFileReport требует
запуска отчета через соединение HTTP/SOAP с локальным компьютером. Однако,
благодаря этому вы можете легко запустить отчеты Crystal Reports for Visual
Studio .NET, существующие на удаленном компьютере: просто щелкните правой кнопки
мыши по узлу Servers в окне Server Explorer и выберите Add Server, затем
подключитесь к любому серверу в ваших сетях LAN/WAN и запустите на удаленном
компьютере требуемые отчеты Crystal Reports for Visual Studio .NET. Данная
возможность позволяет легко развертывать отчеты по всему предприятию: для этого
установите среду Visual Studio .NET на сервере и скопируйте rpt-файлы в
соответствующую папку, после чего эти rpt-файлы без какой-либо специальной
программы станут доступны для всей организации (по протоколу SOAP). В этом
случае вам даже не потребуется такой относительно простой процесс, как выбор
пункта "Publish as Web Service", который выполняется после щелчка правой кнопки
мыши по отчету в проекте ASP.NET, поскольку все, что вам будет нужно сделать,
так это скопировать файл в соответствующую папку. Недостаток использования операции перетаскивания объектов в Server Explorer
заключается в том, что в нем можно просматривать только те объекты сервера,
которые постоянно находятся в сетях LAN/WAN разработчика, а не за брандмауэром.
Но тут есть одна хитрость: пока известны адрес URL и значение атрибута
ReportPath при подключенном к сети Internet сервере (с брандмауэром или нет), вы
сможете создать новый экземпляр CrystalDecisions.ReportSource.ServerFileReport и
задать в нем значения этих атрибутов, указав их в программе. Интерфейс SOAP так удобен и прост, что Crystal Reports for Visual Studio .NET
применяет его в качестве оболочки программ сортировки для своего более раннего
продукта, сервера Crystal Enterprise. Узел Crystal Enterprise под Crystal
Services в Server Explorer можно использовать для просмотра отчетов,
содержащихся на любом сервере Crystal Enterprise в сети LAN/WAN, а также для
использования этих отчетов в качестве допустимых значений ReportSources для
элемента управления CrystalReportViewer при повторном применении SOAP. В этом
случае отчеты Crystal Enterprise будут доступны для любых подключенных к сети
Internet генераторов отчетов Crystal Reports for Visual Studio .NET с правильным
адресом URL и идентификатором объекта. До сих пор все, что я сделал на клиентском компьютере, было выполнено в
приложении Windows Forms, однако отчеты можно также представлять и в
веб-приложениях ASP.NET. К счастью, Crystal Reports for Visual Studio .NET
поддерживает технологию ASP.NET. Теперь я покажу, как представлять отчеты в виде
документов HTML или документов Acrobat (PDF), используя элемент управления
ASP.NET Web Forms CrystalReportViewer. Кроме того, я рассмотрю кэширование и
использование кешированных данных. Поскольку Web Forms CrystalReportViewer работает аналогично Windows Forms,
изложение основных операций займет не слишком много времени. Для начала создайте
в среде Visual Studio .NET новое веб-приложение ASP.NET Web Application и,
используя функцию Add Existing Item, добавьте в проект CustomersBasic.rpt. Затем
задайте местоположение данных для отчетов, вернувшись к таблице Customers, и в
целях тестирования используйте вход с пустым паролем. Переименуйте WebForm по
умолчанию в ViewReport.aspx и добавьте к нему элемент управления Web Forms
CrystalReportViewer, задав для его атрибута ID значение cvwMain. Поскольку на
этапе разработки элемент управления Web Forms CrystalReportViewer не имеет
атрибута ReportSource, следует задать этот атрибут в событии Page_Load в
ViewReport.aspx следующим образом: cvwMain.ReportSource = Server.MapPath("CustomersBasic.rpt") Запустив приложение, убедитесь в эффективности данной процедуры. Этот отчет
является чистым HTML-документом несмотря на то, что в нем поддерживаются функции
поиска, навигации, масштабирования и других элементов управления просмотром
(кроме печати - об этом речь пойдет позже), хотя и с помощью переадресации
(postback). Можно попробовать и другие способы загрузки отчета, которые я уже
рассматривал: создание отчета из строго типизированного набора DataSet или из
набора DataSet без контроля типов, из хранимой процедуры с помощью
ReportDocument или разработчика компонентов ServerFileReport и т.п. Можно
скопировать в событие Page_Load в ViewReport.aspx программу, которую я уже
использовал для настройки учетной информации отчета и значений параметров, а
также для манипулирования объектами ADO.NET. Это аналогично тому, что я уже
делал, и я не буду повторяться, хотя опция ReportDocument требует некоторого
объяснения. Теперь давайте рассмотрим функции Crystal Reports for Visual Studio .NET для
кешированных отчетов. Перетащите разработчик компонентов ReportDocument на
плоскость разработки ViewReport.aspx и выберите ProjectName.CustomersBasic из
Name: комбинированного списка в диалоговом окне Choose a ReportDocument, не
нажимая кнопку OK. Обратите внимание на флажок "Generate cached strongly typed
report" ("Создать кешированный строго типизированный отчет") (см.
рис.11). Рис. 11 Функция кешированных отчетов
Установите этот флажок. Щелкните по кнопке OK и назовите созданный компонент
как ccbMain. Затем, свяжите элемент управления просмотра с этим объектом в
событии Page_Load с помощью следующей строки программы: cvwMain.ReportSource = ccbMain Перетащите элементы управления Data Time и Print Time в раздел заголовка
страницы отчета. Эти элементы управления можно найти в окне Field Explorer под
узлом Special Fields. Затем запустите приложение и просмотрите отчет. Когда вы
его запустите в первый раз, элементы управления Data Time и Print Time должны
быть одинаковыми (или же очень похожими). Но если вы обновите страницу, то
увидите, что Print Time продолжает обновляться, а Data Time остается одним и тем
же. Теперь скопируйте текущий адрес URL обозревателя в буфер обмена и закройте
обозреватель. Откройте окно нового обозревателя и вставьте в него указанный
адрес URL для просмотра отчета в новом сеансе (без перестройки сборки из Visual
Studio .NET). Вы увидите, что исходная временная метка будет отображаться в Data
Time. Теперь закройте обозреватель и вернитесь в Visual Studio .NET. Снова
перетащите дизайнер компонентов ReportDocument на плоскость разработки
ViewReport.aspx и выберите ProjectName.CustomersBasic, сняв флажок "Generate
cached strongly typed report". Щелкните по кнопке OK и назовите созданный
компонент как "cbsMain". После завершения данной операции свяжите элемент
управления просмотра с созданным объектом в событии Page_Load, внеся в программу
имя нового компонента: cvwMain.ReportSource = cbsMain Запустив приложение, просмотрите отчет и обновите несколько раз страницу. При
этом вы увидете, как будет изменяться элемент управления Data Time при каждом
обновлении. Эта операция наглядно продемонстрирует вам основное различие между
кешированными и некешированными отчетами: кэширование позволяет избежать лишних
обращений к базе данных, когда уже есть требуемые данные. Когда вы используете атрибуты DataDefinition или Database объекта cbsMain
(экземпляр моего некешированного ReportDocument) для задания значений параметров
или атрибутов входа в таблицы, обратите внимание, что ccbMain (экземпляр
кешированного ReportDocument) не имеет таких атрибутов. Как использовать
кешированные отчеты по отношению к защищенным таблицам и параметризованным
хранимым процедурам? Ключ лежит в программе, расположенной позади строго
типизированного отчета. Снова щелкните по кнопке Show All Files (Показать все
файлы) в Solution Explorer, перейдите к CustomersBasic.rpt и откройте позади
него файл программы. Вы уже были здесь, но сейчас вам следует открыть программу
для класса CachedCustomersBasic, содержащуюся в этом файле. Обратите внимание, что программа создает новый экземпляр некешированного
класса CustomersBasic для своего метода CreateReport, поскольку
CachedCustomersBasic в действительности содержит CustomersBasic. Таким образом,
я могу написать настраиваемую программу в этом общедоступном методе, чтобы иметь
доступ к атрибутам Database и DataDefinition как созданного экземпляра класса
CustomersBasic, так и интерфейса с защищенными объектами базы данных и
параметризованными хранимыми процедурами. Если я применяю этот метод, то при
создании нового экземпляра кешированного отчета будет создаваться
соответствующий сконфигурированный экземпляр некешированного строго
типизированного отчета. Теперь прокрутите несколько вниз, чтобы увидеть снабженную комментариями
программу для другого важного метода, GetCustomizedCacheKey. Этот метод
генерирует уникальный ключ, который определяет, будет ли использоваться копия
кешированного отчета для выполнения запроса. Если ключ совпадает с ключом
кешированного отчета, то будет использоваться кешированная копия. Если не
совпадает, то данные будут выбираться заново. Если вы убрали из программы комментарии, то специальная функция
BuildCompleteCacheKey сгенерирует уникальный ключ для конкретного отчета.
Раскомментированная программа, которая во всем остальном оставлена без
изменений, выполняется так же как программа с комментариями. Если этот ключ не
модифицируется, то Crystal Reports неявно использует алгоритм
BuildCompleteCacheKey для создания вашего ключа. Это подходит для многих
случаев. Но что делать, если вам требуется модифицировать ключ? Предположим, вы
узнали, что в какой-то момент времени ваши данные значительно изменились. Тогда
вы могли бы приписать к ключу кеша свою строку, чтобы обеспечить его изменение в
этот момент времени или после него. Приведем тривиальный пример:
раскомментируйте программу в GetCustomizedCacheKey и вставьте перед оператором
Return следующую строку: key &= DatePart(DateInterval.Minute, Now()) Эта строка прозволяет генерировать новый ключ кеша в тот момент, когда
текущее время изменяется на одну минуту. В событии Page_Load класса
ViewReport.aspx укажите ccbMain для cvwMain.ReportSource, затем запустите
приложение и обновите несколько раз страницу. При этом вы увидите изменение в
Data Time, которые происходят, когда минутный отсчет фактического времени
увеличивается на единицу. Подобным образом можно приписать к ключу кеша значения
различных параметров и другие детали, связанные с данными, чтобы избежать
обработки одних и тех же кешированных данных при прогонах отчета. Можно создать
собственный ключ, не просто прибавляя кое-какие строки к ключу кеша по
умолчанию, но написав его целиком с самого начала; но этот метод я не буду
рекомендовать хотя бы потому, что это все равно, что изобретать колесо. Конечно, эти изменения в классе строго типизированных отчетов весьма полезны,
но они связаны с некоторым риском, поскольку при обновлении отчета Visual Studio
.NET попытается переписать файл класса этого отчета и, если не принять
соответствующих мер, то вы потеряете внесенные изменения. Чтобы этого избежать,
вам следует создать собственный класс, реализующий IcachedReport с программой из
класса CachedCustomersBasic. После этого вы сможете создать в ViewReport.aspx, а
именно в событии Page_Load, экземпляр этого класса и указать на него в
cvwMain.ReportSource. На Figure 12 показана программа для данного класса
(включая программу, использующую объект ASP.NET Request для задания значения
поля параметра отчета и для добавления этого значения в ключ кеша), а также
программа (см. ниже), демонстрирующая код события Page_Load, который требуется
для ее использования. Private Sub Page_Load(ByVal sender As System.Object, _ Dim mcrMain As New cMSDNCachedReport() Сильная сторона элемента управления Web Forms CrystalReportViewer заключается
в том, что он представляет отчеты в виде документов HTML, но в этом и его
слабость. С одной стороны, такое представление отчетов содействует максимальной
совместимости Crystal Reports for Visual Studio .NET и клиентских обозревателей;
с другой, язык HTML не предусматривает точное постраничное разбиение при выводе
на печать. Чтобы обойти проблемы, связанные с печатью, следует преобразовать отчет в
формат Adobe Acrobat (PDF). Вы можете написать довольно простую программу
ASP.NET, которая позволила бы программным способом преобразовать отчет в формат
PDF и затем перенаправила бы ваш обозреватель на этот файл. Таким образом,
пользователь может запросить отчет через событие Postback и получить адрес
PDF-версии отчета, которую он будет печатать. На Figure 13 показана программа,
позволяющая выполнить эту операцию. Для простоты я использую некешированный
объект cbsMain компонента ReportDocument для генерирования отчета. Если вы для представления отчетов собираетесь использовать PDF-файлы, вам
следует узнать о недостатках этого метода. Во-первых, чтобы удовлетворить
многочисленным пользователям, вы должны дать уникальные имена созданным
PDF-файлам; программа на Figure 13 использует постоянную текстовую строку,
поэтому она годится только для демонстрации предлагаемого метода. Во-вторых, в
какой-то момент времени PDF-файлы должны быть окончательно отредактированы, и, в
зависимости от количества готовых отчетов на вашем приложении, весь файловый
ввод-вывод, связанный с созданием и доводкой PDF-файлов, может при неправильном
управлении и настройке значительно замедлить функцию масштабируемости. При
создании приложений ASP.NET с помощью Crystal Reports for Visual Studio .NET
рекомендуется изучить программу просмотра со стороны клиента и составить
стратегию печати, поскольку у каждой опции имеется свой набор значимых
аргументов "за" и "против". В этой статье я подробно рассмотрел возможности генератора отчетов Crystal
Reports for Visual Studio .NET, хотя за ее рамками осталось много интересного
материала, требующего отдельного исследования. Ничего более не желая, я
рассчитываю на то, что вы после ее прочтения осознаете богатство предоставляемых
возможностей и прекрасную интеграцию этого инструмента с .NET Framework и Visual
Studio .NET. Код для вставки в блог:
Загрузка примеров кодов для этой статьи: Crystal.exe (391KB) Простой отчет

Строго типизированные отчеты
Dim tbCurrent As
CrystalDecisions.CrystalReports.Engine.Table
Dim tliCurrent As
CrystalDecisions.Shared.TableLogOnInfo
tliCurrent =
tbCurrent.LogOnInfo
With tliCurrent.ConnectionInfo
.ServerName =
"localhost"
.UserID = "ReportUser"
.Password =
"msdn"
.DatabaseName = "Northwind"
End
With
tbCurrent.ApplyLogOnInfo(tliCurrent)
Next
tbCurrentServer Explorer

Создание отчетов из DataSets

cbsMain.SetDataSource(ndsMain)
cvwMain.ReportSource
= cbsMainСоздание отчетов из хранимых процедур
(
@CustPattern
nVarChar(40)
)
AS
select * from Customers Where CompanyName Like
@CustPattern + '%'
RETURN
System.EventArgs) Handles MyBase.Load
scnNorthwind)
scmCustomersSP.CommandType =
CommandType.StoredProcedure
scmCustomersSP.Parameters.Add("@CustPattern",
"A")
Dim dsReport As New
DataSet()
sdaCustomersSP.Fill(dsReport, "Customers")
cvwMain.ReportSource =
cbsMain
System.EventArgs) Handles MyBase.Load
Dim pdvCustPattern As New
_
CrystalDecisions.Shared.ParameterDiscreteValue()
pvCustPattern.Add(pdvCustPattern)
cbsMain.DataDefinition.ParameterFields
_
("@CustPattern").ApplyCurrentValues(pvCustPattern)
&
"CustomersBasicService.asmx"
Me.webService = webServiceParam
End Sub
Me.ReportSource = New CachedWebCustomersBasic(Me)
End
SubПостроение отчетности в клиентских приложениях ASP.NET
Кешированные ReportDocuments
ByVal e As
System.EventArgs) Handles MyBase.Load
McrMain.ASPRequest =
Request
CvwMain.ReportSource = mcrMain
End SubПреобразование в формат PDF
Заключение
Оставьте свой комментарий
Новостная лента
SAP выпускает новые приложения для бизнес-платформы HANA
Европейский сервис iZettle позволит принимать банковские карты через iPhone
Facebook покупает команду разработчиков проекта Lightbox
Google анонсировала новую функцию "Диаграмма знаний"
Nvidia предлагает перенести компьютерные игры в облако
The Pirate Bay уже более суток находится под DDOS
Virgin Atlantic разрешит сотовые звонки в самолетах
У покупателей планшетов с Windows RT может не быть широкого выбора моделей
Blizzard предупреждает о перегрузке серверов Diablo III
Google выпустила Chrome 19
Wikimedia предупреждает о возможном заражении пользователей Википедии вредоносным ПО
Роль облачных вычислений в бизнесе растет - опрос
Evernote обновила приложение для Android
