Как в 1С:УНФ добавить поле «Контактное лицо» в Заказ покупателя и настроить уведомление при пустом значении

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

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

Постановка задачи и анализ требований

Перед нами стоит задача доработки документа ЗаказПокупателя. Нам необходимо:

  1. Добавить новое поле Контактное лицо на форму документа, расположив его строго между полями Покупатель и Договор.
  2. Реализовать автоматическое заполнение этого поля при выборе покупателя (контрагента).
  3. Настроить проверку: если поле не заполнено, система должна вывести сообщение пользователю, но при этом не препятствовать проведению документа.

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

Шаг 1. Добавление реквизита и размещение его на форме

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

Разберем, как правильно расположить поле в интерфейсе. В управляемых формах визуальное расположение элементов определяется деревом элементов формы. Нам нужно найти группу, в которой находятся Контрагент (на форме он обычно называется «Покупатель») и Договор. Перетащим наш новый реквизит из списка данных объекта в дерево элементов и установим его между указанными полями. Порядок в дереве элементов сверху вниз соответствует порядку отображения на форме.

Шаг 2. Реализация автоматического заполнения

Для реализации автозаполнения нам понадобится обработчик события ПриИзменении для поля Покупатель (реквизит Контрагент). Рассмотрим логику: когда пользователь выбирает контрагента, система должна заглянуть в его карточку, найти там «Основное контактное лицо» и подставить его в наше новое поле.

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


&НаКлиенте
Процедура КонтрагентПриИзменении(Элемент)
    // Вызываем серверную функцию для получения основного контакта
    Объект.КонтактноеЛицо = ПолучитьОсновнойКонтактСервер(Объект.Контрагент);
КонецПроцедуры

&НаСервереБезКонтекста
Функция ПолучитьОсновнойКонтактСервер(ВыбранныйКонтрагент)
    Если ВыбранныйКонтрагент.Пустая() Тогда
        Возврат Справочники.КонтактныеЛица.ПустаяСсылка();
    КонецЕсли;
    // В УНФ у справочника Контрагенты обычно есть реквизит ОсновноеКонтактноеЛицо
    Возврат ВыбранныйКонтрагент.ОсновноеКонтактноеЛицо;
КонецФункции

Шаг 3. Уведомление пользователя без блокировки проведения

Теперь разберем самый важный момент: как выдать сообщение, но позволить документу провестись. Проанализируем стандартные события. Если мы напишем код в модуле объекта в процедуре ОбработкаПроверкиЗаполнения, то установка параметра Отказ = Истина заблокирует запись. Это нам не подходит.

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

Посмотрим на пример реализации с использованием объекта СообщениеПользователю. Этот метод предпочтительнее, чем ПоказатьПредупреждение, так как он позволяет «привязать» сообщение к конкретному полю на форме, что очень удобно для пользователя.


&НаКлиенте
Процедура ПослеЗаписи(ПараметрыЗаписи)
    // Проверяем, заполнено ли поле
    Если Объект.КонтактноеЛицо.Пустая() Тогда
        // Формируем сообщение, которое не блокирует работу
        Сообщение = Новый СообщениеПользователю;
        Сообщение.Текст = "Внимание: В документе не указано контактное лицо покупателя!";
        Сообщение.Поле = "Объект.КонтактноеЛицо"; // Привязка к полю на форме
        Сообщение.Сообщить();
    КонецЕсли;
КонецПроцедуры

Типичные ошибки при написании кода

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

Также важно помнить о директивах компиляции. В управляемом приложении мы четко разделяем код на тот, что выполняется на компьютере пользователя (&НаКлиенте), и тот, что работает на сервере (&НаСервере). Например, методы вывода предупреждений и оповещений (ПоказатьОповещениеПользователя, ПоказатьПредупреждение) работают только на клиенте.

Альтернативный метод: Оповещение в углу экрана

Если мы хотим сделать уведомление еще менее навязчивым, рассмотрим использование метода ПоказатьОповещениеПользователя. Оно выводит всплывающее окошко в нижнем углу экрана, которое исчезает само через несколько секунд. Проанализируем пример кода:


&НаКлиенте
Процедура ПослеЗаписи(ПараметрыЗаписи)
    Если Объект.КонтактноеЛицо.Пустая() Тогда
        ТекстОповещения = "Рекомендуется заполнить контактное лицо для связи с клиентом.";
        ПоказатьОповещениеПользователя("Поле не заполнено", , ТекстОповещения);
    КонецЕсли;
КонецПроцедуры

Подводя итог, отметим, что для корректного решения данной задачи в 1С:УНФ необходимо сочетать знание типовых реквизитов конфигурации (использование ОсновноеКонтактноеЛицо) с пониманием жизненного цикла формы документа. Использование события ПослеЗаписи в сочетании с СообщениеПользователю является наиболее профессиональным подходом, так как это не нарушает бизнес-процесс (документ проводится), но при этом обеспечивает качественную обратную связь с пользователем.

← На главную