Аннотации Вместо, После, Перед в расширении модулей 1С 8.3
Contents
Возможности расширения модулей 1С
Начиная с версии платформы 1С 8.3.9.1818 появилась прекрасная возможность доработки практически любых модулей конфигурации используя механизм расширений. В статье мы рассмотрим примеры использования аннотаций: Перед, После, Вместо, а также замечательного метода ПродолжитьВызов() и их комбинаций.
В качестве ограничений расширения методов можно выделить:
— запрет на заимствование в расширение глобальных серверных модулей;
— по умолчанию расширенные методы привилегированного общего модуля выполняются в непривилегированном режиме (но это можно настроить в профиле безопасности).
— запрет на создание в расширении привилегированных и глобальных серверных общих модулей;
При расширении модуля объединяется пространство имен расширяемого и расширяющего модуля. Так из расширяющего модуля можно обращаться к переменным и методам расширяемого модуля. А экспортные методы и переменные, созданные в расширяющем модуле, также доступны из других модулей конфигурации и расширения.
В заимствованном в расширение модуле можно:
— создавать собственные переменные, процедуры и функции;
— назначать собственные обработчики на события, которые не обрабатываются в конфигурации;
— перехватывать любой метод расширяемого модуля и вызывать до и/или после него собственные методы.
Механизм аннотаций
Для перехвата методов основной конфигурации используется механизм аннотаций при помощи элементов встроенного языка – &Перед, &После, &Вместо, — они определяют последовательность исполнения расширяемого и расширяющего методов.
Ниже на примерах рассмотрим каждую аннотацию, а также возможность их комбинаций.
1С расширение Перед: Аннотация &Перед
Исходя из названия, очевидно, что метод, обрамленный аннотацией Перед, будет выполняться до того, как будет происходить выполнение расширяемого метода.
Наглядно это можно отразить на приведенной ниже схеме

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

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

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

Добавим в процедуру код программного вывода изображения на форму:
&Перед("СотрудникиПриСозданииНаСервере")
Процедура Расш1_СотрудникиПриСозданииНаСервере(Форма, Отказ, СтандартнаяОбработка)
//Выведем фотографию для сотрудника
//Добавим реквизит формы
МассивРеквизитов = Новый Массив;
РеквизитАдресФотографии = Новый РеквизитФормы("АдресФотографии", Новый ОписаниеТипов("Строка"));
МассивРеквизитов.Добавить(РеквизитАдресФотографии);
Форма.ИзменитьРеквизиты(МассивРеквизитов);
Форма.АдресФотографии = КадровыйУчетРасширенный.АдресФотографииФизическогоЛица(Форма.ФизическоеЛицо.Ссылка);
//Добавление элементов формы
Если Форма.Элементы.Найти("АдресФотографии") <> Неопределено Тогда
Возврат;
КонецЕсли;
Элементы = Форма.Элементы;
//Добавим группу
ГруппаФотография = Элементы.Добавить("ГруппаФотография", Тип("ГруппаФормы"), Элементы.ФИОНомер);
ГруппаФотография.Вид = ВидГруппыФормы.ОбычнаяГруппа;
ГруппаФотография.ОтображатьЗаголовок = Ложь;
//Добавим поле
ПолеАдресФотографии = Элементы.Добавить("АдресФотографии", Тип("ПолеФормы"), ГруппаФотография);
ПолеАдресФотографии.Вид = ВидПоляФормы.ПолеКартинки;
ПолеАдресФотографии.ПутьКДанным = "АдресФотографии";
ПолеАдресФотографии.РастягиватьПоВертикали = Ложь;
ПолеАдресФотографии.РастягиватьПоГоризонтали = Ложь;
ПолеАдресФотографии.ПоложениеЗаголовка = ПоложениеЗаголовкаЭлементаФормы.Нет;
ПолеАдресФотографии.Гиперссылка = Ложь;
ПолеАдресФотографии.ТекстНевыбраннойКартинки = НСтр("ru = 'Картинка не установлена'");
ПолеАдресФотографии.РазмерКартинки = РазмерКартинки.АвтоРазмер;
ПолеАдресФотографии.ЦветТекста = ЦветаСтиля.ТекстЗапрещеннойЯчейкиЦвет;
ПолеАдресФотографии.Высота = 4;
ПолеАдресФотографии.Ширина = 10;
КонецПроцедуры
Запустим 1С в режиме предприятия и убедимся что фото Физлица выведено на Форме Сотрудника

Расширение конфигурации 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_АдресФотографииФизическогоЛица(ФизическоеЛицо)
//Начало вставки
Если Не РольДоступна("Расш1_ПросмотрФото") Тогда
Возврат "";
КонецЕсли;
//Конец вставки
Результат = ПродолжитьВызов(ФизическоеЛицо);
Возврат Результат
КонецФункции
Метод ПродолжитьВызов() можно также использовать для процедур с аннотацией &Вместо он будет равнозначен совместному использованию &Перед и &После с той лишь разницей что в случае использования метода ПродолжитьВызов() часть процедуры до его вызова и часть после будут существовать внутри одного контекста, что требуется для решения некоторых задач. Схематически отобразить это можно следующим образом:
Совместное использование &Перед и &После

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

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

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

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

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

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

Comments
So empty here ... leave a comment!