Как создать макрос для пользовательского отчета в Word
Glossary Item Box
Рекомендуем предварительно ознакомиться с настройкой печатных форм MS Word, подробно описанной в статье Настройка печатных форм MS Word.
В общих случаях настроить печатную форму можно используя стандартные инструменты BPMonline MS Word Report Designer. Для реализации особых задач по настройке печатных форм необходимо использовать макросы. Макрос для настройки печатной формы представляет собой класс, реализующий интерфейс IExpressionConverter.
Для того чтобы вызвать созданный макрос из шаблона печатной формы отметьте его атрибутом ExpressionConverterAttribute с указанием имени макроса, например:
[ExpressionConverterAttribute("CurrentUser")]
В классе должен быть реализован метод интерфейса Evaluate(object value, string arguments = ""). Метод принимает в качестве аргумента значение поля из шаблона печатной формы и возвращает значение типа string, которое будет подставлено на место этого поля в готовой печатной форме.
Алгоритм создания пользовательского макроса для печатной формы:
- Создать печатную форму и добавить в список колонок печатной формы колонку [Id], которая будет являться входящим параметром для макроса.
- В пользовательский пакет добавить модуль исходного кода, в котором описать класс-наследник интерфейса IExpressionConverter. Класс необходимо отметить атрибутом ExpressionConverterAttribute с именем макроса, а также реализовать в нем метод Evaluate(object value, string arguments = "").
- В шаблоне печатной формы к колонке [Id] добавить тег с именем макроса в формате [#MacrosName#].
- Опубликовать модуль исходного кода и загрузить в печатную форму обновленный шаблон печатной формы.
Рассмотрим создание макроса для печатной формы на конкретном примере.
Описание кейса
Создать для страницы редактирования раздела [Контрагенты] печатную форму [Справка по контрагенту], которая будет содержать общие поля [Название], [Тип] и [Основной контакт], а также поле [Дополнительная информация], в котором для контрагентов типа [Клиент] будет отображаться годовой оборот, а для контрагентов типа [Партнер] — количество сотрудников. Кроме того, форма должна содержать информацию о дате ее формирования и об имени контакта пользователя, который ее сформировал.
Алгоритм реализации кейса
1. Создать печатную форму [Справка по контрагенту] для страницы редактирования раздела [Контрагенты]
В список колонок добавить [Id], [Название], [Тип], [Основной контакт] (рис. 1).
Рис. 1. — Список колонок печатной формы
Подробно создание печатной формы описано в статье Настройка печатных форм 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. Добавить теги с именами макросов к полям шаблона отчета
Для этого выбрать в контекстном меню поля шаблона пункт [Изменить поле...] (рис. 2).
Рис. 2. — Контекстное меню поля шаблона
Добавить теги к именам полей (рис. 3, 4, 5).
Рис. 3. — Добавление тега AccountInfoByType для получения дополнительной информации о контрагенте
Рис. 4. — Добавление тега CurrentDate для получения текущей даты
Рис. 5. — Добавление тега CurrentUser для получения контакта текущего пользователя
В результате шаблон будет выглядеть как показано на рисунке 6.
Рис. 6. — Шаблон печатной формы
5. Сохранить шаблон и загрузить его в печатную форму
6. Опубликовать модули исходного кода
После загрузки шаблона и публикации модулей исходного кода на странице редактирования контрагента в списке [Печать] появится новая печатная форма [Справка по контрагенту] (рис. 6).
Рис. 6. — Новая печатная форма в разделе [Контрагенты]
Информация в форме будет зависеть от типа контрагента (рис. 7, 8).
Рис. 7. — Печатная форма для контрагента типа [Клиент]
Рис. 8. — Печатная форма для контрагента типа [Партнер]