logo

[ELMA3] Скрипты в FastReport

Общая информация

В отличие от других генераторов отчетов, скрипт в FastReport содержит только то, что написано вами. В скрипте вы можете:

  • добавлять в главный класс скрипта свои переменные, методы, свойства;
  • создавать обработчики событий объектов отчета;

Вы не можете:

  • добавлять новые классы в скрипт, если это необходимо. Класс может быть добавлен как перед главным классом ReportScript, так и после него.
  • удалять, переименовывать или изменять область видимости главного класса ReportScript;
  • переименовывать пространство имен, в котором находится главный класс.
  • FastReport добавляет в скрипт список переменных, имена которых совпадают с именами объектов отчета. Это делается перед компиляцией скрипта и позволяет вам обращаться к объектам отчета по их имени;

При запуске отчета происходит следующее:

  • в скрипт добавляются выражения, имеющиеся в отчете, в виде функций;
  • выполняется компиляция скрипта, если он не пустой;
  • инициализируются переменные, которые были неявно добавлены в скрипт;
  • обработчики событий, определенные в скрипте, привязываются к объектам отчета;
  • запускается отчет.

Обработчики событий

Скрипт главным образом используется для создания обработчиков событий объектов. Для создания обработчика события выделите нужный объект. В окне Свойства нажмите кнопку, чтобы переключиться на список событий:

Выберите интересующее вас событие и сделайте на нем двойной щелчок мышью. FastReport добавит в код отчета пустой обработчик события:

private void Text2_BeforePrint(object sender, EventArgs e)
{
  
}

Объект Отчет также имеет события. Выбрать этот объект можно следующими способами:

  • выберите Report в окне Дерево отчета;
  • выберите Report в выпадающем списке объектов окна Свойства.

Чтобы удалить обработчик события, выберите событие в окне Свойства, выделите текст имени события и нажмите клавишу Delete:

События

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

Рассмотрим процесс формирования отчета и события, которые при этом генерируются. В качестве примера возьмем простой отчет, содержащий одну страницу, один бэнд – Данные – и два объекта Текст на бэнде:

В начале отчета вызывается событие StartReport объекта Отчет. Перед формированием страницы вызывается событие страницы StartPage. Это событие вызывается один раз для каждой страницы шаблона отчета (не путать со страницами готового отчета!). В нашем случае, сколько бы ни было страниц в готовом отчете, событие вызовется один раз, т.к. шаблон отчета состоит из одной страницы.

Далее начинается печать строк бэнда Данные. Происходит это следующим образом:

  1. Вызывается событие бэнда BeforePrint.
  2. Вызываются события BeforePrint всех объектов, лежащих на бэнде.
  3. Все объекты заполняются данными.
  4. Вызываются события AfterData всех объектов, лежащих на бэнде.
  5. Происходит размещение объектов на бэнде (если среди них есть растягиваемые объекты) и подсчет высоты бэнда и его растягивание (если бэнд растягиваемый).
  6. Вызывается событие бэнда BeforeLayout.
  7. Вызывается событие бэнда AfterLayout.
  8. Если бэнд не помещается на свободном месте страницы, формируется новая страница.
  9. Бэнд и все его объекты выводятся на страницу готового отчета.
  10. Вызывается событие AfterPrint всех объектов бэнда.
  11. Вызывается событие 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 можно вставить в скрипт, перетащив его из окна Данные.

Если запустить отчет, мы увидим следующее: