При разработке в 1С мы часто сталкиваемся с необходимостью поиска элементов в справочниках по их наименованию или другим реквизитам. Однако, после выполнения поиска, критически важно правильно проверить, был ли найден требуемый элемент, или же операция поиска не дала результатов. Нередко возникает путаница относительно того, какое значение возвращается в случае ненахождения элемента: Неопределено или что-то другое. Давайте рассмотрим эту ситуацию подробнее, чтобы избежать ошибок и писать надежный код.
Исходная проблема, с которой мы столкнулись, заключается в следующем: разработчик ожидает, что метод Справочники.ИмяСправочника.НайтиПоНаименованию() вернет Неопределено, если элемент не найден. Однако, вместо этого он получает "пустое значение" и условие НайденныйЭлемент = Неопределено не срабатывает. Мы проанализируем, почему так происходит, и какие существуют корректные способы проверки.
Мы выясним, как работает метод НайтиПоНаименованию() в системе 1С:Предприятие 8.*. Согласно документации, этот метод предназначен для поиска элемента справочника по его наименованию (в процессе также может быть полезен отчет по дублям элементов справочников). И здесь кроется ключевое различие, вызывающее путаницу:
Неопределено будет возвращено только в очень специфическом случае: если для справочника наименование не задано (то есть, его длина равна нулю) и поиск выполняется по полному соответствию. Этот сценарий встречается значительно реже и обычно не является основной причиной ненайденного элемента.Таким образом, в большинстве практических случаев, когда мы ищем элемент по наименованию и его нет, мы получаем не Неопределено, а пустую ссылку. Пустая ссылка — это типизированное значение, которое указывает "в никуда", но при этом является существующим значением данного типа ссылки (например, СправочникСсылка.НаправленияДеятельности).
Теперь, когда мы понимаем, что НайтиПоНаименованию() возвращает пустую ссылку, мы можем рассмотреть правильные подходы к проверке результата.
Самый прямой способ — это сравнить полученную ссылку с пустой ссылкой того же типа справочника. Для этого мы можем использовать статический метод ПустаяСсылка() нужного справочника или метод .Пустая() у самой полученной ссылки.
Рассмотрим пример кода:
НайденныйЭлемент = Справочники.НаправленияДеятельности.НайтиПоНаименованию(Назначение);
// Вариант 1: Сравнение с ПустаяСсылка()
Если НайденныйЭлемент = Справочники.НаправленияДеятельности.ПустаяСсылка() Тогда
// Элемент не найден, выполняем необходимые действия
Сообщить("Элемент с наименованием '" + Назначение + "' не найден.");
Иначе
// Элемент найден
Сообщить("Элемент найден: " + НайденныйЭлемент);
КонецЕсли;
// Вариант 2: Использование метода .Пустая() для ссылки
Если НайденныйЭлемент.Пустая() Тогда
// Элемент не найден
Сообщить("Элемент с наименованием '" + Назначение + "' не найден.");
Иначе
// Элемент найден
Сообщить("Элемент найден: " + НайденныйЭлемент);
КонецЕсли;
Оба эти варианта являются абсолютно корректными и надежными для проверки наличия элемента после поиска по наименованию. Они явно указывают на тип данных, с которым мы работаем, и исключают двусмысленность.
Функция ЗначениеЗаполнено() является одним из наиболее универсальных и часто используемых инструментов в 1С для проверки заполненности значений. Мы проанализируем её поведение и преимущества.
ЗначениеЗаполнено() возвращает Ложь в следующих случаях:
Неопределено.Null.Справочники.ИмяСправочника.ПустаяСсылка()).0.Дата('00010101') (первое января первого года).Важно отметить: В отличие от ошибочного предположения, которое иногда возникает, вызов ЗначениеЗаполнено(Неопределено) не приводит к ошибке. Он корректно возвращает Ложь. Мы можем проверить это следующим образом:
Сообщить("Проверка Неопределено: " + Строка(ЗначениеЗаполнено(Неопределено))); // Выведет "Проверка Неопределено: Нет"
Таким образом, ЗначениеЗаполнено() является отличным выбором для универсальной проверки, так как она покрывает как случай с пустой ссылкой, так и редкий случай с Неопределено, а также другие "пустые" состояния для различных типов данных.
Пример использования ЗначениеЗаполнено() для проверки найденного элемента:
НайденныйЭлемент = Справочники.НаправленияДеятельности.НайтиПоНаименованию(Назначение);
Если Не ЗначениеЗаполнено(НайденныйЭлемент) Тогда
// Элемент не найден (это может быть пустая ссылка или Неопределено)
Сообщить("Элемент с наименованием '" + Назначение + "' не найден.");
Иначе
// Элемент найден
Сообщить("Элемент найден: " + НайденныйЭлемент);
КонецЕсли;
Этот способ часто считается более элегантным и универсальным, поскольку позволяет избежать комбинации нескольких проверок (например, Ссылка <> Неопределено И Не Ссылка.Пустая()).
Чтобы глубже понимать логику проверки, мы разберем различия между ключевыми "пустыми" значениями в 1С:
СправочникСсылка.НаправленияДеятельности.ПустаяСсылка(). Пустая ссылка является значением по умолчанию для переменных ссылочных типов.
Перем МояПеременная; и не присвоим ей значение, она будет Неопределено.
NULL не является аналогом Неопределено в контексте языка 1С.
Понимание этих различий критически важно для корректной обработки данных и избегания ошибок в коде.
Помимо НайтиПоНаименованию(), в 1С существуют и другие полезные методы для поиска элементов справочника, которые мы также можем использовать в зависимости от задачи:
НайтиПоКоду(Код): Ищет элемент справочника по его коду. Поведение аналогично НайтиПоНаименованию() — если элемент не найден, возвращается пустая ссылка.
НайденныйЭлемент = Справочники.МойСправочник.НайтиПоКоду("000000001");
Если ЗначениеЗаполнено(НайденныйЭлемент) Тогда
// ...
КонецЕсли;
НайтиПоРеквизиту(ИмяРеквизита, ЗначениеРеквизита): Позволяет найти элемент по значению любого реквизита справочника. Это очень гибкий метод, когда поиск требуется не по коду или наименованию.
НайденныйЭлемент = Справочники.Контрагенты.НайтиПоРеквизиту("ИНН", "7701234567");
Если Не НайденныйЭлемент.Пустая() Тогда
// ...
КонецЕсли;
Для проверки наличия предопределенных элементов (которые создаются на этапе конфигурирования и всегда существуют в базе) мы можем обращаться к ним напрямую по имени (например, Справочники.Валюты.Рубль). Однако, если существует вероятность, что предопределенный элемент может быть удален или переименован (что крайне нежелательно, но возможно), более надежным способом является использование запросов к базе данных, которые позволяют эффективно фильтровать и получать данные, а также обеспечивают стабильность даже при возможных нарушениях целостности.
Для обеспечения надежности и читаемости нашего кода, мы рекомендуем следующие лучшие практики при работе с поиском элементов справочников:
НайтиПоНаименованию(), НайтиПоКоду(), НайтиПоРеквизиту().
ЗначениеЗаполнено() для проверки: Функция ЗначениеЗаполнено() является универсальным и надежным способом проверки результата поиска, так как она корректно обрабатывает как пустые ссылки, так и Неопределено, а также другие "пустые" значения. Это делает код более лаконичным и устойчивым.
НайденныйОбъект = Справочники.МойСправочник.НайтиПоНаименованию("ИскомоеНаименование");
Если Не ЗначениеЗаполнено(НайденныйОбъект) Тогда
Сообщить("Элемент не найден!");
Возврат;
КонецЕсли;
// Дальнейшая работа с найденным объектом
Запрос будет значительно более производительным и гибким решением, чем множественные вызовы методов поиска.
Следуя этим рекомендациям, мы сможем эффективно и надежно проверять наличие элементов в справочниках 1С, делая наш код более robustным и производительным.