К статье
Практический материал

Разработка и Конфигурация · 14 мин

Как в 1С сделать реквизит обязательным для заполнения программно

Как программно сделать реквизит обязательным в 1С: проверка заполнения, свойство ПроверкаЗаполнения, обработчик ОбработкаПроверкиЗаполнения, примеры кода и типичные ошибки.

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

Управлять проверкой можно на трёх уровнях: в модуле объекта через обработчик ОбработкаПроверкиЗаполнения, в модуле формы через одноимённый обработчик формы, а также через изменение свойства ПроверкаЗаполнения в коде. Каждый уровень имеет свои ограничения: проверка в модуле объекта срабатывает при любом способе записи (в том числе из обмена и фоновых заданий), а проверка в форме — только при интерактивной работе пользователя.

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

Когда нужна программная проверка, а когда достаточно свойства в конфигураторе

Самый простой способ сделать реквизит обязательным — открыть палитру свойств реквизита в конфигураторе и установить «Проверка заполнения» в значение «Выдавать ошибку». Платформа сама будет блокировать запись объекта с пустым значением и подсвечивать поле в форме. Этого достаточно, если реквизит обязателен всегда и без исключений.

Программная проверка оправдана в трёх ситуациях. Первая — условная обязательность: реквизит нужен только при определённом состоянии объекта (статус, вид операции, заполненность другого поля). Вторая — обязательность табличной части или отдельных её колонок по условию. Третья — разные правила для разных режимов записи: например, при проведении документа контроль строже, чем при простом сохранении.

Маршрут решения

Как выбрать способ

Реквизит обязателен всегда, без условийУстановите Проверка заполнения = Выдавать ошибку в свойствах реквизита, код не нужен
Обязательность зависит от других данных объектаИспользуйте ОбработкаПроверкиЗаполнения в модуле объекта
Контроль нужен только при работе пользователя в конкретной формеРеализуйте проверку в обработчике формы ОбработкаПроверкиЗаполненияНаСервере
Нужно только визуально подсветить поле без блокировки записиУстановите программно свойство ОтметкаНезаполненного у элемента формы

Проверка заполнения в модуле объекта: обработчик ОбработкаПроверкиЗаполнения

Основной инструмент — обработчик события ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты) в модуле объекта справочника, документа или другого прикладного объекта. Он вызывается платформой при записи, когда включена проверка заполнения (при интерактивной записи — всегда, при программной — если вызывается Записать() с проверкой или проведение).

Типовой шаблон проверки выглядит так: если выполняется условие обязательности и реквизит не заполнен — вывести сообщение, привязанное к полю, и установить Отказ = Истина. Привязка сообщения к данным объекта обеспечивает переход к полю по двойному щелчку на сообщении.

Процедура ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты)

Если ВидОперации = Перечисления.ВидыОпераций.Реализация

И Не ЗначениеЗаполнено(Договор) Тогда

ОбщегоНазначения.СообщитьПользователю(

НСтр("ru = 'Поле ""Договор"" не заполнено'"),

ЭтотОбъект,

"Договор",

,

Отказ);

КонецЕсли;

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

Если в конфигурации нет общего модуля ОбщегоНазначения (самописная конфигурация без БСП), используйте объект СообщениеПользователю напрямую: создайте сообщение, заполните Текст, Поле, КлючДанных, установите УстановитьДанные(ЭтотОбъект) и вызовите Сообщить(), после чего присвойте Отказ = Истина.

Массив ПроверяемыеРеквизиты: как платформа решает, что проверять

Платформа заранее формирует массив ПроверяемыеРеквизиты — имена реквизитов, у которых в конфигураторе задана проверка заполнения «Выдавать ошибку». Если вы хотите отключить стандартную проверку для части случаев, удалите имя реквизита из этого массива в своём обработчике. Это безопаснее, чем менять свойство реквизита в метаданных.

Процедура ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты)

// Для внутренних перемещений склад получателя не требуется

Если ВидОперации = Перечисления.ВидыОпераций.ВнутреннееПеремещение Тогда

Индекс = ПроверяемыеРеквизиты.Найти("СкладПолучатель");

Если Индекс <> Неопределено Тогда

ПроверяемыеРеквизиты.Удалить(Индекс);

КонецЕсли;

КонецЕсли;

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

Обратная задача — добавить реквизит в массив, чтобы платформа проверила его стандартным образом — тоже решается через ПроверяемыеРеквизиты.Добавить("ИмяРеквизита"). Такой вариант удобен, когда нужна типовая реакция (сообщение и подсветка) без написания собственного текста ошибки.

Подсветка поля в форме: свойство ОтметкаНезаполненного

Блокировка записи — это одна часть задачи, визуальная индикация — другая. Чтобы поле в управляемой форме было подчёркнуто красным пунктиром (или отмечено иначе в зависимости от настроек), у элемента формы есть свойство ОтметкаНезаполненного с типом «Булево» или «Авто». В режиме «Авто» платформа сама управляет отметкой по результатам проверки заполнения.

Программно управлять отметкой имеет смысл, когда обязательность меняется динамически прямо в открытой форме. Обычно это делают в обработчике ПриИзменении управляющего поля и в ПриОткрытии/ПриСозданииНаСервере для установки начального состояния.

&НаКлиенте

Процедура ВидОперацииПриИзменении(Элемент)

УстановитьОбязательностьДоговора();

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

&НаСервере

Процедура УстановитьОбязательностьДоговора()

ЭтоРеализация = (Объект.ВидОперации =

Перечисления.ВидыОпераций.Реализация);

Элементы.Договор.ОтметкаНезаполненного = ЭтоРеализация;

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

Важно понимать: ОтметкаНезаполненного — только визуальный признак. Само по себе оно не запрещает запись. Блокировку обеспечивает либо свойство «Проверка заполнения» реквизита, либо обработчик ОбработкаПроверкиЗаполнения.

Проверка на уровне формы: ОбработкаПроверкиЗаполненияНаСервере

В модуле управляемой формы доступен обработчик ОбработкаПроверкиЗаполненияНаСервере(Отказ, ПроверяемыеРеквизиты). Он вызывается только при интерактивной записи из этой формы. Уровень формы уместен, когда правило касается конкретного сценария работы пользователя и не должно распространяться на обмены и программную запись.

Типовой приём — проверка реквизитов, которые существуют только как реквизиты формы (например, временные поля, не сохраняемые в объекте). Их невозможно проверить в модуле объекта, потому что в данных объекта их нет. В обработчике формы они доступны напрямую.

&НаСервере

Процедура ОбработкаПроверкиЗаполненияНаСервере(Отказ, ПроверяемыеРеквизиты)

Если ТребуетсяСогласование И Не ЗначениеЗаполнено(Согласующий) Тогда

ОбщегоНазначения.СообщитьПользователю(

НСтр("ru = 'Укажите согласующего сотрудника'"),

,

"Согласующий",

,

Отказ);

КонецЕсли;

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

Обязательные колонки табличной части

Для табличных частей действуют те же принципы, но проверку нужно выполнять в цикле по строкам, а сообщение привязывать к конкретной строке. Путь к данным формируется через точку: Товары[0].Цена — индексация строк в пути идёт с нуля, а в тексте сообщения принято показывать номер строки с единицы.

Для Каждого СтрокаТовары Из Товары Цикл

Если Не ЗначениеЗаполнено(СтрокаТовары.Номенклатура) Тогда

ОбщегоНазначения.СообщитьПользователю(

СтрШаблон(НСтр("ru = 'В строке %1 не указана номенклатура'"),

Товары.Индекс(СтрокаТовары) + 1),

ЭтотОбъект,

"Товары[" + Товары.Индекс(СтрокаТовары) + "].Номенклатура",

,

Отказ);

КонецЕсли;

КонецЦикла;

Если колонка обязательна всегда, проще установить «Проверка заполнения» в свойствах реквизита табличной части — платформа сама сформирует сообщения по всем строкам. Программный цикл нужен только при условной обязательности, например когда цена обязательна лишь для строк с определённым видом номенклатуры.

Порядок внедрения условной обязательности
  1. 1
    Определите условие, при котором реквизит обязателен, и зафиксируйте его в виде логического выражения
  2. 2
    Добавьте в модуль объекта обработчик ОбработкаПроверкиЗаполнения с проверкой условия и заполненности
  3. 3
    При нарушении выведите сообщение с привязкой к полю и установите Отказ = Истина
  4. 4
    В форме добавьте управление свойством ОтметкаНезаполненного для визуальной подсветки
  5. 5
    Протестируйте запись из формы, программную запись и, при наличии, обмен данными

Частые ошибки и ограничения

Самая распространённая ошибка — попытка сделать реквизит обязательным, изменив свойство ПроверкаЗаполнения программно «на лету». У объекта метаданных это свойство доступно только в конфигураторе; изменить его из кода встроенного языка для конкретного экземпляра нельзя. Динамическое поведение достигается только через обработчики проверки и массив ПроверяемыеРеквизиты.

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

Отдельное ограничение касается режима совместимости и тонкого клиента: обращение к серверным общим модулям из клиентского кода требует, чтобы модуль имел соответствующие флаги («Сервер», «Вызов сервера»). Если сообщение формируется на клиенте, используйте объект СообщениеПользователю напрямую — он работает в обоих контекстах.

Типичные ошибки
01
Попытка программно изменить свойство ПроверкаЗаполнения метаданных — оно недоступно для записи из кода, используйте массив ПроверяемыеРеквизиты
02
Контроль только в клиентском обработчике — при обмене и программной записи объекты сохранятся без обязательных данных
03
Сообщение без указания поля и КлючаДанных — пользователь не может перейти к ошибочному полю
04
Установка Отказ = Истина без сообщения — запись блокируется без объяснения причины
05
Проверка в модуле формы для правила, которое должно действовать при обмене — форма при обмене не участвует, контроль не сработает

Как проверить, что контроль работает

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

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

Контрольные точки

Как проверить результат

Запись из формы с пустым реквизитом при выполненном условии
Норма

Запись отклонена, сообщение привязано к полю, поле подсвечено

Тревожный признак

Объект записывается или ошибка появляется без привязки к полю

Запись при невыполненном условии обязательности
Норма

Объект сохраняется без сообщений

Тревожный признак

Контроль срабатывает всегда, условие не учитывается

Программная запись или обмен данными
Норма

Проверка из модуля объекта срабатывает и здесь

Тревожный признак

Контроль работает только из формы

Поведение стандартных проверок других реквизитов
Норма

Остальные обязательные реквизиты проверяются как раньше

Тревожный признак

После удаления элемента из массива пропали чужие проверки

FAQ

Можно ли сделать реквизит обязательным без изменения конфигурации?

Без доработки — только частично. В типовых конфигурациях на БСП есть механизм запрета редактирования и отдельные настраиваемые проверки, но полноценная условная обязательность произвольного реквизита требует расширения конфигурации или доработки модуля объекта. Расширение — предпочтительный путь, так как типовая конфигурация остаётся на поддержке.

Почему проверка не срабатывает при программной записи?

Чаще всего проверка размещена в модуле формы, а не в модуле объекта. Также возможен вызов Записать() в режиме, где проверка заполнения отключена, либо запись через ОбменДанными.Загрузка = Истина, при котором обработчики контроля не выполняются. Перенесите проверку в ОбработкаПроверкиЗаполнения модуля объекта.

Как сделать обязательным реквизит только при проведении документа?

В обработчике ОбработкаПроверкиЗаполнения проверяйте режим записи через параметр или через событие ОбработкаПроведения: можно вынести контроль в начало ОбработкаПроведения и при нарушении устанавливать Отказ = Истина. Тогда простое сохранение документа-черновика останется возможным, а проведение будет заблокировано.

Чем отличается ОтметкаНезаполненного от свойства Проверка заполнения?

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

Как вывести своё сообщение вместо стандартного «Поле не заполнено»?

Удалите имя реквизита из массива ПроверяемыеРеквизиты в обработчике ОбработкаПроверкиЗаполнения, чтобы отключить стандартное сообщение, и выведите собственное через СообщениеПользователю с привязкой к полю и установкой Отказ = Истина. Так вы полностью контролируете текст и условия появления ошибки.

Работает ли этот подход в обычных формах?

Да, обработчик ОбработкаПроверкиЗаполнения в модуле объекта не зависит от типа форм и работает одинаково. Отличия касаются только визуальной части: в обычных формах управление подсветкой полей устроено иначе, и свойство ОтметкаНезаполненного в том виде, как в управляемых формах, недоступно.

Итог

Что важно запомнить

Условную обязательность реквизита реализуют в обработчике ОбработкаПроверкиЗаполнения модуля объекта: проверка условия, сообщение с привязкой к полю, Отказ = Истина. Массив ПроверяемыеРеквизиты позволяет отключать стандартные проверки, а свойство ОтметкаНезаполненного отвечает только за подсветку в форме. Контроль на клиенте недостаточен — дублируйте его на сервере.