Как сделать реквизит обязательным в 1С 8.3: свойство, код и расширение
Содержание
Чтобы сделать реквизит обязательным в 1С 8.3, откройте его свойства в Конфигураторе и в поле «Проверка заполнения» выберите Выдавать ошибку. После обновления конфигурации базы платформа не даст записать справочник или провести документ
с пустым значением и выведет сообщение Поле "Контрагент" не заполнено.
Это самый простой способ, но не единственный. Если поле обязательно только при условии, его проверяют кодом в обработчике ОбработкаПроверкиЗаполнения. Если конфигурация типовая и снимать её с поддержки не хочется, ту же проверку делают в расширении.
Как установить обязательность реквизита в Конфигураторе
Свойство «Проверка заполнения» есть у реквизитов справочников, документов, планов видов характеристик, планов счетов, бизнес-процессов и задач. Оно же есть у реквизитов табличных частей, у измерений, ресурсов и реквизитов регистров сведений.
Пошагово
- Откройте Конфигуратор:
Конфигурация → Открыть конфигурацию. - В дереве метаданных разверните нужный объект, например
Справочники → Номенклатура → Реквизиты. - Дважды щёлкните реквизит — откроется палитра свойств.
- Найдите группу «Использование» и поле «Проверка заполнения».
- Смените значение
Не проверятьнаВыдавать ошибку. - Сохраните изменения и выполните
Конфигурация → Обновить конфигурацию базы данных(F7).
Свойство не меняет структуру хранения данных. Реструктуризации таблиц не будет, обновление проходит быстро. Но для обновления конфигурации базы всё равно нужен монопольный доступ, если вы не используете динамическое обновление.
Стандартные реквизиты
У справочника есть стандартные реквизиты: Код, Наименование, Родитель, Владелец. Их не видно в списке реквизитов в дереве. Чтобы настроить обязательность:
- Откройте окно редактирования объекта (двойной щелчок по справочнику).
- Перейдите на закладку «Данные».
- Нажмите кнопку «Стандартные реквизиты».
- Выберите, например,
Наименованиеи установите «Проверка заполнения» =Выдавать ошибку.
Табличная часть целиком
У самой табличной части тоже есть свойство «Проверка заполнения». Если выставить Выдавать ошибку, документ без единой строки не проведётся. Это удобно для накладных и заказов, где пустая табличная часть — явная ошибка оператора.
Что считается «незаполненным»
Платформа проверяет не «введено ли что-то», а «отличается ли значение от пустого для своего типа». Это важно для числовых полей.
| Тип реквизита | Пустое значение | Что это значит на практике |
|---|---|---|
| Строка | "" | Пробел в начале не спасёт: строка из пробелов тоже считается пустой |
| Число | 0 | Проверка заодно запрещает ноль — удобно для «Количества» |
| Дата | 01.01.0001 | Пустая дата не пройдёт |
| Ссылка | пустая ссылка | Не выбран элемент справочника или документ |
| Составной тип | Неопределено | Тип не выбран вовсе |
Если ноль в числовом поле — допустимое значение, свойство «Проверка заполнения» ему ставить нельзя: пользователь не сможет записать объект со скидкой 0 % или нулевой ценой. Такую обязательность делают кодом.
Когда платформа выполняет проверку
Это главное, что надо знать, прежде чем жаловаться, что «проверка не работает ».
- 📗 Справочники, планы видов характеристик, регистры сведений — проверка при интерактивной записи из формы.
- 📄 Документы — проверка при проведении. Простая запись документа без проведения проверку заполнения не запускает. Черновик с пустым контрагентом сохранится, а провести его не получится.
- 🤖 Запись из кода — метод
Записать()проверку заполнения не вызывает. Обработка загрузки, обмен или регламентное задание запишут объект с пустыми полями.
Если объект создаётся программно и проверка нужна, вызовите её явно:
НовыйЭлемент = Справочники.Контрагенты.СоздатьЭлемент();
НовыйЭлемент.Наименование = ДанныеСтроки.Наименование;
НовыйЭлемент.ИНН = ДанныеСтроки.ИНН;
Если НовыйЭлемент.ПроверитьЗаполнение() Тогда
НовыйЭлемент.Записать();
Иначе
// Сообщения о незаполненных полях уже выведены платформой
КоличествоОшибок = КоличествоОшибок + 1;
КонецЕсли;
Метод ПроверитьЗаполнение() возвращает Истина, если всё заполнено, и сам формирует сообщения пользователю. Он учитывает и свойство в метаданных, и обработчик ОбработкаПроверкиЗаполнения из модуля объекта.
Программная проверка заполнения в модуле объекта
Свойство в метаданных работает «всегда или никогда». На практике чаще нужно условие: «КПП обязателен только для юрлиц», «Склад обязателен, если в документе есть товары». Для этого есть обработчик события в модуле объекта.
Как устроен обработчик ОбработкаПроверкиЗаполнения
Сигнатура такая:
Процедура ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты)
ПроверяемыеРеквизиты— массив имён реквизитов, которые платформа проверит после обработчика. В него уже попали все реквизиты со свойствомВыдавать ошибку.Отказ— если установитьИстина, запись или проведение прервутся.
Отсюда два приёма: добавить реквизит в массив (сделать обязательным по условию) или удалить его оттуда (снять обязательность по условию).
Пример: КПП обязателен только для юрлица
В модуле объекта справочника «Контрагенты»:
Процедура ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты)
Если ЮрФизЛицо = Перечисления.ЮрФизЛицо.ЮрЛицо Тогда
ПроверяемыеРеквизиты.Добавить("КПП");
КонецЕсли;
КонецПроцедуры
Сообщение о пустом КПП платформа сформирует сама, в том же виде, что и для свойства в метаданных. Имена перечисления и реквизитов здесь условные — в вашей конфигурации подставьте свои.
Пример: снять обязательность по условию
Допустим, «Склад» в документе отмечен как Выдавать ошибку, но для услуг он не нужен:
Процедура ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты)
Если Товары.Количество() = 0 Тогда
Индекс = ПроверяемыеРеквизиты.Найти("Склад");
Если Индекс <> Неопределено Тогда
ПроверяемыеРеквизиты.Удалить(Индекс);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Метод Найти() возвращает Неопределено, если элемента нет. Вызов Удалить(Неопределено) упадёт с ошибкой. Поэтому проверка индекса обязательна.
Реквизиты табличной части
Для колонки табличной части в массив добавляют имя через точку: ПроверяемыеРеквизиты.Добавить("Товары.Цена"). Платформа проверит каждую строку и укажет в сообщении номер строки.
Своё сообщение вместо стандартного
Если стандартный текст не подходит, проверку делают вручную и выводят собственное сообщение с привязкой к полю:
Процедура ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты)
Если ДатаОплаты < Дата Тогда
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Дата оплаты не может быть раньше даты документа";
Сообщение.Поле = "ДатаОплаты";
Сообщение.УстановитьДанные(ЭтотОбъект);
Сообщение.Сообщить();
Отказ = Истина;
КонецЕсли;
КонецПроцедуры
УстановитьДанные(ЭтотОбъект) и Поле нужны, чтобы при клике по сообщению курсор встал в нужное поле формы. В конфигурациях на БСП то же самое короче делает ОбщегоНазначения.СообщитьПользователю(Текст, ЭтотОбъект, "ДатаОплаты", , Отказ).
Проверка на уровне формы
Есть данные, которых нет в объекте: реквизиты формы, флажки диалога, поля обработки. Для них — свои механизмы.
Реквизиты формы
У реквизита управляемой формы есть то же свойство «Проверка заполнения». Оно срабатывает, когда вызывается проверка формы: при записи основного реквизита или явным вызовом ПроверитьЗаполнение() в модуле формы.
Типичный сценарий — форма обработки с кнопкой «Выполнить»:
&НаКлиенте
Процедура Выполнить(Команда)
Если Не ПроверитьЗаполнение() Тогда
Возврат;
КонецЕсли;
ВыполнитьНаСервере();
КонецПроцедуры
Если у реквизитов формы «Период» и «Организация» стоит Выдавать ошибку, при пустых значениях кнопка просто выведет сообщения и не запустит обработку.
Обработчик в модуле формы
В модуле формы есть парный обработчик ОбработкаПроверкиЗаполненияНаСервере(Отказ, ПроверяемыеРеквизиты). Он работает с реквизитами формы. Имена реквизитов объекта в нём указывают через основной реквизит: "Объект.Склад".
Правило выбора простое: если проверка касается данных объекта — пишите её в модуле объекта. Тогда она сработает и при записи из формы, и при программном вызове ПроверитьЗаполнение(). Проверку в форме оставьте для того, что живёт только в форме.
Красное подчёркивание
Свойство элемента формы АвтоОтметкаНезаполненного подчёркивает пустое поле красной пунктирной линией. Оно включено по умолчанию, когда у реквизита стоит проверка заполнения.
Подчёркивание — только подсказка, оно ничего не запрещает. Если включить его у поля без проверки заполнения, пользователь увидит «обязательное» поле, которое на деле можно оставить пустым. Для условной обязательности подсветку меняют кодом через свойство элемента ОтметкаНезаполненного, например в обработчике ПриИзменении поля-условия.
Какой способ выбрать: сравнение
| Способ | Когда подходит | Ограничения и риски |
|---|---|---|
| Свойство «Проверка заполнения» в метаданных | Поле нужно всегда, ноль и пустая строка недопустимы | В типовой конфигурации требует снять объект с поддержки |
ОбработкаПроверкиЗаполнения в модуле объекта | Обязательность по условию, своя логика, своё сообщение | Тот же вопрос с поддержкой; код надо сопровождать |
| Проверка в модуле формы | Реквизиты формы, параметры обработок и отчётов | Не сработает при записи объекта из кода |
| Расширение конфигурации | Типовая конфигурация на поддержке | Нужно следить за совместимостью после обновлений |
Проверка в ПередЗаписью с Отказ = Истина | Надо запретить запись даже из кода и обменов | Ломает загрузку, если не учесть ОбменДанными.Загрузка |
Последняя строка — на случай, когда обязательность нужна жёсткая, на любой записи. ОбработкаПроверкиЗаполнения при Записать() не вызывается, а ПередЗаписью вызывается. Но при загрузке данных обменом в коде принято сразу выходить из обработчика, если ОбменДанными.Загрузка = Истина. Иначе обмен встанет на первом же неполном объекте.
Обязательный реквизит через расширение типовой конфигурации
В типовых БП 3.0, ЗУП 3.1, УТ 11 правка основной конфигурации означает снятие объекта с поддержки. Каждое следующее обновление придётся сравнивать и объединять вручную. Расширение решает задачу без этого.
Пошагово
- В Конфигураторе:
Конфигурация → Расширения конфигурации, кнопка «Добавить». - Задайте имя и префикс, например
Доработкиидр_. Назначение — «Адаптация». - Откройте конфигурацию расширения. Найдите в основной конфигурации нужный объект, щёлкните правой кнопкой и выберите «Добавить в расширение».
- В расширении откройте модуль объекта заимствованного объекта.
- Добавьте обработчик события
ОбработкаПроверкиЗаполненияс аннотацией&После:
&После("ОбработкаПроверкиЗаполнения")
Процедура др_ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты)
Если ЗначениеЗаполнено(Контрагент) И Не ЗначениеЗаполнено(ДоговорКонтрагента) Тогда
ПроверяемыеРеквизиты.Добавить("ДоговорКонтрагента");
КонецЕсли;
КонецПроцедуры
- Сохраните расширение и обновите конфигурацию базы данных — это отдельный шаг после загрузки или правки расширения.
Аннотация &После используется, когда в типовом модуле обработчик уже есть: ваш код выполнится после типового и увидит уже собранный массив. Если у объекта в типовой конфигурации такого обработчика нет, создайте обычный обработчик события в модуле объекта расширения, без аннотации.
Имена Контрагент и ДоговорКонтрагента в примере условные. Посмотрите точные имена реквизитов в дереве метаданных заимствованного объекта.
Если доработку надо применить к десятку объектов
Писать одинаковый обработчик в каждом документе неудобно. Альтернатива — подписка на событие (Общие → Подписки на события) с событием ОбработкаПроверкиЗаполнения и списком источников. Обработчик подписки размещают в общем серверном модуле, а параметры у него те же плюс первый — Источник, сам проверяемый объект.
Частые ошибки и как их устранить
Если ничего не помогло
- Поставьте точку останова в
ОбработкаПроверкиЗаполненияи запустите отладку (Отладка → Начать отладку). Посмотрите содержимое массиваПроверяемыеРеквизитына входе и на выходе. - Проверьте, нет ли в конфигурации второго места, которое удаляет ваш реквизит из массива: поиск по строке
ПроверяемыеРеквизитычерезПравка → Глобальный поиск(Ctrl+Shift+F). - Для расширения убедитесь, что оно активно и применено к этой базе: в пользовательском режиме откройте
Все функции → Стандартные → Управление расширениями конфигурацииили в типовых — раздел администрирования «Расширения». - Если в базе несколько расширений, проверьте порядок их применения: обработчик другого расширения может выполниться после вашего и изменить массив.