Как сделать реквизит обязательным в 1С 8.3: свойство, код и расширение

· 10 мин

Содержание

Чтобы сделать реквизит обязательным в 1С 8.3, откройте его свойства в Конфигураторе и в поле «Проверка заполнения» выберите Выдавать ошибку. После обновления конфигурации базы платформа не даст записать справочник или провести документ с пустым значением и выведет сообщение Поле "Контрагент" не заполнено.

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

Как установить обязательность реквизита в Конфигураторе

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

Пошагово

  1. Откройте Конфигуратор: Конфигурация → Открыть конфигурацию.
  2. В дереве метаданных разверните нужный объект, например Справочники → Номенклатура → Реквизиты.
  3. Дважды щёлкните реквизит — откроется палитра свойств.
  4. Найдите группу «Использование» и поле «Проверка заполнения».
  5. Смените значение Не проверять на Выдавать ошибку.
  6. Сохраните изменения и выполните Конфигурация → Обновить конфигурацию базы данных (F7).

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

Стандартные реквизиты

У справочника есть стандартные реквизиты: Код, Наименование, Родитель, Владелец. Их не видно в списке реквизитов в дереве. Чтобы настроить обязательность:

  1. Откройте окно редактирования объекта (двойной щелчок по справочнику).
  2. Перейдите на закладку «Данные».
  3. Нажмите кнопку «Стандартные реквизиты».
  4. Выберите, например, Наименование и установите «Проверка заполнения» = Выдавать ошибку.

Табличная часть целиком

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

Что считается «незаполненным»

Платформа проверяет не «введено ли что-то», а «отличается ли значение от пустого для своего типа». Это важно для числовых полей.

Тип реквизитаПустое значениеЧто это значит на практике
Строка""Пробел в начале не спасёт: строка из пробелов тоже считается пустой
Число0Проверка заодно запрещает ноль — удобно для «Количества»
Дата01.01.0001Пустая дата не пройдёт
Ссылкапустая ссылкаНе выбран элемент справочника или документ
Составной типНеопределеноТип не выбран вовсе

Если ноль в числовом поле — допустимое значение, свойство «Проверка заполнения» ему ставить нельзя: пользователь не сможет записать объект со скидкой 0 % или нулевой ценой. Такую обязательность делают кодом.

Когда платформа выполняет проверку

Это главное, что надо знать, прежде чем жаловаться, что «проверка не работает ».

  • 📗 Справочники, планы видов характеристик, регистры сведений — проверка при интерактивной записи из формы.
  • 📄 Документы — проверка при проведении. Простая запись документа без проведения проверку заполнения не запускает. Черновик с пустым контрагентом сохранится, а провести его не получится.
  • 🤖 Запись из кода — метод Записать() проверку заполнения не вызывает. Обработка загрузки, обмен или регламентное задание запишут объект с пустыми полями.

Если объект создаётся программно и проверка нужна, вызовите её явно:

НовыйЭлемент = Справочники.Контрагенты.СоздатьЭлемент();
НовыйЭлемент.Наименование = ДанныеСтроки.Наименование;
НовыйЭлемент.ИНН = ДанныеСтроки.ИНН;

Если НовыйЭлемент.ПроверитьЗаполнение() Тогда
	НовыйЭлемент.Записать();
Иначе
	// Сообщения о незаполненных полях уже выведены платформой
	КоличествоОшибок = КоличествоОшибок + 1;
КонецЕсли;

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

Программная проверка заполнения в модуле объекта

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

Как устроен обработчик ОбработкаПроверкиЗаполнения

Сигнатура такая:

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

Отсюда два приёма: добавить реквизит в массив (сделать обязательным по условию) или удалить его оттуда (снять обязательность по условию).

Пример: КПП обязателен только для юрлица

В модуле объекта справочника «Контрагенты»:

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

	Если ЮрФизЛицо = Перечисления.ЮрФизЛицо.ЮрЛицо Тогда
		ПроверяемыеРеквизиты.Добавить("КПП");
	КонецЕсли;

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

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

Пример: снять обязательность по условию

Допустим, «Склад» в документе отмечен как Выдавать ошибку, но для услуг он не нужен:

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

	Если Товары.Количество() = 0 Тогда
		Индекс = ПроверяемыеРеквизиты.Найти("Склад");
		Если Индекс <> Неопределено Тогда
			ПроверяемыеРеквизиты.Удалить(Индекс);
		КонецЕсли;
	КонецЕсли;

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

Метод Найти() возвращает Неопределено, если элемента нет. Вызов Удалить(Неопределено) упадёт с ошибкой. Поэтому проверка индекса обязательна.

Реквизиты табличной части

Для колонки табличной части в массив добавляют имя через точку: ПроверяемыеРеквизиты.Добавить("Товары.Цена"). Платформа проверит каждую строку и укажет в сообщении номер строки.

Своё сообщение вместо стандартного

Если стандартный текст не подходит, проверку делают вручную и выводят собственное сообщение с привязкой к полю:

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

	Если ДатаОплаты < Дата Тогда
		Сообщение = Новый СообщениеПользователю;
		Сообщение.Текст = "Дата оплаты не может быть раньше даты документа";
		Сообщение.Поле = "ДатаОплаты";
		Сообщение.УстановитьДанные(ЭтотОбъект);
		Сообщение.Сообщить();
		Отказ = Истина;
	КонецЕсли;

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

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

Проверка на уровне формы

Есть данные, которых нет в объекте: реквизиты формы, флажки диалога, поля обработки. Для них — свои механизмы.

Реквизиты формы

У реквизита управляемой формы есть то же свойство «Проверка заполнения». Оно срабатывает, когда вызывается проверка формы: при записи основного реквизита или явным вызовом ПроверитьЗаполнение() в модуле формы.

Типичный сценарий — форма обработки с кнопкой «Выполнить»:

&НаКлиенте
Процедура Выполнить(Команда)

	Если Не ПроверитьЗаполнение() Тогда
		Возврат;
	КонецЕсли;

	ВыполнитьНаСервере();

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

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

Обработчик в модуле формы

В модуле формы есть парный обработчик ОбработкаПроверкиЗаполненияНаСервере(Отказ, ПроверяемыеРеквизиты). Он работает с реквизитами формы. Имена реквизитов объекта в нём указывают через основной реквизит: "Объект.Склад".

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

Красное подчёркивание

Свойство элемента формы АвтоОтметкаНезаполненного подчёркивает пустое поле красной пунктирной линией. Оно включено по умолчанию, когда у реквизита стоит проверка заполнения.

Подчёркивание — только подсказка, оно ничего не запрещает. Если включить его у поля без проверки заполнения, пользователь увидит «обязательное» поле, которое на деле можно оставить пустым. Для условной обязательности подсветку меняют кодом через свойство элемента ОтметкаНезаполненного, например в обработчике ПриИзменении поля-условия.

Какой способ выбрать: сравнение

СпособКогда подходитОграничения и риски
Свойство «Проверка заполнения» в метаданныхПоле нужно всегда, ноль и пустая строка недопустимыВ типовой конфигурации требует снять объект с поддержки
ОбработкаПроверкиЗаполнения в модуле объектаОбязательность по условию, своя логика, своё сообщениеТот же вопрос с поддержкой; код надо сопровождать
Проверка в модуле формыРеквизиты формы, параметры обработок и отчётовНе сработает при записи объекта из кода
Расширение конфигурацииТиповая конфигурация на поддержкеНужно следить за совместимостью после обновлений
Проверка в ПередЗаписью с Отказ = ИстинаНадо запретить запись даже из кода и обменовЛомает загрузку, если не учесть ОбменДанными.Загрузка

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

Какая у вас задача?

Обязательный реквизит через расширение типовой конфигурации

В типовых БП 3.0, ЗУП 3.1, УТ 11 правка основной конфигурации означает снятие объекта с поддержки. Каждое следующее обновление придётся сравнивать и объединять вручную. Расширение решает задачу без этого.

Пошагово

  1. В Конфигураторе: Конфигурация → Расширения конфигурации, кнопка «Добавить».
  2. Задайте имя и префикс, например Доработки и др_. Назначение — «Адаптация».
  3. Откройте конфигурацию расширения. Найдите в основной конфигурации нужный объект, щёлкните правой кнопкой и выберите «Добавить в расширение».
  4. В расширении откройте модуль объекта заимствованного объекта.
  5. Добавьте обработчик события ОбработкаПроверкиЗаполнения с аннотацией &После:
&После("ОбработкаПроверкиЗаполнения")
Процедура др_ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты)

	Если ЗначениеЗаполнено(Контрагент) И Не ЗначениеЗаполнено(ДоговорКонтрагента) Тогда
		ПроверяемыеРеквизиты.Добавить("ДоговорКонтрагента");
	КонецЕсли;

КонецПроцедуры
  1. Сохраните расширение и обновите конфигурацию базы данных — это отдельный шаг после загрузки или правки расширения.

Аннотация &После используется, когда в типовом модуле обработчик уже есть: ваш код выполнится после типового и увидит уже собранный массив. Если у объекта в типовой конфигурации такого обработчика нет, создайте обычный обработчик события в модуле объекта расширения, без аннотации.

Имена Контрагент и ДоговорКонтрагента в примере условные. Посмотрите точные имена реквизитов в дереве метаданных заимствованного объекта.

Если доработку надо применить к десятку объектов

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

Частые ошибки и как их устранить

Диагностика: выберите симптом

Если ничего не помогло

  1. Поставьте точку останова в ОбработкаПроверкиЗаполнения и запустите отладку (Отладка → Начать отладку). Посмотрите содержимое массива ПроверяемыеРеквизиты на входе и на выходе.
  2. Проверьте, нет ли в конфигурации второго места, которое удаляет ваш реквизит из массива: поиск по строке ПроверяемыеРеквизиты через Правка → Глобальный поиск (Ctrl+Shift+F).
  3. Для расширения убедитесь, что оно активно и применено к этой базе: в пользовательском режиме откройте Все функции → Стандартные → Управление расширениями конфигурации или в типовых — раздел администрирования «Расширения».
  4. Если в базе несколько расширений, проверьте порядок их применения: обработчик другого расширения может выполниться после вашего и изменить массив.
Можно ли сделать реквизит обязательным без Конфигуратора?
В пользовательском режиме свойство реквизита конфигурации не меняется. Без программиста можно настроить только обязательность дополнительных реквизитов там, где конфигурация это поддерживает, — в карточке дополнительного реквизита.
Нужна ли реструктуризация базы после смены свойства «Проверка заполнения»?
Нет. Свойство не меняет структуру таблиц, поэтому обновление конфигурации базы проходит быстро, без перестройки данных.
Работает ли обязательность в регистре сведений?
Да, у измерений, ресурсов и реквизитов регистра сведений есть свойство «Проверка заполнения». Для измерений есть ещё свойство «Запрет незаполненных значений»: оно не даёт записать запись с пустым измерением даже из кода.
Почему проверка срабатывает в тонком клиенте, но не в обработке, которая заполняет документы?
Обработка, скорее всего, вызывает Записать() или Записать(РежимЗаписиДокумента.Проведение) из кода. Добавьте явный вызов ПроверитьЗаполнение() перед записью.
Можно ли проверить заполнение булевого реквизита?
Для флажка понятие «не заполнен» лишено смысла: значение всегда Истина или Ложь. Если флажок должен быть включён, проверяйте условие кодом и выводите своё сообщение.