Как создать макрос для пользовательского отчета в Word
Glossary Item Box
Общие сведения
Настроить печатную форму можно используя стандартные инструменты BPMonline MS Word Report Designer. Настройка печатных форм MS Word подробно описана в статье "Настройка печатных форм MS Word".
Для реализации особых задач по настройке печатных форм необходимо использовать макросы. Базовые макросы описаны в статье "Базовые макросы в печатных формах MS Word". Макрос для настройки печатной формы представляет собой класс, реализующий интерфейс IExpressionConverter.
Для того чтобы вызвать созданный макрос из шаблона печатной формы, необходимо отметить его атрибутом ExpressionConverterAttribute с указанием имени макроса. Например:
[ExpressionConverterAttribute("CurrentUser")]
В классе должен быть реализован метод интерфейса Evaluate(object value, string arguments = ""). Метод принимает в качестве аргумента значение поля из шаблона печатной формы и возвращает значение типа string, которое будет подставлено на место этого поля в готовой печатной форме.
Алгоритм создания пользовательского макроса для печатной формы:
- Создать печатную форму и добавить в список колонок печатной формы колонку [Id], которая будет являться входящим параметром для макроса.
- В пользовательский пакет добавить модуль исходного кода, в котором описать класс-наследник интерфейса IExpressionConverter. Класс необходимо отметить атрибутом ExpressionConverterAttribute с именем макроса, а также реализовать в нем метод Evaluate(object value, string arguments = "").
- В шаблоне печатной формы к колонке [Id] добавить тег с именем макроса в формате [#MacrosName#].
- Опубликовать модуль исходного кода и загрузить в печатную форму обновленный шаблон печатной формы.
Рассмотрим создание макроса для печатной формы на конкретном примере.
Описание кейса
Создать для страницы редактирования раздела [Контрагенты] печатную форму [Справка по контрагенту], которая будет содержать общие поля [Название], [Тип] и [Основной контакт], а также поле [Дополнительная информация], в котором для контрагентов типа [Клиент] будет отображаться годовой оборот, а для контрагентов типа [Партнер] — количество сотрудников. Кроме того, форма должна содержать информацию о дате ее формирования и об имени контакта пользователя, который ее сформировал.
Алгоритм реализации кейса
1. Создать печатную форму [Справка по контрагенту] для страницы редактирования раздела [Контрагенты]
В список колонок добавить [Id], [Название], [Тип], [Основной контакт] (рис. 1).
Рис. 1. — Список колонок печатной формы
Уже на этапе настройки колонок к ним можно добавить необходимый макрос. Для этого нужно перейти в поле [Выбранные колонки] и выбрать нужную колонку. Затем надо нажать на кнопку редактирования колонки и в открывшемся окне редактирования колонки добавить макрос (рис. 2).
Рис. 2. — Добавление макроса к колонке
Подробно создание печатной формы описано в статье Настройка печатных форм MS Word.
2. Выгрузить шаблон печатной формы и разместить на нем поля необходимым образом
3. В пользовательском пакете добавить три модуля исходного кода
Код макроса для получения дополнительной информации в зависимости от типа контрагента:
namespace Terrasoft.Configuration { using System; using System.CodeDom.Compiler; using System.Collections.Generic; using System.Data; using System.Linq; using System.Runtime.Serialization; using System.ServiceModel; using System.ServiceModel.Web; using System.ServiceModel.Activation; using System.Text; using System.Text.RegularExpressions; using System.Web; using Terrasoft.Common; using Terrasoft.Core; using Terrasoft.Core.DB; using Terrasoft.Core.Entities; using Terrasoft.Core.Packages; using Terrasoft.Core.Factories; // Атрибут с именем макроса [AccountInfoByType]. [ExpressionConverterAttribute("AccountInfoByType")] // Класс должен реализовывать интерфейс IExpressionConverter. class AccountInfoByTypeConveter : IExpressionConverter { private UserConnection _userConnection; // Реализация метода Evaluate интерфейса IExpressionConverter. public string Evaluate(object value, string arguments = "") { try { _userConnection = (UserConnection)HttpContext.Current.Session["UserConnection"]; Guid accountId = new Guid(value.ToString()); return getAccountInfo(accountId); } catch (Exception err) { return err.Message; } } // Метод получения дополнительной информации в зависимости от типа контрагента. // В качестве входящего параметра Id контрагента. private string getAccountInfo(Guid accountId) { try { // Создание объекта класса EntitySchemaQuery с корневой схемой [Account]. EntitySchemaQuery esq = new EntitySchemaQuery(_userConnection.EntitySchemaManager, "Account"); // Добавление в схему колонки [Name] из справочного поля [Type]. var columnType = esq.AddColumn("Type.Name").Name; // Добавление в схему колонки [Name] из справочного поля [EmployeesNumber]. var columnNumber = esq.AddColumn("EmployeesNumber.Name").Name; // Добавление в схему колонки [Name] из справочного поля [AnnualRevenue]. var columnRevenue = esq.AddColumn("AnnualRevenue.Name").Name; // Записи фильтруются по Id контрагента. var accountFilter = esq.CreateFilterWithParameters( FilterComparisonType.Equal, "Id", accountId ); esq.Filters.Add(accountFilter); // Получении коллекции сущностей. EntityCollection entities = esq.GetEntityCollection(_userConnection); // Если коллекция содержит элементы, то в зависимости от типа контрагента // метод возвращает соответствующую информацию. if (entities.Count > 0) { Entity entity = entities[0]; var type = entity.GetTypedColumnValue<string>(columnType); switch (type) { case "Клиент": return String.Format("Годовой оборот {0} млн.руб.", entity.GetTypedColumnValue<string>(columnRevenue)); case "Партнер": return String.Format("Количество сотрудников {0} чел.", entity.GetTypedColumnValue<string>(columnNumber)); default: return String.Empty; } } return String.Empty; } catch (Exception err) { throw err; } } } }
Код макроса для получения текущей даты:
namespace Terrasoft.Configuration { using System; using System.CodeDom.Compiler; using System.Collections.Generic; using System.Data; using System.Linq; using System.Runtime.Serialization; using System.ServiceModel; using System.ServiceModel.Web; using System.ServiceModel.Activation; using System.Text; using System.Text.RegularExpressions; using System.Web; using Terrasoft.Common; using Terrasoft.Core; using Terrasoft.Core.DB; using Terrasoft.Core.Entities; using Terrasoft.Core.Packages; using Terrasoft.Core.Factories; // Атрибут с именем макроса [CurrentDate]. [ExpressionConverterAttribute("CurrentDate")] // Класс должен реализовывать интерфейс IExpressionConverter. class CurrentDateConveter : IExpressionConverter { private UserConnection _userConnection; // Реализация метода Evaluate интерфейса IExpressionConverter. public string Evaluate(object value, string arguments = "") { try { _userConnection = (UserConnection)HttpContext.Current.Session["UserConnection"]; // Метод возвращает текущую дату. return _userConnection.CurrentUser.GetCurrentDateTime().Date.ToString("d MMM yyyy"); } catch (Exception err) { return err.Message; } } } }
Код макроса для получения текущего пользователя:
namespace Terrasoft.Configuration { using System; using System.CodeDom.Compiler; using System.Collections.Generic; using System.Data; using System.Linq; using System.Runtime.Serialization; using System.ServiceModel; using System.ServiceModel.Web; using System.ServiceModel.Activation; using System.Text; using System.Text.RegularExpressions; using System.Web; using Terrasoft.Common; using Terrasoft.Core; using Terrasoft.Core.DB; using Terrasoft.Core.Entities; using Terrasoft.Core.Packages; using Terrasoft.Core.Factories; // Атрибут с именем макроса [CurrentUser]. [ExpressionConverterAttribute("CurrentUser")] // Класс должен реализовывать интерфейс IExpressionConverter. class CurrentUserConveter : IExpressionConverter { private UserConnection _userConnection; // Реализация метода Evaluate интерфейса IExpressionConverter. public string Evaluate(object value, string arguments = "") { try { _userConnection = (UserConnection)HttpContext.Current.Session["UserConnection"]; // Метод возвращает контакт текущего пользователя. return _userConnection.CurrentUser.ContactName; } catch (Exception err) { return err.Message; } } } }
4. Добавить теги с именами макросов к полям шаблона отчета
Для этого выбрать в контекстном меню поля шаблона пункт [Изменить поле...] (рис. 3).
Рис. 3. — Контекстное меню поля шаблона
Добавить теги к именам полей (рис. 4, 5, 6).
Рис. 4. — Добавление тега AccountInfoByType для получения дополнительной информации о контрагенте
Рис. 5. — Добавление тега CurrentDate для получения текущей даты
Рис. 6. — Добавление тега CurrentUser для получения контакта текущего пользователя
В результате шаблон будет выглядеть как показано на рисунке 7.
Рис. 7. — Шаблон печатной формы
5. Сохранить шаблон и загрузить его в печатную форму
6. Опубликовать модули исходного кода
После загрузки шаблона и публикации модулей исходного кода на странице редактирования контрагента в списке [Печать] появится новая печатная форма [Справка по контрагенту] (рис. 8).
Рис. 8. — Новая печатная форма в разделе [Контрагенты]
Информация в форме будет зависеть от типа контрагента (рис. 9, 10).
Рис. 9. — Печатная форма для контрагента типа [Клиент]
Рис. 10. — Печатная форма для контрагента типа [Партнер]