Как в 1С:Документооборот 3.0 обработать изменение дополнительного реквизита на форме документа?

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

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

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

Решение 1: Программная обработка через специальный обработчик

Самый правильный и гибкий способ отреагировать на изменение дополнительного реквизита — использовать специальный подключаемый обработчик события, который предусмотрен разработчиками платформы. Этот механизм позволяет "перехватить" событие изменения любого дополнительного реквизита на форме.

Порядок действий:

  1. Создание расширения. Чтобы не изменять основную конфигурацию, все доработки будем выполнять в расширении. Создайте новое расширение и добавьте в него нужный объект, например, справочник ДокументыПредприятия, для которого нужно отслеживать изменения.
  2. Заимствование формы. Добавьте в расширение форму объекта, на которой происходит работа с реквизитами. Чаще всего это ФормаДокумента.
  3. Добавление обработчика в модуль формы. Откройте модуль заимствованной формы и добавьте в него новую клиентскую экспортную процедуру со строго определенным названием: Подключаемый_ПриИзмененииДополнительногоРеквизита.

Эта процедура принимает два параметра:

Посмотрим на пример кода:

Предположим, у нас есть дополнительный реквизит с идентификатором "ТребуетсяКонтрольЮриста" типа "Булево". Нам нужно выводить сообщение, если пользователь установил флажок.


&НаКлиенте
Процедура Подключаемый_ПриИзмененииДополнительногоРеквизита(ИмяРеквизита, Объект)

    // Проверяем, что изменился именно наш реквизит
    Если ИмяРеквизита = "ТребуетсяКонтрольЮриста" Тогда

        // Значение дополнительного реквизита нужно получить из табличной части объекта.
        // Создадим переменную для хранения найденного значения.
        ЗначениеРеквизита = Неопределено;

        // Переберем все строки табличной части "ДополнительныеРеквизиты"
        Для Каждого СтрокаДопРеквизита Из Объект.ДополнительныеРеквизиты Цикл
            // Сравниваем имя свойства (ссылка на ПВХ) с нашим идентификатором
            Если СтрокаДопРеквизита.Свойство.Имя = "ТребуетсяКонтрольЮриста" Тогда
                ЗначениеРеквизита = СтрокаДопРеквизита.Значение;
                Прервать; // Реквизит нашли, выходим из цикла
            КонецЕсли;
        КонецЦикла;

        // Теперь у нас есть актуальное значение, и мы можем выполнить нашу логику
        Если ЗначениеРеквизита = Истина Тогда
            Сообщить("Внимание! Документ направлен на дополнительный контроль юридической службы.");
            // Здесь можно реализовать более сложную логику:
            // - изменить значение другого реквизита;
            // - сделать видимыми или доступными другие элементы формы;
            // - выполнить дополнительные проверки.
        КонецЕсли;

    КонецЕсли;

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

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

Решение 2: Настройка условной обязательности и видимости (без программирования)

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

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

Как это работает:

Откройте карточку дополнительного реквизита (НСИ и администрирование - Настройки НСИ - Доп. реквизиты и сведения). На вкладке "Основное" можно настроить условия для свойств "Видимость", "Доступность" и "Обязательность".

Пример:

Допустим, есть два доп. реквизита для договора: "Тип договора" (со значениями "Поставка", "Аренда", "Услуги") и "Адрес объекта аренды". Реквизит "Адрес объекта аренды" должен быть видимым и обязательным для заполнения только в том случае, если "Тип договора" равен "Аренда".

  1. В настройках реквизита "Адрес объекта аренды" для свойства "Обязательность" выберите вариант "Обязателен с условием".
  2. В конструкторе условия добавьте правило: Дополнительный реквизит "Тип договора" Равно "Аренда".
  3. Аналогичное условие можно задать и для видимости.

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

Решение 3: Альтернатива — создание обычного реквизита через расширение

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

В таких случаях стоит рассмотреть альтернативу — добавить в объект документа (например, Справочник.ДокументыПредприятия) новый, "обычный" реквизит через расширение.

Преимущества такого подхода:

Недостатки:

Этот способ подходит, когда поле является фундаментальной частью документа и его логика не должна меняться пользователями.

Важное техническое уточнение: где хранятся данные

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

Таким образом, для программной работы со значением дополнительного реквизита всегда нужно обращаться к табличной части объекта Объект.ДополнительныеРеквизиты, как и было показано в примере кода выше.

← На главную