Мы часто сталкиваемся с ситуацией, когда, казалось бы, все настройки для запрета пустых значений в 1С установлены, но каким-то образом в базе данных все равно появляются записи с незаполненными полями. Это может привести к некорректным отчетам, ошибкам в расчетах и нарушению целостности данных. В этой статье мы подробно разберем, почему так происходит, и как обеспечить надежный контроль заполнения данных.
ПроверкаЗаполнения и ЗапретНезаполненныхЗначенийПрежде всего, давайте выясним, в чем принципиальное отличие между двумя часто путаемыми свойствами, которые отвечают за контроль заполнения в 1С. Понимание этой разницы — ключ к решению нашей проблемы.
ПроверкаЗаполнения (устанавливается в "Выдавать ошибку")
Это свойство предназначено исключительно для интерактивного режима работы с системой, то есть для случаев, когда пользователь вручную вводит данные через формы. Мы включаем его для реквизитов документов, элементов справочников или ресурсов регистров, чтобы система проверяла их заполнение при попытке записи или проведения.
ПроверкаЗаполнения не анализируется и данная проверка не срабатывает.ЗапретНезаполненныхЗначений (устанавливается в "Истина")
Это свойство применяется к измерениям регистров (сведений, накопления, бухгалтерских, расчетных) и является частью бизнес-логики регистра. Оно означает, что записи с незаполненным измерением не имеют смысла в информационной базе.
Таким образом, если незаполненными оказываются измерения регистра, и для них установлено свойство ЗапретНезаполненныхЗначений, но записи все равно появляются, то причина кроется в обходе этой проверки.
ЗапретНезаполненныхЗначений может быть обойден?Когда мы убедились, что свойство ЗапретНезаполненныхЗначений корректно установлено для измерения регистра, но пустые значения все равно проникают, это указывает на то, что стандартные проверки обходятся. Рассмотрим подробнее основную причину такого поведения.
ОбменДанными.Загрузка = Истина
Это наиболее частая причина обхода проверок. В платформе 1С существует глобальный флаг ОбменДанными.Загрузка. Если этот флаг установлен в значение Истина, то большинство проверок, включая ЗапретНезаполненныхЗначений, а также проверки в обработчиках событий ПередЗаписью и подписках на события, отключаются. Этот режим используется для загрузки данных "как есть" из других систем или узлов обмена, предполагая, что данные уже были проверены на источнике.
Записать() или Записать() набора записей был установлен ОбменДанными.Загрузка = Истина, система игнорирует большинство внутренних проверок.ОбменДанными.Загрузка = Истина в модулях объектов, модулях менеджеров, общих модулях, особенно в тех, которые отвечают за загрузку данных, синхронизацию или создание объектов программно.
Если УсловиеЗагрузкиИзОбмена Тогда
ОбменДанными.Загрузка = Истина;
КонецЕсли;
Попытка
НаборЗаписейРегистра = РегистрыСведений.МойРегистр.СоздатьНаборЗаписей();
// ... Заполняем измерения и ресурсы ...
НаборЗаписейРегистра.Записать();
Исключение
// Обработка исключения
КонецПопытки;
Если УсловиеЗагрузкиИзОбмена Тогда
ОбменДанными.Загрузка = Ложь; // Важно сбросить флаг!
КонецЕсли;
ОбменДанными.Загрузка = Истина вызывающая сторона (программист, разработчик) берет на себя полную ответственность за целостность и корректность загружаемых данных. Если вы обнаружили такой код, но не уверены в источнике данных или его проверках, вам следует пересмотреть логику.Мы выяснили, что свойство ЗапретНезаполненныхЗначений применимо только к измерениям регистров. Что же делать, если пустые значения появляются в ресурсах регистров или в обычных реквизитах документов/справочников при программной записи?
Для ресурсов и реквизитов, помимо интерактивной проверки ПроверкаЗаполнения, нам потребуется реализовать собственные механизмы контроля, которые будут работать при программной записи:
Мы можем добавить код проверки в обработчики событий объекта, например, в ПередЗаписью() модуля объекта регистра или документа. Это позволит нам контролировать заполнение ресурсов или реквизитов перед непосредственной записью в базу данных.
// В модуле объекта регистра или документа
Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
Если Не ОбменДанными.Загрузка Тогда // Игнорируем проверки при загрузке данных
Если ЭтоНовый() И ЗначениеЗаполнено(ЭтотОбъект.МойРесурс) = Ложь Тогда
Сообщить("Ресурс 'МойРесурс' должен быть заполнен!");
Отказ = Истина;
КонецЕсли;
// Или для изменения существующих
Если Не ЭтоНовый() Тогда
Если ЗначениеЗаполнено(ЭтотОбъект.МойРесурс) = Ложь Тогда
Сообщить("Ресурс 'МойРесурс' не может быть пустым!");
Отказ = Истина;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Обратите внимание, что здесь мы также проверяем флаг ОбменДанными.Загрузка, чтобы избежать конфликтов при загрузке данных.
Для более централизованного управления проверками, особенно если они затрагивают несколько объектов или имеют сложную логику, мы можем использовать подписки на события. Создадим подписку на событие ПередЗаписью для нужных нам объектов.
Чтобы полностью контролировать заполнение значений и избежать нежелательных пустых полей, мы предлагаем комплексный подход. Разберем его по шагам.
ЗапретНезаполненныхЗначений
Убедимся, что для всех критически важных измерений регистров, которые не должны быть пустыми, свойство ЗапретНезаполненныхЗначений установлено в "Истина". Это базовый уровень защиты.
Как проверить: Откройте конфигуратор, перейдите в ветку "Регистры сведений" или "Регистры накопления" (или другие типы регистров), выберите нужный регистр, откройте его структуру. Для каждого измерения проверьте значение свойства "Запрет незаполненных значений".
ОбменДанными.Загрузка = Истина
Это самый критичный шаг. Мы должны найти все участки кода, где программно устанавливается флаг ОбменДанными.Загрузка = Истина, особенно если они предшествуют записи в регистры, где требуется строгий контроль заполнения.
ОбменДанными.Загрузка = Истина.ОбменДанными.Загрузка = Истина не оправдана, следует удалить или закомментировать эти строки. Если же она необходима, но при этом требуется контроль заполнения, переходим к Шагу 3.Подписки на события — это мощный инструмент для реализации собственной логики проверки, которая будет срабатывать независимо от того, как происходит запись (интерактивно или программно) и даже с учетом флага ОбменДанными.Загрузка (если мы явно это укажем).
ЗапретНезаполненныхЗначений обходится из-за ОбменДанными.Загрузка = Истина, но вам все равно нужна проверка.ОбменДанными.Загрузка:
// В Общем модуле (например, "МоиПроверки")
Процедура ПередЗаписьюРегистраМойРегистр(Источник, Отказ) Экспорт
// Источник в данном случае - это набор записей регистра
// Проверяем, не происходит ли загрузка данных через обмен
Если Не ОбменДанными.Загрузка Тогда
Для Каждого ЗаписьРегистра Из Источник Цикл
// Проверяем заполнение измерения, если стандартный ЗапретНезаполненныхЗначений
// по какой-то причине не сработал или был обойден.
// Хотя для измерений лучше полагаться на встроенный механизм, если он не обойден.
Если ЗначениеЗаполнено(ЗаписьРегистра.МоеИзмерение) = Ложь Тогда
Сообщить("Измерение 'МоеИзмерение' в регистре '" + Источник.Имя + "' не заполнено!");
Отказ = Истина;
Возврат; // Прекращаем проверку и запись
КонецЕсли;
// Проверяем заполнение ресурса, для которого нет ЗапретаНезаполненныхЗначений
Если ЗначениеЗаполнено(ЗаписьРегистра.МойРесурс) = Ложь Тогда
Сообщить("Ресурс 'МойРесурс' в регистре '" + Источник.Имя + "' не заполнен!");
Отказ = Истина;
Возврат; // Прекращаем проверку и запись
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецПроцедуры
ПередЗаписью и подписках на события, следуя стандартам разработки 1С, всегда выполняйте бизнес-логику и проверки после проверки Если Не ОбменДанными.Загрузка Тогда. Это гарантирует, что при загрузке данных через обмен не будет непредвиденных ошибок.Применяя эти методы, мы сможем создать надежную систему контроля заполнения данных, которая не позволит незаполненным значениям проникать в нашу информационную базу, делая ее более чистой и корректной.
← К списку