[ELMA3] Скрипты в FastReport
Общая информация
В отличие от других генераторов отчетов, скрипт в FastReport содержит только то, что написано вами. В скрипте вы можете:
- добавлять в главный класс скрипта свои переменные, методы, свойства;
- создавать обработчики событий объектов отчета;
Вы не можете:
- добавлять новые классы в скрипт, если это необходимо. Класс может быть добавлен как перед главным классом ReportScript, так и после него.
- удалять, переименовывать или изменять область видимости главного класса ReportScript;
- переименовывать пространство имен, в котором находится главный класс.
- FastReport добавляет в скрипт список переменных, имена которых совпадают с именами объектов отчета. Это делается перед компиляцией скрипта и позволяет вам обращаться к объектам отчета по их имени;
При запуске отчета происходит следующее:
- в скрипт добавляются выражения, имеющиеся в отчете, в виде функций;
- выполняется компиляция скрипта, если он не пустой;
- инициализируются переменные, которые были неявно добавлены в скрипт;
- обработчики событий, определенные в скрипте, привязываются к объектам отчета;
- запускается отчет.
Обработчики событий
Скрипт главным образом используется для создания обработчиков событий объектов. Для создания обработчика события выделите нужный объект. В окне Свойства нажмите кнопку, чтобы переключиться на список событий:
Выберите интересующее вас событие и сделайте на нем двойной щелчок мышью. FastReport добавит в код отчета пустой обработчик события:
private void Text2_BeforePrint(object sender, EventArgs e) { }
Объект Отчет также имеет события. Выбрать этот объект можно следующими способами:
- выберите Report в окне Дерево отчета;
- выберите Report в выпадающем списке объектов окна Свойства.
Чтобы удалить обработчик события, выберите событие в окне Свойства, выделите текст имени события и нажмите клавишу Delete:
События
Чтобы максимально гибко управлять отчетом, каждый объект отчета имеет несколько событий, которым можно назначить обработчик – метод из скрипта. Например, в обработчике, привязанном к бэнду Данные, можно выполнять фильтрацию записей, т.е. скрывать или показывать бэнд в зависимости от каких-либо условий.
Рассмотрим процесс формирования отчета и события, которые при этом генерируются. В качестве примера возьмем простой отчет, содержащий одну страницу, один бэнд – Данные – и два объекта Текст на бэнде:
В начале отчета вызывается событие StartReport объекта Отчет. Перед формированием страницы вызывается событие страницы StartPage. Это событие вызывается один раз для каждой страницы шаблона отчета (не путать со страницами готового отчета!). В нашем случае, сколько бы ни было страниц в готовом отчете, событие вызовется один раз, т.к. шаблон отчета состоит из одной страницы.
Далее начинается печать строк бэнда Данные. Происходит это следующим образом:
- Вызывается событие бэнда BeforePrint.
- Вызываются события BeforePrint всех объектов, лежащих на бэнде.
- Все объекты заполняются данными.
- Вызываются события AfterData всех объектов, лежащих на бэнде.
- Происходит размещение объектов на бэнде (если среди них есть растягиваемые объекты) и подсчет высоты бэнда и его растягивание (если бэнд растягиваемый).
- Вызывается событие бэнда BeforeLayout.
- Вызывается событие бэнда AfterLayout.
- Если бэнд не помещается на свободном месте страницы, формируется новая страница.
- Бэнд и все его объекты выводятся на страницу готового отчета.
- Вызывается событие AfterPrint всех объектов бэнда.
- Вызывается событие AfterPrint бэнда.
Печать строк бэнда происходит до тех пор, пока есть данные в источнике. После этого формирование отчета в нашем случае завершается, и вызываются события FinishPage страницы отчета и наконец – событие FinishReport объекта Отчет.
Таким образом, используя события разных объектов, можно контролировать практически каждый момент формирования отчета. Ключ к правильному использованию событий – полное понимание процесса печати бэндов, изложенного выше в одиннадцати пунктах. Так, большинство действий можно выполнить, используя только событие бэнда BeforePrint: любые изменения, внесенные в объект, будут тут же отображены. Но в этом событии невозможно анализировать, на какой странице будет напечатан бэнд, если он растягиваемый – ведь подсчет высоты бэнда будет выполнен в пункте 6. Это можно сделать с помощью событий AfterLayout в пункте 7 или AfterPrint в пункте 10, но в последнем случае бэнд уже будет напечатан и действия над объектами ничего не дадут. Одним словом, вы должны четко представлять, в какой момент времени вызывается каждое из событий и использовать те, которые соответствуют поставленной задаче.
Обращение к объектам .Net
Из скрипта вы можете обращаться к любым объектам .Net, которые определены в следующих сборках:
System.dll System.Drawing.dll System.Windows.Forms.dll System.Data.dll System.Xml.dll
Кроме того, вы можете использовать любые объекты, определенные в сборках FastReport. Если вам нужно получить доступ к другой сборке, добавьте ее название в список сборок отчета. Это можно сделать в меню Отчет|Свойства…, выбрав в окне элемент Скрипт.
Например, если вы хотите использовать в скрипте функцию, объявленную в вашем приложении, добавьте ссылку на сборку приложения (.exe или .dll) в список сборок отчета. После этого можно обращаться к функции, используя пространство имени (namespace) вашего приложения. Например, в приложении определена следующая функция:
namespace Demo { public static class MyFunctions { public static string Func1() { return "Hello!"; } } }
Обратиться к ней в скрипте можно так:
string hello = Demo.MyFunctions.Func1();
Если добавить в скрипт директиву using Demo, это позволит укоротить форму обращения к функции:
string hello = MyFunctions.Func1();
Обращение к объектам отчета
Для обращения к объектам отчета (например, объекту Текст) используйте имя объекта. Следующий пример вернет высоту объекта Text1:
float height = Text1.Height;
Учтите, что "родными" единицами измерения отчета являются экранные пикселы. Вы должны это помнить при обращении к таким свойствам объектов, как Left, Top, Width, Height. Для перевода пикселов в сантиметры и обратно используйте константы, определенные в классе Units:
float heightInPixels = Text1.Height; float heightInCM = heightInPixels / Units.Centimeters; Text1.Height = Units.Centimeters * 5; // 5см
Обращение к источникам данных
В отличие от выражений FastReport (они рассмотрены в главе "Выражения"), в скрипте нельзя использовать квадратные скобки для обращения к данным отчета. Вместо этого используется метод GetColumnValue объекта Report, возвращающий значение поля:
string productName = (string)Report.GetColumnValue("Products.Name");
Как видно, надо указать имя источника данных и его поля через точку. Имя источника может быть составным в случае, если мы обращаемся к источнику данных, используя связь (relation). Подробнее о связях рассказано в главе "Данные". Например, так можно обратиться к полю связанного источника данных:
string categoryName = (string)Report.GetColumnValue("Products.Categories.CategoryName");
Для облегчения работы используйте окно Данные. Из него можно перетаскивать элементы данных в скрипт, при этом FastReport автоматически создает код для обращения к элементу.
Для обращения к самому источнику данных используйте метод GetDataSource объекта Report:
DataSourceBase ds = Report.GetDataSource("Products");
Справку по свойствам и методам класса DataSourceBase можно получить в справочной системе FastReport.Net Class Reference. Как правило, этот объект используется в скрипте следующим образом:
// получаем ссылку на источник данных DataSourceBase ds = Report.GetDataSource("Products"); // инициализируем его ds.Init(); // перебираем все записи в источнике while (ds.HasMoreRows) { // получаем значение поля для текущей записи источника string productName = (string)Report.GetColumnValue("Products.Name"); // выполняем с ним какие-то действия... // ... // переходим на следующую запись ds.Next(); }
Обращение к системным переменным
Для обращения к системной переменной используйте метод GetVariableValue объекта Report:
DateTime date = (DateTime)Report.GetVariableValue("Date");
Список системных переменных можно увидеть в окне Данные. Из него можно перетаскивать переменные в скрипт, при этом FastReport автоматически создает код для обращения к переменной.
Обращение к итоговым значениям
Для обращения к итоговому значению используйте метод GetTotalValue объекта Report:
float sales = Report.GetTotalValue("TotalSales");
Список итогов можно увидеть в окне Данные. Из него можно перетаскивать итоги в скрипт, при этом FastReport автоматически создает код для обращения к итогу.
Итоговое значение имеет тип FastReport.Variant. Оно может быть напрямую использовано в любых выражениях, потому что тип FastReport.Variant автоматически приводится к любому типу. Например:
float tax = Report.GetTotalValue("TotalSales") * 0.2f;
Обращаться к итоговому значению можно в тот момент, когда оно вычислено. Обычно итог "готов к употреблению" в момент печати бэнда, на котором он располагается в отчете.
Обращение к параметрам отчета
Для обращения к параметру отчета используйте метод GetParameterValue объекта Report:
int myParam = (int)Report.GetParameterValue("MyParameter");
Параметры могут быть вложенными. В этом случае укажите имя родительского параметра и через точку имя дочернего параметра:
Report.GetParameterValue("ParentParameter.ChildParameter")
Параметры имеют определенный тип данных. Он задается в свойстве DataType параметра. Вы должны учитывать это при обращении к параметру. Список параметров можно увидеть в окне Данные. Из него можно перетаскивать параметры в скрипт, при этом FastReport автоматически создает код для обращения к параметру.
Для изменения значения параметра используйте метод SetParameterValue объекта Report:
Report.SetParameterValue("MyParameter", 10);
Пример 1. Изменение внешнего вида объекта
В этом примере мы покажем, как изменить цвет текста у объекта в зависимости от значения, которое печатается в объекте. Мы будем использовать:
- событие BeforePrint;
- обращение к полю БД из скрипта.
Создайте простой отчет следующего вида:
У объекта, который печатает стоимость продукта, создайте обработчик события BeforePrint:
private void Text2_BeforePrint(object sender, EventArgs e) { if (((Decimal)Report.GetColumnValue("Products.UnitPrice")) > 20) Text2.TextColor = Color.Red; }
Чтобы вставить в скрипт значение поля Products.UnitPrice, перетащите его из окна Данные. При этом в скрипт будет вставлена строка:
((Decimal)Report.GetColumnValue("Products.UnitPrice"))
Если запустить отчет, мы увидим, что все продукты, имеющие стоимость > 20, выделены красным цветом:
Пример 2. Вычисление итогов
В этом примере мы покажем, как программным способом вычислить суммарное значение. Мы будем использовать:
- событие BeforePrint бэнда;
- обращение к полю БД из скрипта;
- локальную переменную, значение которой будет печататься в отчете.
Создайте отчет следующего вида:
В скрипте объявите переменную summa и создайте у бэнда обработчик события BeforePrint:
public class ReportScript { private decimal summa; private void Data1_BeforePrint(object sender, EventArgs e) { summa += (Decimal)Report.GetColumnValue("Products.UnitPrice"); } }
Поле таблицы Products.UnitPrice можно вставить в скрипт, перетащив его из окна Данные.
Если запустить отчет, мы увидим следующее: