Разработка и Конфигурация · 12 мин
Как проверить реквизит на заполнение в 1С
Как проверить реквизит на заполнение в 1С: функция ЗначениеЗаполнено(), проверка заполнения на форме, в запросе и автоматическая проверка. Примеры кода.
Проверка заполнения реквизита — одна из самых частых задач при разработке и доработке конфигураций 1С. Она нужна, чтобы не допустить сохранение документа без контрагента, проведение без склада или формирование отчёта с пустым периодом. Платформа предлагает несколько механизмов: от встроенной функции ЗначениеЗаполнено() до автоматической проверки заполнения на уровне объекта конфигурации.
Выбор способа зависит от контекста: проверка в коде модуля, проверка на форме при записи, контроль в запросе или штатная автоматическая проверка, заданная в свойствах реквизита. Неправильно выбранный метод приводит либо к ложным срабатываниям (например, число 0 считается «не заполненным»), либо к пропуску реально пустых значений.
Ниже разобраны все основные подходы с примерами кода, их ограничения и типичные ошибки. Материал применим к платформе 1С:Предприятие 8.3 и типовым конфигурациям на её основе.
Функция ЗначениеЗаполнено() — базовый способ проверки
Основной инструмент — встроенная функция ЗначениеЗаполнено(Значение). Она возвращает Истина, если значение отличается от «пустого» для своего типа, и Ложь в противном случае. Функция универсальна: работает со строками, числами, датами, ссылками, булевыми значениями и Неопределено.
Типичный пример — проверка реквизита объекта перед записью:
Если Не ЗначениеЗаполнено(Объект.Контрагент) Тогда
Сообщить("Не заполнен контрагент");
Отказ = Истина;
КонецЕсли;
Важно понимать, что функция считает пустыми: пустую строку (в том числе из пробелов — нет, строка из пробелов считается заполненной, это частая ловушка), число 0, дату '00010101', пустую ссылку любого типа, Неопределено и NULL. Ложь (булево) при этом считается заполненным значением — для булевых реквизитов функция бесполезна.
Что считается пустым значением для разных типов
Главный источник ошибок — неверное представление о том, какие значения функция трактует как пустые. Перед написанием проверки стоит свериться с фактическим поведением для конкретного типа реквизита.
| Тип реквизита | Пустое значение | Особенность |
|---|---|---|
| Строка | "" (пустая строка) | Строка из пробелов считается заполненной |
| Число | 0 | Ноль нельзя отличить от «не введено» — учитывайте в логике |
| Дата | 01.01.0001 00:00:00 | — |
| Ссылка | Пустая ссылка типа | Проверяется и через ПустаяСсылка() |
| Булево | Ложь | ЗначениеЗаполнено(Ложь) вернёт Истина — не используйте для булевых полей |
| Неопределено | Неопределено | Возникает у реквизитов составного типа |
Отдельный случай — составной тип реквизита. Если реквизит может хранить и строку, и ссылку, то «пустым» он будет при значении Неопределено либо при пустом значении текущего типа. ЗначениеЗаполнено() корректно обрабатывает оба варианта, поэтому для составных реквизитов это предпочтительный способ.
Альтернативные способы проверки в коде
Кроме универсальной функции, существуют специализированные проверки, которые иногда точнее или читабельнее.
Сравнение с пустой ссылкой
Для ссылочных реквизитов можно использовать метод Пустая() или сравнение с пустой ссылкой конкретного типа:
Если Объект.Склад.Пустая() Тогда
// склад не указан
КонецЕсли;
Если Объект.Контрагент = Справочники.Контрагенты.ПустаяСсылка() Тогда
// контрагент не указан
КонецЕсли;
Такой вариант работает только если тип реквизита точно известен. Для составных реквизитов он ненадёжен: значение может оказаться строкой, и сравнение со ссылкой даст неверный результат.
Проверка строк с обрезкой пробелов
Для строковых реквизитов, где пользователь мог ввести пробелы, применяйте СокрЛП():
Если ПустаяСтрока(Объект.Комментарий) Тогда
// строка пустая или состоит из пробелов
КонецЕсли;
Функция ПустаяСтрока() считает пустой и строку из одних пробелов — в отличие от ЗначениеЗаполнено(). Для текстовых полей, заполняемых вручную, это обычно более корректное поведение.
Автоматическая проверка заполнения в конфигураторе
Если реквизит обязателен всегда, код писать не нужно. В конфигураторе у каждого реквизита объекта (справочника, документа и т.д.) есть свойство «Проверка заполнения» с вариантами: «Не проверять», «Выдавать ошибку», «Выдавать предупреждение».
При установке «Выдавать ошибку» платформа сама откажется записывать объект с пустым реквизитом и покажет пользователю стандартное сообщение с привязкой к полю формы. Это работает и при интерактивной записи, и при программной — если запись выполняется с проверкой заполнения.
Аналогичное свойство есть у реквизитов формы и у колонок табличных частей. Для табличных частей проверка выполняется по каждой строке, что избавляет от ручного перебора в цикле.
- 1Откройте конфигуратор и найдите нужный объект (справочник или документ)
- 2Перейдите на закладку «Данные» и выберите реквизит
- 3В палитре свойств найдите «Проверка заполнения» и установите «Выдавать ошибку»
- 4Обновите конфигурацию базы данных (F7)
- 5Проверьте: попробуйте записать объект с пустым реквизитом — должно появиться сообщение об ошибке
Обработчик ОбработкаПроверкиЗаполнения для сложных условий
Когда обязательность реквизита зависит от других данных (например, договор обязателен только для определённого вида операции), штатного свойства недостаточно. Тогда в модуле объекта переопределяется обработчик ОбработкаПроверкиЗаполнения:
Процедура ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты)
Если ВидОперации = Перечисления.ВидыОпераций.ПоДоговору
И Не ЗначениеЗаполнено(Договор) Тогда
ТекстСообщения = НСтр("ru = 'Не заполнен договор'");
ОбщегоНазначения.СообщитьПользователю(
ТекстСообщения, ЭтотОбъект, "Договор", , Отказ);
КонецЕсли;
КонецПроцедуры
Обратите внимание на массив ПроверяемыеРеквизиты: в него платформа помещает реквизиты, у которых включена автоматическая проверка. Из обработчика можно удалить реквизит из этого массива, если в конкретной ситуации проверять его не нужно — это стандартный приём для условной обязательности.
Третий параметр СообщитьПользователю() — имя реквизита — обеспечивает привязку сообщения к полю формы: пользователь увидит подсветку именно того поля, которое нужно заполнить. Не пренебрегайте этим параметром, иначе сообщение появится без привязки и затруднит поиск проблемы.
В типовых конфигурациях на БСП для вывода сообщений используйте ОбщегоНазначения.СообщитьПользователю(), а не Сообщить(). Это обеспечивает привязку к полям формы, корректную работу в веб-клиенте и единый формат сообщений об ошибках.
Проверка реквизита на форме перед записью
Иногда проверку нужно выполнить до обращения к объекту — например, на управляемой форме перед записью или при нажатии собственной кнопки. Для этого используется обработчик ПередЗаписью формы или явный вызов проверки:
&НаКлиенте
Процедура ПередЗаписью(Отказ, ПараметрыЗаписи)
Если Не ЗначениеЗаполнено(Объект.Ответственный) Тогда
ПоказатьПредупреждение(, "Укажите ответственного");
Отказ = Истина;
КонецЕсли;
КонецПроцедуры
У формы также есть метод ПроверитьЗаполнение(), который программно запускает стандартную проверку заполнения и возвращает Истина, если все проверки пройдены. Это удобно в собственных командах: Если Не ПроверитьЗаполнение() Тогда Возврат; КонецЕсли;.
Учитывайте разницу контекстов: на клиенте недоступны запросы к базе и серверные методы, поэтому сложные проверки (например, уникальность значения) выполняйте на сервере — в обработчике объекта или серверной процедуре формы.
Проверка заполнения в запросе
В запросах проверка на пустоту выполняется иначе — через сравнение с пустым значением или параметром. Для ссылок удобна конструкция ЗНАЧЕНИЕ():
ВЫБРАТЬ
Реализация.Ссылка
ИЗ
Документ.РеализацияТоваровУслуг КАК Реализация
ГДЕ
Реализация.Договор = ЗНАЧЕНИЕ(Справочник.ДоговорыКонтрагентов.ПустаяСсылка)
Для строк — сравнение с пустой строкой, для дат — с ДАТАВРЕМЯ(1,1,1). Универсальный вариант для реквизитов составного типа — проверка через ЕСТЬ NULL не подходит: NULL в запросе возникает при соединениях, а не как признак незаполненности реквизита. Не путайте эти понятия: незаполненный реквизит хранит пустое значение своего типа, а не NULL.
Проверка результата и границы самостоятельной работы
После внедрения проверки протестируйте три сценария: реквизит пуст — проверка срабатывает и блокирует запись; реквизит заполнен штатным значением — запись проходит; реквизит заполнен граничным значением (0 для числа, строка пробелов, пустая дата) — поведение соответствует задуманному. Именно граничные значения выявляют большинство ошибок в логике проверки.
Работайте сначала на копии базы, особенно если меняете модуль объекта документа, который уже используется в учёте. Ошибка в обработчике ОбработкаПроверкиЗаполнения может заблокировать проведение целого типа документов для всех пользователей. Перед изменением типовой конфигурации проверьте, не реализована ли нужная проверка типовыми средствами — доработка может оказаться лишней.
Как проверить результат
Появляется сообщение об ошибке с привязкой к полю, запись отменяется
Объект записывается без предупреждений или сообщение не указывает на поле
Запись и проведение проходят штатно
Проверка срабатывает на заполненном значении
Поведение соответствует бизнес-логике
Ноль отклоняется как «не заполнено» или строка пробелов проходит проверку
Что важно запомнить
В коде используйте ЗначениеЗаполнено(), для строк из пробелов — ПустаяСтроку(), для постоянно обязательных реквизитов — свойство «Проверка заполнения», для условной обязательности — обработчик ОбработкаПроверкиЗаполнения. Помните про особенности чисел и булевых значений и всегда проверяйте граничные случаи на копии базы.
Частые вопросы
Чем ЗначениеЗаполнено() отличается от ПустаяСтрока()?
ЗначениеЗаполнено() универсальна и работает с любым типом, но строку из пробелов считает заполненной. ПустаяСтрока() работает только со строками, зато считает пустой и строку из пробельных символов. Для текстовых полей, вводимых вручную, предпочтительнее ПустаяСтрока().
Почему ЗначениеЗаполнено(Ложь) возвращает Истина?
Для булевого типа «пустого» значения в понимании платформы нет — Ложь является полноценным значением. Поэтому для булевых реквизитов проверка заполнения через эту функцию бессмысленна, проверяйте значение напрямую по логике задачи.
Как сделать реквизит обязательным только при определённом условии?
Оставьте свойство «Проверка заполнения» в значении «Не проверять» и добавьте условную проверку в обработчик ОбработкаПроверкиЗаполнения модуля объекта. Либо, наоборот, включите автоматическую проверку и удаляйте реквизит из массива ПроверяемыеРеквизиты, когда он не обязателен.
Проверка заполнения сработает при программной записи объекта?
Да, если запись выполняется методом Записать() с проверкой заполнения (по умолчанию проверка выполняется). Если запись идёт в режиме загрузки (ОбменДанными.Загрузка = Истина), проверки заполнения не выполняются — это используется при обменах и обработках переноса данных.
Как проверить заполнение колонки табличной части?
У колонки табличной части в конфигураторе есть то же свойство «Проверка заполнения» — платформа проверит каждую строку автоматически. Для условной проверки переберите строки в ОбработкаПроверкиЗаполнения и выводите сообщения с указанием номера строки.
Как проверить, что реквизит не заполнен, в запросе для составного типа?
Одного сравнения недостаточно — нужно перечислить пустые значения всех возможных типов через ИЛИ, либо проверять на Неопределено непосредственно в коде после выборки. На практике проще ограничить состав типов реквизита на этапе проектирования.