При работе с некоторыми источниками данных, иногда приходится создавать алиасы для полей таблицы. Это бывает, когда названия полей не понятны интуитивно или используется неродной язык при их именовании. Для повышения удобства работы с такими базами данных, FastReport .Net позволяет создавать алиасы. Но создавать их вручную при каждом создании нового отчета совсем не удобно. Поэтому я расскажу, как создать алиасы в программном коде. Это позволит использовать данный источник данных во многих отчетах.
Для наглядности я создам приложение с немецкой локализацией. То есть интерфейс и названия полей будут на немецком языке.
Нужно учитывать, что источник данных с алиасами должен быть доступен и при создании отчета с помощью меню File->New. Для этого нам потребуется перехватить событие выбора меню New.
Воспользуемся приложением WindowsForms.
Добавим на форму две кнопки.
Первая запускает дизайнер с пустым отчетом. Вторая – открывает в дизайнере демонстрационный отчет.
Добавляем библиотеки:
1 2 3 4 5 6 |
using FastReport; using FastReport.Utils; using FastReport.Data; using FastReport.Design; using FastReport.Wizards; using System.IO; |
Первым делом создаем процедуру регистрации источника данных для отчета:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
private void RegisterData(Report report) { // cteate any DataSet DataSet dataSet = new DataSet(); dataSet.ReadXml(Path.Combine(appPath, "nwind.xml")); // register data source in the report report.RegisterData(dataSet, "NorthWind"); // Loop through the tables. Override aliases have necessary tables. Activate visibility of the tables foreach (DataSourceBase dsItem in report.Dictionary.DataSources) { if (dsItem.Name == "Employees") { dsItem.Enabled = true; dsItem.Alias = "Mitarbeiter"; dsItem.Columns.FindByName("EmployeeID").Alias = "Identifier"; dsItem.Columns.FindByName("LastName").Alias = "Nachname"; dsItem.Columns.FindByName("FirstName").Alias = "Vorname"; dsItem.Columns.FindByName("Title").Alias = "City"; dsItem.Columns.FindByName("TitleOfCourtesy").Alias = "Titel"; dsItem.Columns.FindByName("BirthDate").Alias = "Geburtsdatum"; dsItem.Columns.FindByName("HireDate").Alias = "Datum der Beschäftigung"; dsItem.Columns.FindByName("Address").Alias = "Anschrift"; dsItem.Columns.FindByName("City").Alias = "Stadt"; dsItem.Columns.FindByName("Region").Alias = "Bereich"; dsItem.Columns.FindByName("PostalCode").Alias = "Index"; dsItem.Columns.FindByName("Country").Alias = "Land"; dsItem.Columns.FindByName("HomePhone").Alias = "Haustelefon"; dsItem.Columns.FindByName("Extension").Alias = "Area Code"; dsItem.Columns.FindByName("Photo").Alias = "Photographie"; dsItem.Columns.FindByName("Notes").Alias = "Hinweise"; dsItem.Columns.FindByName("ReportsTo").Alias = "Vorlage"; } } // set report parameters report.SetParameterValue("Die Testparameter 1", "Der Parameter 1 vor dem Aufruf des Berichts"); report.SetParameterValue("Parameter 2", "\"Der Parameter 2 Standard\""); } |
Как вы заметили, мы создали DataSet, затем загрузили в него базу данных XML и зарегистрировали источник данных в отчете. В цикле по таблицам в источнике находим нужную – Employees. Включаем ее (Enabled = true). Это нужно, чтобы таблица появилась в окне данных в дизайнере. Теперь каждому полю таблицы назначаем алиас – название на немецком языке.
Обрабатываем событие загрузки дизайнера:
1 2 3 4 5 6 7 8 9 10 |
private string appPath; private void Designer_Load(object sender, EventArgs e) { appPath = Path.GetDirectoryName(Application.ExecutablePath); // load the German local for designer Res.LoadLocale(Path.Combine(appPath, "German.frl")); // intercept the load event of designer for further overriding the event handlers Config.DesignerSettings.DesignerLoaded += DesignerSettings_DesignerLoaded; } |
В ресурсах дизайнера устанавливаем язык локализации – в нашем случае немецкий.
Затем назначаем событию DesignerLoaded наш собственный обработчик, который мы напишем ниже.
Пишем обработчик для DesignerLoaded:
1 2 3 4 5 6 7 8 9 |
// load event of designer private void DesignerSettings_DesignerLoaded(object sender, EventArgs e) { // intercept action of creating a new report for the registration of our sources and parameters (sender as Designer).cmdNew.CustomAction += new EventHandler(cmdNew_CustomAction); // except cmdNew. Similarly, you can intercept other Designer.cmd * and do anything inside, // for example, load report from database field and save it back } |
Здесь мы назначаем событию выбор пункта меню New свой обработчик. Происходит, так сказать, «перехват» события.
Напишем обработчик для выбора пункта меню New:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
void cmdNew_CustomAction(object sender, EventArgs e) { Designer designer = sender as Designer; // Use blank wizard to create blank report BlankReportWizard wizard = new BlankReportWizard(); //StandardReportWizard wizard = new StandardReportWizard(); // you can use other wizards // run wizard wizard.Run(designer); // register our data and parameters RegisterData(designer.Report); // update data tree designer.SetModified(this, "EditData"); } |
Тут мы используем пустой дизайнер. Создаем экземпляр объекта BlankReportWizard. Как понятно из названия – это пустой отчет. Далее запускаем дизайнер, регистрируем источник данных и обновляем дерево данных в окне данных.
Пора создать обработчики для двух кнопок. Кнопка создания нового отчета:
1 2 3 4 5 6 7 8 9 |
// create new report private void btnNewReport_Click(object sender, EventArgs e) { using (Report report = new Report()) { RegisterData(report); report.Design(); } } |
Здесь создается объект отчета. Для него регистрируются данные и запускается дизайнер.
Кнопка редактирования отчета. В принципе, все то же самое, но добавляется загрузка существующего отчета:
Здесь создается объект отчета. Для него регистрируются данные и запускается дизайнер.
Кнопка редактирования отчета. В принципе, все то же самое, но добавляется загрузка существующего отчета:
1 2 3 4 5 6 7 8 9 10 |
// edit report private void btnLoadReport_Click(object sender, EventArgs e) { using (Report report = new Report()) { report.Load(Path.Combine(appPath, "report.frx")); RegisterData(report); report.Design(); } } |
Не забываем, что в папке с exe-шником должен быть отчет, база и файл локали (German.frl).
Запустим приложение. Нажимаем на вторую кнопку, получаем шаблон отчета. Раскроем источник данных в дереве:
Все поля, как и названия таблицы, показаны на немецком языке благодаря алиасам.
А теперь, создадим новый пустой отчет с помощью меню File->New.
И вновь мы видим наш источник данных с алиасами.
Мы создали источник данных и присвоили алиасы полям таблицы. Теперь мы можем использовать этот источник в данном виде в любом отчете.
Использование алиасов значительно облегчает создание отчетов людям, которые не знакомы с именованием в той или иной базе данных. Вы можете единожды применить алиасы в базе, и избавиться от уймы вопросов разработчиков отчетов.
Ну и на последок сам отчет: