Документация по разработке bpm’online
PDF

Как создать макрос для пользовательского отчета в Word

Glossary Item Box

Общие сведения

Настроить печатную форму можно используя стандартные инструменты BPMonline MS Word Report Designer. Настройка печатных форм MS Word подробно описана в статье "Настройка печатных форм MS Word".

Для реализации особых задач по настройке печатных форм необходимо использовать макросы. Базовые макросы описаны в статье "Базовые макросы в печатных формах MS Word". Макрос для настройки печатной формы представляет собой класс, реализующий интерфейс IExpressionConverter (см. схему ExpressionConverter пакета NUI).

Чтобы вызвать пользовательский макрос из шаблона печатной формы, он должен быть отмечен атрибутом ExpressionConverterAttribute с указанием имени макроса. Например:

[ExpressionConverterAttribute("CurrentUser")]

В классе должен быть реализован метод интерфейса Evaluate(object value, string arguments = ""). Метод принимает в качестве аргумента значение поля из шаблона печатной формы и возвращает значение типа string, которое будет подставлено на место этого поля в готовой печатной форме.

Алгоритм создания пользовательского макроса для печатной формы:

  1. Создайте печатную форму и добавьте в список колонок печатной формы колонку [Id], которая будет являться входящим параметром для макроса.
  2. В пользовательский пакет добавьте модуль исходного кода, в котором опишите класс-наследник интерфейса IExpressionConverter. Класс необходимо отметить атрибутом ExpressionConverterAttribute с именем макроса, а также реализовать в нем метод Evaluate(object value, string arguments = "").
  3. В шаблоне печатной формы к колонке [Id] добавьте тег с именем макроса в формате [#MacrosName#].
  4. Опубликуйте модуль исходного кода и загрузите в печатную форму обновленный шаблон печатной формы.

Описание примера

Создать для страницы редактирования раздела [Контрагенты] печатную форму [Справка по контрагенту], которая будет содержать общие поля [Название], [Тип] и [Основной контакт], а также поле [Дополнительная информация], в котором для контрагентов типа [Клиент] будет отображаться годовой оборот, а для контрагентов типа [Партнер] — количество сотрудников. Кроме того, форма должна содержать информацию о дате ее формирования и имени сотрудника, который ее сформировал.

Исходный код

Пакет с реализацией примера можно скачать по ссылке.

Алгоритм реализации примера

1. Создать печатную форму [Справка по контрагенту] ([Account Summary]) для страницы редактирования раздела [Контрагенты] ([Accounts])

В список колонок добавьте[Id], [Название] ([Name]), [Тип] ([Type]), [Основной контакт] ([Primary contact]) (рис. 1).

Рис. 1. — Список колонок печатной формы

Уже на этапе настройки колонок к ним можно добавить необходимый макрос. Для этого перейдите в поле [Выбранные колонки] и выберите нужную колонку. Затем нажмите на кнопку редактирования колонки и в открывшемся окне редактирования колонки добавьте макрос (рис. 2).

Рис. 2. — Добавление макроса к колонке

Подробно создание печатной формы описано в статье Настройка печатных форм MS Word.

2. Выгрузить шаблон печатной формы и разместить на нем поля необходимым образом

После добавления полей шаблон может выглядеть как на рисунке 3. Подробно редактирование шаблона печатной формы описано в статье Настройка шаблона печатной формы MS Word.

Рис. 3. — Размещение полей в шаблоне

3. В пользовательском пакете добавить модули исходного кода, реализующие макросы

3.1 Макрос получения дополнительной информации в зависимости от типа контрагента

Добавьте схему типа исходный код (см. Создание схемы [Исходный код]) со следующими свойствами:

  • [Название] ([Name]) — "UsrAccountInfoByTypeConverter";
  • [Заголовок] ([Title]) — "AccountInfoByTypeConverter".

В схему добавьте локализуемые строки, свойства которых представлены в таблице 1.

Табл. 1. — Свойства локализуемых строк

Название (Name) Значение (Value)
PartnerAdditional "Количество сотрудников {0} чел." ("Number of employees {0} persons")
CustomerAdditional "Годовой оборот {0}" ("Annual turnover {0}")

В исходном коде схемы создайте класс макроса для получения дополнительной информации в зависимости от типа контрагента:

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 AccountInfoByTypeConverter : IExpressionConverter
    {
        private UserConnection _userConnection;
        private string _customerAdditional;
        private string _partnerAdditional;
        // Вызов значений локализуемых строк
        private void SetResources() {
            string sourceCodeName = "UsrAccountInfoByTypeConverter";
            _customerAdditional = new LocalizableString(_userConnection.ResourceStorage, sourceCodeName,
                "LocalizableStrings.CustomerAdditional.Value");
            _partnerAdditional =  new LocalizableString(_userConnection.ResourceStorage, sourceCodeName,
                "LocalizableStrings.PartnerAdditional.Value");
        }
        // Реализация метода 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 "Customer":
                            return String.Format(_customerAdditional, entity.GetTypedColumnValue<string>(columnRevenue));
                        case "Partner":
                            return String.Format(_partnerAdditional, entity.GetTypedColumnValue<string>(columnNumber));
                        default:
                            return String.Empty;
                    }
                }
                return String.Empty;
            }
            catch (Exception err)
            {
                throw err;
            }
        }
    }
}

Опубликуйте модуль.

3.2 Макрос получения текущей даты

Добавьте схему типа исходный код (см. Создание схемы [Исходный код]) со следующими свойствами:

  • [Название] ([Name]) — "UsrCurrentDateConverter";
  • [Заголовок] ([Title]) — "CurrentDateConverter".

В исходном коде схемы создайте класс макроса для получения текущей даты:

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 CurrentDateConverter : 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;
            }
        }
    }
}

Опубликуйте модуль.

3.3 Макрос получения текущего пользователя

Добавьте схему типа исходный код (см. Создание схемы [Исходный код]) со следующими свойствами:

  • [Название] ([Name]) — "UsrCurrentUserConverter";
  • [Заголовок] ([Title]) — "CurrentUserConverter".

В исходном коде схемы создайте класс макроса для получения текущего пользователя:

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 CurrentUserConverter : 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. Добавить теги с именами макросов к полям шаблона отчета

Выберите в контекстном меню поля шаблона пункт [Изменить поле...] ([Edit Field...]) (рис. 4).

Рис. 4. — Контекстное меню поля шаблона

Добавьте теги с именами макросов к именам полей (рис. 5, 6, 7).

К СВЕДЕНИЮ

Для получения данных о текущей дате и текущем пользователе можно использовать любое поле шаблона, так как макросы-обработчики для этих данных не используют входящих параметров. В примере в обоих случаях использовано поле [Id].

Рис. 5. — Добавление тега AccountInfoByType для получения дополнительной информации о контрагенте

Рис. 6. — Добавление тега CurrentDate для получения текущей даты

Рис. 7. — Добавление тега CurrentUser для получения контакта текущего пользователя

В результате шаблон будет выглядеть как показано на рисунке 8.

Рис. 8. — Шаблон печатной формы

5. Сохранить шаблон и загрузить его в печатную форму

Подробно загрузка шаблона в печатную форму описана в статье Настройка шаблона печатной формы MS Word.

После загрузки шаблона на странице редактирования контрагента в меню кнопки [Печать] ([Print]) появится новая печатная форма [Справка по контрагенту] ([Account summary]) (рис. 9).

Рис. 9. — Новая печатная форма в разделе [Контрагенты]

Информация в форме будет зависеть от типа контрагента (рис. 10, 11).

Рис. 10. — Печатная форма для контрагента типа [Клиент] ([Customer])

Рис. 11. — Печатная форма для контрагента типа [Партнер] ([Partner])

© Terrasoft 2002-2019.

Был ли данный материал полезен?

Как можно улучшить эту статью?