Копирование бэндов отчета в другой со всем содержимым

31.03.2021

Иногда возникает необходимость использовать части одного отчета в другом. В простых случаях для этого можно использовать наследование отчетов.

Например, ситуация, когда во всех отчетах есть общие элементы (логотип компании, подпись и т.д.). Тогда эти объекты можно вынести в родительский отчет и при создании дочерних отчетов они будут скопированы автоматически. Таким образом отпадет необходимость копировать каждый раз вручную, что значительно упростит и ускорит создание новых отчетов. Кроме того, если что-то изменить в родительском отчете, то эти изменения также будут отражены во всех дочерних.

Однако у наследования отчетов есть ряд ограничений. Бывают ситуации, когда у отчета был один “родитель” и возникла необходимость сделать родительским совершенно другой отчет. Может показаться, что достаточно изменить свойство BaseReport, но, к сожалению, это не сработает.

Тем не менее такую задачу можно решить необычным способом, подменив из кода бэнды одного отчета бэндами другого.
Допустим, есть базовый отчет (base.frx) его бэнды нужно скопировать с заменой в дочерний отчет (child.frx). Заменить нужно бэнды PageHeader, PageFooter и DataBand с именем "Data1". Далее в примерах кода предполагается, что оба отчета находятся в корневой папке диска C.

Для начала нужно загрузить оба отчета:

Report base = new Report();
base.Load(@"C:\base.frx");
Report child = new Report();
child.Load(@"C:\child.frx");

Следующим шагом необходимо получить страницы из обоих отчетов. Важно при этом знать имена страниц. В следующем примере предполагается, что имя страниц в обоих отчетах "Page1":

ReportPage basePage = base.FindObject("Page1") as ReportPage;
ReportPage childPage = child.FindObject("Page1") as ReportPage;

Если имена страниц неизвестны, то можно получить их по индексу. Например, далее получаем доступ к первым страницам обоих отчетов:

ReportPage basePage = baseReport.Pages[0] as ReportPage;
ReportPage childPage = childReport.Pages[0] as ReportPage;

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

Теперь можно подменить PageHeader и PageFooter. Здесь все просто:

childPage.PageHeader = basePage.PageHeader;
childPage.PageFooter = basePage.PageFooter;

Этими строками копируются два бэнда со всеми свойствами и настройками. Кроме того, дублируются все расположенные на них объекты и не теряются свойства.

Далее заменяем DataBand с именем "Data1":

DataBand baseBand = basePage.FindObject("Data1") as DataBand;
DataBand childBand = childPage.FindObject("Data1") as DataBand;
// необходимо получить индекс Data1 в дочернем отчете
int childBandIndex = childPage.Bands.IndexOf(childBand);
// теперь его можно удалить
childPage.Bands.Remove(childBand);
// и вставить на его место бэнд из базового отчета
childPage.Bands.Insert(bandIndex, baseBand);

В итоге скопирован бэнд со всеми свойствами и дочерними объектами. А также перенесена привязка к источнику данных, за которую отвечает свойство DataSource. Без этой привязки бэнд не будет работать корректно и выводить данные из базы.

Осталось только скопировать источники данных. Это делается следующим фрагментом кода:

for (int i = 0; i < baseReport.Dictionary.DataSources.Count; i++)
{
 childReport.Dictionary.DataSources.Add(baseReport.Dictionary.DataSources[i]);
}

Таким образом, были скопированы все источники данных. Если в этом нет необходимости, то можно клонировать только нужные.

Вот и всё. Пара десятков строк кода позволили скопировать бэнды и объекты из одного отчета в другой. Если на бэндах много объектов, то дублировать их с помощью дизайнера довольно долго и рутинно, а создавать заново - ещё дольше.

Конечно, если в базовом отчете были только скопированные в данном примере бэнды, то эту задачу можно выполнить еще проще - банальным копипастом файла отчета. А если серьезно, то описанным способом можно скопировать один или несколько бэндов из множества, когда все они в новом отчете не нужны. Или вообще, можно взять заголовок страницы из одного отчета, бэнд с данными из другого и подвал страницы из третьего.

20 ноября 2024

Локализация и смена языков в FastReport VCL

FastReport VCL поддерживает 40 языков для локализации интерфейса и позволяет изменять язык на лету через меню или код, без перекомпиляции.
1 ноября 2024

Новые возможности редактора отчетов FastReport VCL

Рассматриваем новые возможности редактора отчетов: выносные линии, подсветка пересекающихся объектов, обновлённые деревья отчетов и данных.
30 октября 2024

Использование стилей при создании отчетов в FastReport VCL

В статье подробно рассматривается одна из новых возможностей FastReport VCL – применение стилей и страниц стилей.