Расширение модулей 1С 8.3. Аннотации Вместо, После, Перед

Возможности расширения модулей

Начиная с версии платформы 1С 8.3.9.1818 появилась прекрасная возможность доработки практически любых модулей конфигурации используя механизм расширений. В статье мы рассмотрим примеры использования аннотаций: Перед, После, Вместо, а также замечательного метода ПродолжитьВызов() и их комбинаций.

В качестве ограничений расширения методов можно выделить:

— запрет на заимствование в расширение глобальных серверных модулей;

— по умолчанию расширенные методы привилегированного общего модуля выполняются в непривилегированном режиме (но это можно настроить в профиле безопасности).

— запрет на создание в расширении привилегированных и глобальных серверных общих модулей;

При расширении модуля объединяется пространство имен расширяемого и расширяющего модуля. Так из расширяющего модуля можно обращаться к переменным и методам расширяемого модуля. А экспортные методы и переменные, созданные в расширяющем модуле, также доступны из других модулей конфигурации и расширения.

В заимствованном в расширение модуле можно:

— создавать собственные переменные, процедуры и функции;

— назначать собственные обработчики на события, которые не обрабатываются в конфигурации;

— перехватывать любой метод расширяемого модуля и вызывать до и/или после него собственные методы.

Механизм аннотаций.

Для перехвата методов основной конфигурации используется механизм аннотаций при помощи элементов встроенного языка – &Перед, &После, &Вместо, — они определяют последовательность исполнения расширяемого и расширяющего методов.

Ниже на примерах рассмотрим каждую аннотацию, а также возможность их комбинаций.

Аннотация &Перед

Исходя из названия, очевидно, что метод, обрамленный данной аннотацией, будет выполняться до того, как будет происходить выполнение расширяемого метода.

Наглядно это можно отразить на приведенной ниже схеме

В качестве примера решим задачу вывода Фото Физического лица на Форму элемента Справочника Сотрудники в конфигурации ЗУП 3.1. Для этого добавим в расширение метод СотрудникиФормы.СотрудникиПриСозданииНаСервере вызываемый в обработчике Формы ПриСозданииНаСервере.

Запустим 1С Предприятие в режиме конфигуратора и перейдем в общий модуль СотрудникиФормы, далее щелкнув правой кнопкой мыши по заголовку процедуры СотрудникиПриСозданииНаСервере откроем выпадающий список – в нем выберем строчку «Добавить в расширение», система спросит тип аннотации – выберем «Вызывать перед»

Далее мы увидим следующее – в расширение добавился общий модуль СотрудникиФормы и создалась процедура Расш1_СотрудникиПриСозданииНаСервере с аннотацией &Перед(«СотрудникиПриСозданииНаСервере»)

Добавим в процедуру код программного вывода изображения на форму:

&Перед("СотрудникиПриСозданииНаСервере")
Процедура Расш1_СотрудникиПриСозданииНаСервере(Форма, Отказ, СтандартнаяОбработка)

    //Выведем фотографию для сотрудника
    //Добавим реквизит формы
    МассивРеквизитов = Новый Массив;
    РеквизитАдресФотографии = Новый РеквизитФормы("АдресФотографии", Новый ОписаниеТипов("Строка"));
    МассивРеквизитов.Добавить(РеквизитАдресФотографии);
    Форма.ИзменитьРеквизиты(МассивРеквизитов);
    Форма.АдресФотографии = КадровыйУчетРасширенный.АдресФотографииФизическогоЛица(Форма.ФизическоеЛицо.Ссылка);

    //Добавление элементов формы
    Если Форма.Элементы.Найти("АдресФотографии") <> Неопределено Тогда
        Возврат;
    КонецЕсли;

    Элементы = Форма.Элементы;

    //Добавим группу
    ГруппаФотография = Элементы.Добавить("ГруппаФотография", Тип("ГруппаФормы"), Элементы.ФИОНомер);
    ГруппаФотография.Вид = ВидГруппыФормы.ОбычнаяГруппа;
    ГруппаФотография.ОтображатьЗаголовок  = Ложь;

    //Добавим поле
    ПолеАдресФотографии = Элементы.Добавить("АдресФотографии", Тип("ПолеФормы"), ГруппаФотография);
    ПолеАдресФотографии.Вид = ВидПоляФормы.ПолеКартинки;
    ПолеАдресФотографии.ПутьКДанным = "АдресФотографии";
    ПолеАдресФотографии.РастягиватьПоВертикали = Ложь;
    ПолеАдресФотографии.РастягиватьПоГоризонтали = Ложь;
    ПолеАдресФотографии.ПоложениеЗаголовка = ПоложениеЗаголовкаЭлементаФормы.Нет;
    ПолеАдресФотографии.Гиперссылка = Ложь;
    ПолеАдресФотографии.ТекстНевыбраннойКартинки = НСтр("ru = 'Картинка не установлена'");
    ПолеАдресФотографии.РазмерКартинки = РазмерКартинки.АвтоРазмер;
    ПолеАдресФотографии.ЦветТекста = ЦветаСтиля.ТекстЗапрещеннойЯчейкиЦвет;
    ПолеАдресФотографии.Высота = 4;
    ПолеАдресФотографии.Ширина = 10;

КонецПроцедуры

Запустим 1С в режиме предприятия и убедимся что фото Физлица выведено на Форме Сотрудника

Аннотация &После

Исходя из названия, очевидно, что метод, обрамленный данной аннотацией, будет выполняться после выполнения расширяемого метода.

Для примера рассмотрим задачу изменения цвета текста в поле ФОТ на Форме элемента Справочника Сотрудники в конфигурации ЗУП 3.1. в зависимости от выведенного значения. Если ФОТ < 30 000 сделаем желтый, если значение в диапазоне от 30 000 до 50 000 зеленый, если больше 50 000 – красный.

Вернемся в режим конфигуратора 1С Предприятия, данные ФОТ заполняются в обработчике Формы элемента Справочника Сотрудники ПриЧтенииНаСервере процедурой общего модуля СотрудникиФормы.СотрудникиПриЧтенииНаСервере. Для того чтобы анализировать уже заполненное значение ФОТ добавим метод СотрудникиФормы.СотрудникиПриЧтенииНаСервере в расширение с аннотацией &После

Так как общий модуль СотрудникиФормы уже был в нашем расширении в него просто добавилась процедура Расш1_ Расш1_СотрудникиПриЧтенииНаСервере с аннотацией &После(«СотрудникиПриЧтенииНаСервере»)

Далее добавим в процедуру код изменяющий цвет текста

&После("СотрудникиПриЧтенииНаСервере")
Процедура Расш1_СотрудникиПриЧтенииНаСервере(Форма, ТекущийОбъект)
    
    // Проверим на существование Элемента Формы
    Если Форма.Элементы.Найти("ТекущийФОТ") = Неопределено Тогда
        Возврат;
    КонецЕсли;

    Если Форма.ТекущийФОТ = 0 Тогда //Не оформляем нулевое значение
        Возврат;
    ИначеЕсли Форма.ТекущийФОТ <= 30000 Тогда
        Форма.Элементы.ТекущийФОТ.ЦветТекста = WebЦвета.Желтый;
    ИначеЕсли Форма.ТекущийФОТ > 50000 Тогда
        Форма.Элементы.ТекущийФОТ.ЦветТекста = WebЦвета.Красный;
    Иначе
        Форма.Элементы.ТекущийФОТ.ЦветТекста = WebЦвета.Зеленый;
    КонецЕсли;

КонецПроцедуры

Запустим 1С в режиме предприятия и убедимся что цвет текста в поле ФОТ стал зеленым

Аннотация &Вместо

Данная аннотация полностью отключает выполнение расширяемого метода и выполняется только метод расширенный

Стоит отметить, что если для процедур основной конфигурации доступны все три аннотации то при добавлении в расширение функции из основной конфигурации доступна только одна аннотация &Вместо

Для примера запустим 1С Предприятие в режиме конфигуратора и добавим используемую выше функцию получения изображения физлица КадровыйУчетРасширенный.АдресФотографииФизическогоЛица в расширение. Платформа 1С создала функцию Расш1_АдресФотографииФизическогоЛица в расширении со следующим содержимым:

Метод ПродолжитьВызов() рассмотрим ниже, а сейчас заменим содержимое функции слегка доработанным типовым кодом, добавив в него условие, что если пользователю не доступна Роль «Расш1_ПросмотрФото» то адрес изображения возвращаться не будет:

&Вместо("АдресФотографииФизическогоЛица")
Функция Расш1_АдресФотографииФизическогоЛица(ФизическоеЛицо)

    //Начало вставки
    Если Не РольДоступна("Расш1_ПросмотрФото") Тогда
        Возврат "";
    КонецЕсли;
    //Конец вставки

    Запрос = Новый Запрос;
    Запрос.УстановитьПараметр("ФизическоеЛицо", ФизическоеЛицо);
    Запрос.Текст =
    "ВЫБРАТЬ РАЗРЕШЕННЫЕ
    |             ФотографииФизическихЛиц.ФизическоеЛицо,
    |             ФотографииФизическихЛиц.Фотография
    |ИЗ    
    |             РегистрСведений.ФотографииФизическихЛиц КАК ФотографииФизическихЛиц
    |ГДЕ
    |             ФотографииФизическихЛиц.ФизическоеЛицо = &ФизическоеЛицо";

    РезультатЗапроса = Запрос.Выполнить();

    Если РезультатЗапроса.Пустой() Тогда
        Возврат "";
    КонецЕсли;
    
    Выборка = РезультатЗапроса.Выбрать();
    Выборка.Следующий();
    
    Возврат ПоместитьВоВременноеХранилище(Выборка.Фотография.Получить(), ФизическоеЛицо.УникальныйИдентификатор());

КонецФункции

Запустим 1С в режиме предприятия и убедимся, что изображение скрыто даже для пользователя с полными правами

Метод ПродолжитьВызов()

Теперь остановимся на методе платформы 1С ПродолжитьВызов(), если добавить его в расширяемую функцию, то можно обрабатывать его результат как бы было в случае использования аннотации &После для процедуры.

Решим сейчас такую задачу – выведем вместо надписи «Картинка не установлена» собственную картинку для тех Сотрудников у которых в базе нет фото. Для этого добавим также в расширении картинку в ветку метаданных  Общие картинки новый элемент Расш1_ПустоеФото с подходящим изображением

Изменим код расширяемой процедуры, чтобы он выглядел следующим образом:

&Вместо("АдресФотографииФизическогоЛица")
Функция Расш1_АдресФотографииФизическогоЛица(ФизическоеЛицо)
    
    // Выполним код типовой функции.
    Результат = ПродолжитьВызов(ФизическоеЛицо);
    
    //Проверим есть ли изображение в базе
    Если Не ЗначениеЗаполнено(Результат) Тогда
        // Если изображения нет вернем картинку-заглушку
        Возврат ПоместитьВоВременноеХранилище(БиблиотекаКартинок.Расш1_ПустоеФото.ПолучитьДвоичныеДанные(), ФизическоеЛицо.УникальныйИдентификатор());
    КонецЕсли;
    
    Возврат Результат;

КонецФункции

Запустим 1С в режиме предприятия и убедимся, что вместо надписи «Картинка не установлена» мы видим добавленную в расширение картинку-заглушку

Если вернуться к предыдущей задаче, где мы возвращали пустое значение картинки, в случае если у пользователя нет нужной роли, код функции можно переписать, также используя метод ПродолжитьВызов()

&Вместо("АдресФотографииФизическогоЛица")
Функция Расш1_АдресФотографииФизическогоЛица(ФизическоеЛицо)
    
    //Начало вставки
    Если Не РольДоступна("Расш1_ПросмотрФото") Тогда
        Возврат "";
    КонецЕсли;
    //Конец вставки

    Результат = ПродолжитьВызов(ФизическоеЛицо);
    
    Возврат Результат

КонецФункции

Метод ПродолжитьВызов() можно также использовать для процедур с аннотацией &Вместо он будет равнозначен совместному использованию &Перед и &После с той лишь разницей что в случае использования метода ПродолжитьВызов() часть процедуры до его вызова и часть после  будут существовать внутри одного контекста, что требуется для решения некоторых задач. Схематически отобразить это можно следующим образом:

Совместное использование &Перед и &После

Использование метода ПродолжитьВызов()

Последовательность выполнения расширенных методов

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

Порядок следования расширений в конфигурации

Порядок обхода аннотаций &Перед и &После

Порядок обхода аннотации &Вместо совместно с методом ПродолжитьВызов() и аннотациями &Перед и &После

Порядок обхода аннотации &Вместо без метода ПродолжитьВызов()

Важно отметить что в данном случае будет выполнятся только код из Расширения 2

В данной статье мы на примерах разобрали, как работает механизм аннотаций при расширении методов начиная с версии платформы 1С 8.3.9.1818. Удачи в программировании. Спасибо.

Comments

So empty here ... leave a comment!

Добавить комментарий

Sidebar