Работа с данными в платформе 1С:Предприятие требует постоянного контроля за целостностью информации. Ситуация, когда критически важный реквизит оказывается пустым, может привести к ошибкам при проведении документов или формировании отчетности. Программисты и администраторы часто сталкиваются с необходимостью верифицировать наличие данных перед выполнением бизнес-логики.
Существует несколько способов выполнить такую проверку, начиная от встроенных функций языка запросов и заканчивая низкоуровневым кодом на встроенном языке. Выбор конкретного метода зависит от того, где происходит анализ: в модуле объекта, в обработке или в запросе к базе данных.
Некорректная проверка может стать причиной падения системы или появления «битых» ссылок в базе. Поэтому важно четко понимать разницу между пустой строкой, значением Null и неопределенным типом данных.
Встроенные функции языка запросов
Самый эффективный способ фильтрации записей с незаполненными полями — использование встроенной функции Заполнено() непосредственно в тексте запроса. Этот метод работает быстрее всего, так как фильтрация происходит на стороне СУБД, и в выборку попадают только нужные объекты.
Функция возвращает истину, если значение не является Null и не является пустой строкой (для строковых типов).
Рассмотрим пример использования в запросе:
ВЫБРАТЬ
Номенклатура.Ссылка,
Номенклатура.Артикул
ИЗ
Справочник.Номенклатура КАК Номенклатура
ГДЕ
Заполнено(Номенклатура.Артикул) = ИСТИНА
Такой подход гарантирует, что вы не получите записи, где поле «Артикул» вообще не заполнено. Однако стоит учитывать, что функция Заполнено чувствительна к типу данных. Если в поле записан пробел, функция вернет ИСТИНА, что иногда является нежелательным поведением.
Используйте функцию Заполнено() в условии ГДЕ запроса для максимальной производительности, вместо выборки всех данных и последующей фильтрации в коде.
Для более строгой проверки, исключающей строки, состоящие только из пробелов, часто используют комбинацию с функцией СтрЗаменить или сравнение с пустой строкой после приведения типов.
Проверка значений во встроенном языке
При написании кода в модулях форм, объектов или общих модулей программисты используют функцию ЗначениеЗаполнено(). Это универсальный инструмент, который корректно обрабатывает большинство типов данных платформы 1С.
Функция возвращает Ложь, если переданное значение равно Неопределено, Null, пустой строке, нулю (для чисел) или пустой дате. В остальных случаях возвращается Истина.
☑️ Алгоритм проверки реквизита в коде
Пример использования в процедуре:
Если ЗначениеЗаполнено(ТекущийДокумент.Контрагент) Тогда
// Выполняем дальнейшие действия
Иначе
Сообщить("Необходимо указать контрагента!");
КонецЕсли;
Однако существуют нюансы. Например, если реквизит имеет тип «Число» и в нем хранится значение 0, функция вернет Ложь. Если ноль является валидным значением для вашей бизнес-логики (например, нулевая цена или количество), такая проверка приведет к ошибке.
В таких случаях необходимо использовать явное сравнение с Неопределено или Null:
Если ТекущийДокумент.Количество <> Неопределено Тогда
// Число может быть любым, включая 0
КонецЕсли;
Также стоит помнить о разнице между Null и Неопределено. В контексте реквизитов объектов базы данных чаще встречается Null, тогда как Неопределено характерно для переменных, которым еще не присвоено значение.
Особенности работы со ссылочными типами
Проверка заполненности ссылочных типов (справочники, документы) имеет свою специфику. Пустая ссылка в 1С — это ссылка на несуществующий объект, но она технически является значением типа «Ссылка».
Функция ЗначениеЗаполнено() для пустой ссылки вернет Ложь. Это удобно для быстрой проверки. Но иногда требуется убедиться, что ссылка указывает именно на существующий объект, даже если он помечен на удаление.
Что такое пустая ссылка?
Пустая ссылка — это специальный объект типа Ссылка, у которого все внутренние идентификаторы равны нулю. Она не указывает ни на одну запись в базе данных.
Для проверки существования объекта по ссылке используется метод Пустая() у самого объекта ссылки или функция Ссылка.Пустая().
Пример кода:
Если Не Выборка.Номенклатура.Пустая() Тогда
// Ссылка указывает на какой-то объект
КонецЕсли;
Важно различать ситуацию, когда реквизит не заполнен (пустая ссылка), и ситуацию, когда объект существует, но помечен на удаление. Для проверки удаления используется свойство ПометкаУдаления.
| Метод проверки | Возвращает ЛОЖЬ если.. | Рекомендуемое использование |
|---|---|---|
ЗначениеЗаполнено() |
Null, Неопределено, "", 0, ПустаяДата, ПустаяСсылка | Универсальная проверка пользовательского ввода |
Ссылка.Пустая() |
Только если ссылка пустая | Проверка наличия связанного объекта |
Заполнено() (в запросе) |
Null, "" (для строк) | Отбор данных в запросах |
При работе со ссылками в циклах всегда проверяйте их на пустоту перед обращением к свойствам объекта, иначе получите ошибку выполнения.
Массовая проверка и обход табличных частей
Часто возникает задача проверить заполненность реквизитов не в одном объекте, а в целом массиве данных, например, в табличной части документа «Реализация товаров и услуг». Перебор строк в цикле может занять значительное время при больших объемах.
Оптимальный подход — использование запроса с группировкой или отбором. Однако если логика сложная и требует пошагового анализа, приходится использовать циклы.
Пример обхода табличной части:
Для Каждого СтрокаТовары Из ДокументОбъект.Товары Цикл
Если Не ЗначениеЗаполнено(СтрокаТовары.Номенклатура) Тогда
СтрокаТовары.Количество = 0;
Продолжить;
КонецЕсли;
// Дальнейшая обработка
КонецЦикла;
При массовой обработке тысяч записей через ВыборкаДетальныеЗаписи или в цикле по таблице значений, критически важно минимизировать количество обращений к базе данных внутри цикла.
⚠️ Внимание: При обходе табличных частей в цикле избегайте выполнения запросов внутри тела цикла. Это приводит к квадратичному росту времени выполнения (N*N запросов).
Если необходимо проверить заполненность реквизита у множества объектов разных видов, лучше выгрузить нужные данные в таблицу значений одним запросом и анализировать уже локальный массив.
Использование ТаблицаЗначений позволяет применять те же методы фильтрации, что и к обычным запросам, включая функцию Заполнено, если вы используете язык запросов для работы с временными таблицами.
Типичные ошибки и логические ловушки
Самая распространенная ошибка — предположение, что все пустые значения равны между собой. В 1С пустая строка "" и значение Null — это разные сущности, хотя визуально они могут выглядеть одинаково в интерфейсе.
Еще одна ловушка связана с типом «Булево». Если реквизит имеет тип Булево и не заполнен (разрешено не заполнять), его значение будет Неопределено. Проверка Если Реквизит = Ложь Тогда в этом случае не сработает так, как ожидает разработчик, так как Неопределено <> Ложь.
Всегда явно проверяйте тип значения перед сравнением, если реквизит может принимать неопределенное значение.
При работе с датами часто забывают про «нулевую дату» (01.01.0001). Функция ЗначениеЗаполнено() считает её пустым значением, что обычно верно, но в редких случаях исторических данных это может быть некорректно.
Также стоит быть осторожным с приведением типов. Попытка сравнить строку с числом без явного приведения может вызвать ошибку или неожиданный результат в старых версиях платформы.
⚠️ Внимание: В конфигурациях с расширенными правами доступа некоторые реквизиты могут быть скрыты от пользователя. Проверка заполненности такого реквизита в клиентском коде может вернуть ложноположительный результат или вызвать ошибку прав доступа.
Оптимизация и производительность проверок
В высоконагруженных системах каждая миллисекунда на счету. Использование тяжелых конструкций для проверки простых условий недопустимо. Например, вызов сложных функций пользователя внутри условия Если в цикле по большому набору данных убьет производительность.
Старайтесь выносить проверки на уровень запроса. База данных (MS SQL, PostgreSQL) оптимизирована для фильтрации миллионов строк лучше, чем виртуальная машина 1С.
Если проверка необходима на клиенте (в форме), используйте события изменения реквизитов (ПриИзменении), чтобы валидировать данные сразу при вводе, а не накапливать ошибки до момента записи.
&НаКлиенте
Процедура АртикулПриИзменении(Элемент)
Если Не ЗначениеЗаполнено(Объект.Артикул) Тогда
// Мгновенная реакция на ошибку
Элемент.ЦветФона = Цвет.Розовый;
Иначе
Элемент.ЦветФона = Цвет.Белый;
КонецЕсли;
КонецПроцедуры
Для серверного кода хорошим тоном является использование транзакций и блокировок при массовой проверке и исправлении данных, чтобы избежать конфликтов блокировок с другими пользователями.
Влияние индексов на скорость проверки
Если вы часто фильтруете данные по условию Заполнено(Реквизит), убедитесь, что для этого поля создан индекс в базе данных (для SQL-серверов). Это ускорит выполнение запросов в разы.
Часто задаваемые вопросы (FAQ)
В чем разница между Null и Неопределено в 1С?
Null — это значение, пришедшее из базы данных, означающее отсутствие значения в поле таблицы. Неопределено — это значение языка 1С, означающее, что переменной ничего не присвоено. В большинстве случаев встроенные функции обрабатывают их схожим образом, но технически это разные типы.
Как проверить, что строка не содержит только пробелы?
Функция ЗначениеЗаполнено() вернет Истина для строки с пробелами. Чтобы проверить наличие реального текста, используйте конструкцию: СтрДлина(СтрЗаменить(Строка, " ", "")) > 0.
Почему ЗначениеЗаполнено возвращает Ложь для числа 0?
По логике платформы, ноль часто считается отсутствием количественного значения. Если 0 является валидным данным (например, температура или баланс), используйте сравнение Реквизит <> Неопределено.
Можно ли использовать Заполнено() в условиях соединения (JOIN)?
Да, функцию Заполнено() можно использовать в условиях ЛЕВОЕ СОЕДИНЕНИЕ.. ПО Заполнено(..), но это может негативно сказаться на плане выполнения запроса в некоторых СУБД. Лучше фильтровать данные в подзапросе перед соединением.
Как проверить заполненность реквизита в консольных запросах?
В консоли запросов (например, в обработке "Консоль запросов") синтаксис идентичен коду конфигурации. Просто введите условие ГДЕ Заполнено(Таблица.Поле) = ИСТИНА в тексте запроса.