Как дополнить типовую функцию в расширении 1С без снятия конфигурации с поддержки

Программист 1С v8.3 (Управляемые формы) 1С:Документооборот IT и автоматизация бизнеса
← На главную

При внедрении и сопровождении программных продуктов на платформе «1С:Предприятие 8», таких как «1С:Документооборот», разработчики регулярно сталкиваются с необходимостью кастомизации типового функционала. Самым правильным и безопасным способом решения этой задачи является использование механизма расширений конфигурации. Он позволяет вносить изменения в логику системы, сохраняя типовую конфигурацию на полной поддержке поставщика, что существенно облегчает последующие обновления.

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

Выясняем причину: влияние версии платформы и режима совместимости

Если вы открываете модуль управляемой формы в конфигураторе, нажимаете правой кнопкой мыши на имя процедуры или функции и не видите в контекстном меню пункта «Добавить в расширение», в первую очередь необходимо обратить внимание на технические характеристики вашей системы. Давайте проанализируем, как развивался этот механизм в платформе «1С:Предприятие 8»:

  1. Платформа версии 8.3.9 и ниже: В этих версиях механизм аннотаций (таких как &Перед, &После, &Вместо) находился на начальном этапе своего развития. Возможности заимствования логики модулей форм были крайне ограничены. Заимствовать конкретный метод формы напрямую через контекстное меню модуля было невозможно. Разработчикам приходилось переносить форму целиком, что приводило к конфликтам при обновлении типового решения.
  2. Платформа версии 8.3.10: Произошел качественный скачок. Появилась штатная функция добавления конкретного метода в расширение (в том числе с помощью горячих клавиш Alt + Shift + F2). Была реализована полноценная поддержка перехвата процедур и функций управляемых форм.
  3. Платформа версии 8.3.13 и выше: Механизмы работы с заимствованными формами окончательно стабилизировались, устранены многие критические ошибки при работе с контекстом формы в расширениях.

Важный нюанс: даже если на вашем компьютере установлена современная платформа (например, 8.3.13 или 8.3.20), ключевое значение имеет Режим совместимости основной конфигурации и самого расширения. Если в свойствах конфигурации установлен режим совместимости с версией 8.3.9 или ниже, новые механизмы заимствования методов работать не будут. Для использования аннотаций перехвата режим совместимости должен быть поднят минимум до значения 8.3.10.

Инструкция: как правильно добавить метод формы в расширение

Давайте по шагам разберем корректную последовательность действий для расширения логики функции управляемой формы. В качестве примера возьмем типовую функцию ОписаниеПользователяДляКарточки из формы списка справочника АдреснаяКнига конфигурации «1С:Документооборот».

Для начала убедимся, что расширение создано и подготовлено к работе:

  1. Откроем конфигуратор и перейдем в меню Конфигурация — Расширения конфигурации.
  2. Создадим новое расширение (или выберем существующее). Обратите внимание на назначение расширения: для доработки логики лучше выбрать назначение «Адаптация» или «Исправление».
  3. Для созданного расширения в окне его свойств крайне рекомендуется снять флажок «Защита от опасных действий», иначе платформа может блокировать выполнение некоторых процедур при работе пользователей.

Теперь выполним правильное заимствование объектов. Пытаться заимствовать метод «в пустоту» нельзя — сначала нужно перенести в расширение сами объекты метаданных:

  1. В дереве метаданных основной конфигурации найдем справочник АдреснаяКнига.
  2. Нажмем на него правой кнопкой мыши и выберем пункт «Добавить в расширение».
  3. Раскроем структуру заимствованного справочника в расширении, найдем нужную форму (в нашем случае — «Форма списка») и также добавим её в расширение.
  4. Откроем модуль заимствованной формы списка уже из дерева объектов расширения.
  5. Найдем в тексте модуля интересующую нас функцию ОписаниеПользователяДляКарточки. Нажмем на её имя правой кнопкой мыши и выберем пункт «Добавить в расширение» (или воспользуемся комбинацией клавиш Alt + Shift + F2).
  6. Платформа предложит выбрать тип аннотации для перехвата:
    • &Перед (вызовется перед выполнением типового кода);
    • &После (вызовется после выполнения типового кода);
    • &Вместо (типовой код будет полностью замещен вашим кодом, при этом внутри можно вызвать исходный метод через ключевое слово ПродолжитьВызов()).

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


&Вместо("ОписаниеПользователяДляКарточки")
Функция Расш1_ОписаниеПользователяДляКарточки(ПараметрыПользователя)
    
    // Получаем стандартный результат работы функции
    Результат = ПродолжитьВызов(ПараметрыПользователя);
    
    // Здесь мы можем дописать свою логику модификации результата
    Возврат Результат;
    
КонецФункции

Реализация задачи: кастомизация карточки пользователя в «1С:Документооборот»

Давайте рассмотрим практический пример. В «1С:Документооборот» функция ОписаниеПользователяДляКарточки отвечает за формирование красивого HTML-представления с контактной информацией о сотруднике, отображаемой на панели справа при выборе пользователя в адресной книге. Предположим, руководство поставило задачу выводить в эту карточку дополнительные сведения: корпоративный никнейм в Telegram и номер офисного кабинета.

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


&Вместо("ОписаниеПользователяДляКарточки")
Функция Расш1_ОписаниеПользователяДляКарточки(ПараметрыПользователя)
    
    // Шаг 1. Вызываем базовую логику типовой конфигурации
    СтандартныйТекст = ПродолжитьВызов(ПараметрыПользователя);
    
    // Шаг 2. Получаем дополнительные данные, которых нет в стандартном наборе
    // Предположим, они хранятся в дополнительных реквизитах пользователя
    ТелеграмНик = "Не указан";
    НомерКабинета = "Не указан";
    
    СсылкаНаПользователя = ПараметрыПользователя.Пользователь;
    Если ЗначениеЗаполнено(СсылкаНаПользователя) Тогда
        // Здесь может быть запрос или обращение к свойствам
        ТелеграмНик = СсылкаНаПользователя.ДополнительныйРеквизитTelegram;
        НомерКабинета = СсылкаНаПользователя.Кабинет;
    КонецЕсли;
    
    // Шаг 3. Модифицируем HTML-текст карточки, добавляя новые строки
    НовыеДанныеHTML = "<tr><td><b>Telegram:</b></td><td>" + ТелеграмНик + "</td></tr>"
                    + "<tr><td><b>Кабинет:</b></td><td>" + НомерКабинета + "</td></tr>";
                    
    // Внедряем новые строки в таблицу описания перед закрывающим тегом таблицы
    МодифицированныйТекст = СтрЗаменить(СтандартныйТекст, "</table>", НовыеДанныеHTML + "</table>");
    
    Возврат МодифицированныйТекст;
    
КонецФункции

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

Что делать, если инфраструктура вашей компании жестко привязана к старой версии платформы (например, 8.3.9) или в силу организационных ограничений вы не можете изменить режим совместимости конфигурации? В таких условиях использовать аннотации методов управляемой формы напрямую не получится. Однако задачу всё равно можно решить программно. Рассмотрим три альтернативных подхода.

Способ 1. Перехват события обновления данных формы

Как правило, функция генерации описания карточки вызывается при изменении текущей строки в списке пользователей. Это событие обрабатывается процедурой формы ПриАктивизацииСтроки. Мы можем пойти по пути перехвата вызывающего метода:

  1. Заимствуем в расширение событие формы списка ПриАктивизацииСтроки с аннотацией &После.
  2. Внутри нашего обработчика получаем текущие данные строки списка.
  3. Самостоятельно генерируем описание пользователя с учетом кастомных полей.
  4. Принудительно записываем наш результат в реквизит формы, отвечающий за отображение карточки на клиенте, тем самым перезаписывая стандартное значение.

Пример реализации такого подхода:


&После("СписокПриАктивизацииСтроки")
Процедура Расш1_СписокПриАктивизацииСтроки(Элемент)
    
    ТекущиеДанные = Элементы.Список.ТекущиеДанные;
    Если ТекущиеДанные = Неопределено Тогда
        Возврат;
    КонецЕсли;
    
    // Самостоятельно формируем описание и перезаписываем элемент формы
    НовоеОписание = ПолучитьКастомноеОписаниеПользователя(ТекущиеДанные.Пользователь);
    ЭтаФорма.Элементы.ПолеОписаниеКарточки.Документ.body.innerHTML = НовоеОписание;
    
КонецПроцедуры

Способ 2. Программное переопределение обработчиков событий

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

  1. Заимствуем в расширение событие формы ПриСозданииНаСервере с аннотацией &После.
  2. Программно перенаправляем обработчик события элемента на нашу собственную процедуру, описанную в расширении.

Посмотрим на пример программной привязки нового действия:


&После("ПриСозданииНаСервере")
Процедура Расш1_ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    // Переопределяем действие при активизации строки программно
    Элементы.Список.УстановитьДействие("ПриАктивизацииСтроки", "Расш1_МояПроцедураПриАктивизации");
    
КонецПроцедуры

Способ 3. Подписки на события для синхронизации данных

Если вывод информации в карточку пользователя завязан на чтение данных из связанных регистров сведений или справочников, мы можем не менять логику самой формы. Вместо этого можно создать подписку на событие ПриЗаписи для объектов, содержащих контактные данные. При изменении телефона или почты мы можем автоматически перезаписывать эти данные в консолидированные поля карточки пользователя, откуда их без труда считает и выведет стандартная функция ОписаниеПользователяДляКарточки.

Таким образом, даже при серьезных ограничениях платформы разработчик 1С всегда имеет в арсенале несколько альтернативных архитектурных путей для реализации бизнес-требований заказчика без изменения типового кода конфигурации.

← На главную