К статье
Практический материал

Разработка и Конфигурация · 11 мин

Как проверить, существует ли объект в 1С

Способы проверить существование объекта в 1С: Пустая(), НайтиПоКоду, НайтиПоНаименованию, запросы, ПолучитьОбъект. Примеры кода, ошибки и рекомендации.

Проверка существования объекта — одна из самых частых задач при разработке и доработке конфигураций 1С. Она нужна перед записью данных, при обмене, при поиске дублей и при обработке ссылок, полученных извне. Ошибка на этом этапе приводит либо к созданию дублей, либо к падению кода с исключением.

В 1С нет единого универсального метода «объект существует». Вместо этого используется набор приёмов: проверка ссылки на пустоту, поиск по ключевым полям, запросы к базе и обработка результата ПолучитьОбъект(). Выбор зависит от того, что у вас есть на входе — ссылка, код, наименование или набор реквизитов.

Ниже разобраны основные способы с примерами кода на встроенном языке, их ограничения и типичные ошибки. Материал применим к управляемым и обычным формам, к справочникам, документам и другим ссылочным типам.

Что значит «объект существует» в терминах 1С

В 1С различают объект и ссылку. Ссылка — это уникальный идентификатор записи в базе, объект — данные, загруженные в память для чтения или изменения. Проверка существования почти всегда сводится к проверке ссылки: есть ли в базе запись с таким идентификатором.

Важный нюанс: переменная может содержать ссылку, которая выглядит заполненной, но запись в базе уже удалена. Такие «битые ссылки» — частая ситуация после обменов и удаления данных. Поэтому проверка «ссылка не пустая» и проверка «объект существует в базе» — разные операции.

Проверка ссылки на пустоту

Самая простая проверка — метод Пустая() у ссылки. Он отвечает на вопрос «заполнена ли ссылка», но не «есть ли объект в базе»:

Если НоменклатураСсылка.Пустая() Тогда

Сообщить("Ссылка не заполнена");

КонецЕсли;

Для Неопределено и пустых значений в составных типах используйте комбинированную проверку:

Если Ссылка = Неопределено 

Или Не ЗначениеЗаполнено(Ссылка) Тогда

Возврат;

КонецЕсли;

Функция ЗначениеЗаполнено() универсальна: она корректно обрабатывает Неопределено, пустые ссылки любых типов, пустые строки и нулевые даты. Её удобно использовать на входе процедур и функций.

Поиск объекта по коду и наименованию

Для справочников и планов есть встроенные методы поиска: НайтиПоКоду(), НайтиПоНаименованию(), НайтиПоРеквизиту(). Все они возвращают ссылку; если ничего не найдено — пустую ссылку.

НайденнаяСсылка = Справочники.Номенклатура.НайтиПоКоду("0000123");

Если НайденнаяСсылка.Пустая() Тогда

// Объекта с таким кодом нет — можно создавать новый

НовыйЭлемент = Справочники.Номенклатура.СоздатьЭлемент();

НовыйЭлемент.Наименование = "Новая позиция";

НовыйЭлемент.Записать();

КонецЕсли;

Метод НайтиПоНаименованию() ищет точное совпадение без учёта регистра в большинстве случаев, но не по части строки. Для поиска по произвольному реквизиту используйте НайтиПоРеквизиту("ИНН", "7707083893"). Учтите: поиск по неиндексированному реквизиту на больших таблицах работает медленно.

Проверка существования объекта по ссылке через запрос

Чтобы убедиться, что ссылка реально существует в базе (не битая), выполните запрос:

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ ПЕРВЫЕ 1

| Номенклатура.Ссылка

|ИЗ

| Справочник.Номенклатура КАК Номенклатура

|ГДЕ

| Номенклатура.Ссылка = &Ссылка";

Запрос.УстановитьПараметр("Ссылка", ПроверяемаяСсылка);

Если Запрос.Выполнить().Пустой() Тогда

Сообщить("Объект в базе не найден (битая ссылка)");

КонецЕсли;

Это самый надёжный способ: запрос обращается напрямую к таблице и возвращает результат только при наличии записи. Конструкция ВЫБРАТЬ ПЕРВЫЕ 1 минимизирует нагрузку — сервер остановится после первой найденной строки.

Порядок проверки ссылки из обмена
  1. 1
    Проверьте переменную: Неопределено или ЗначениеЗаполнено()
  2. 2
    Проверьте Ссылка.Пустая() — отсеките незаполненные значения
  3. 3
    Выполните запрос ВЫБРАТЬ ПЕРВЫЕ 1 по ссылке
  4. 4
    Если запрос пустой — объект отсутствует, создайте его или запишите ошибку в журнал
  5. 5
    Только после этого вызывайте ПолучитьОбъект() для изменения данных

Проверка через ПолучитьОбъект и когда её избегать

Метод ПолучитьОбъект() загружает данные объекта в память. Если ссылка битая, он вернёт Неопределено:

Объект = Ссылка.ПолучитьОбъект();

Если Объект = Неопределено Тогда

Сообщить("Объект не найден в базе");

КонецЕсли;

Однако использовать ПолучитьОбъект() только ради проверки — плохая практика. Метод вычитывает из базы все данные объекта, включая табличные части, что в разы тяжелее запроса ВЫБРАТЬ ПЕРВЫЕ 1. В циклах по тысячам ссылок это даёт заметную просадку производительности. Вызывайте ПолучитьОбъект() только если объект действительно нужно прочитать или изменить.

Проверка существования документа по номеру и дате

Для документов метода «НайтиПоНомеру» в чистом виде нет — номер уникален только в пределах периода. Правильный путь — запрос с отбором по номеру и диапазону дат:

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ ПЕРВЫЕ 1

| Реализация.Ссылка

|ИЗ

| Документ.РеализацияТоваровУслуг КАК Реализация

|ГДЕ

| Реализация.Номер = &Номер

| И Реализация.Дата МЕЖДУ &НачалоГода И &КонецГода";

Запрос.УстановитьПараметр("Номер", "000000123");

Запрос.УстановитьПараметр("НачалоГода", НачалоГода(ТекущаяДатаСеанса()));

Запрос.УстановитьПараметр("КонецГода", КонецГода(ТекущаяДатаСеанса()));

Результат = Запрос.Выполнить();

ДокументСуществует = Не Результат.Пустой();

Обратите внимание: номер документа — строка, и в разных базах её длина и лидирующие нули могут отличаться. При загрузке из внешних систем приводите номер к формату базы-приёмника, иначе поиск не найдёт существующий документ и вы создадите дубль.

Сравнение способов проверки

Сравнение вариантов

Ссылка.Пустая() / ЗначениеЗаполнено()

Самая быстрая, без обращения к базе. Не защищает от битых ссылок — только проверяет заполненность переменной.

НайтиПоКоду / НайтиПоНаименованию / НайтиПоРеквизиту

Подходит для поиска по ключевым полям справочников. Медленный на неиндексированных реквизитах, не работает для документов по номеру.

Запрос ВЫБРАТЬ ПЕРВЫЕ 1

Универсальный и надёжный способ для любых условий, включая документы и составные отборы. Требует написания текста запроса.

ПолучитьОбъект() = Неопределено

Даёт готовый объект для работы, но тяжёлый: читает все данные. Оправдан только когда объект нужен для изменения.

Типичные ошибки и частые сценарии

Главная ошибка — путать проверку заполненности с проверкой существования. Код Если Не Ссылка.Пустая() пропускает битые ссылки, и следующее обращение к реквизитам возвращает «<Объект не найден>» вместо данных.

Вторая частая ошибка — поиск по наименованию как ключу. Наименования не уникальны: два контрагента могут называться одинаково. Для идентификации используйте код, ИНН, GUID или специальный реквизит-идентификатор.

Типичные ошибки
01
Проверка только через Пустая() — битые ссылки проходят проверку и ломают логику ниже по коду
02
Поиск дублей по наименованию — одинаковые наименования у разных объектов дают ложные совпадения
03
Вызов ПолучитьОбъект() в цикле ради проверки — резкое падение производительности на больших объёмах
04
Поиск документа по номеру без учёта периода и формата номера — дубли документов при загрузке
05
Игнорирование пометки удаления — найденный объект может быть помечен на удаление, и работать с ним как с действующим нельзя

Учёт пометки удаления

Если объект помечен на удаление, формально он существует, но использовать его в новых документах обычно нельзя. Добавьте в запрос условие И НЕ Таблица.ПометкаУдаления или проверяйте реквизит ПометкаУдаления у найденной ссылки.

Проверка по GUID из другой базы

При обмене объект часто ищут по уникальному идентификатору. Получить ссылку по GUID можно через Справочники.Номенклатура.ПолучитьСсылку(Новый УникальныйИдентификатор(СтрокаGUID)), а затем запросом проверить её существование — сама по себе полученная так ссылка всегда непустая, даже если объекта нет.

Контрольные точки

Как проверить результат

Поиск по коду вернул ссылку
Норма

Ссылка не пустая, запрос по ней находит запись, ПометкаУдаления = Ложь

Тревожный признак

Ссылка непустая, но запрос пустой — это битая ссылка, объект нужно создавать заново

Объект не найден, создаётся новый
Норма

После Записать() повторный поиск находит ровно один объект

Тревожный признак

Повторный поиск находит несколько объектов — в логике создания дубль, проверьте условия поиска

Проверка в цикле на большом объёме
Норма

Используется один запрос с условием В(&МассивСсылок) вместо запроса в цикле

Тревожный признак

Запрос выполняется на каждой итерации — время обработки растёт линейно и нагружает сервер

FAQ

Чем отличается Пустая() от ЗначениеЗаполнено()?

Метод Пустая() есть только у ссылок и проверяет, равна ли ссылка пустому значению своего типа. ЗначениеЗаполнено() — универсальная функция: она корректно обрабатывает Неопределено, пустые ссылки, пустые строки, ноль и пустые даты. Для проверки входных параметров произвольного типа используйте ЗначениеЗаполнено().

Как проверить существование объекта, если есть только GUID из другой базы?

Сформируйте ссылку через ПолучитьСсылку(Новый УникальныйИдентификатор(СтрокаGUID)) — она всегда будет непустой. Затем выполните запрос ВЫБРАТЬ ПЕРВЫЕ 1 по этой ссылке: если запрос пустой, объекта в базе нет и его нужно создавать с привязкой к этому же идентификатору.

Почему НайтиПоНаименованию не находит объект, который точно есть?

Чаще всего причины — лишние пробелы, неразрывные пробелы из внешних файлов, разный регистр спецсимволов или то, что метод ищет только точное совпадение всей строки. Очистите строку через СокрЛП() и, при необходимости, используйте запрос с ПОДОБНО для частичного поиска.

Можно ли проверить существование объекта без запроса в цикле по тысяче ссылок?

Да. Соберите все ссылки в массив и выполните один запрос с условием ГДЕ Ссылка В(&МассивСсылок). Результат выгрузите в таблицу значений и дальше ищите по ней через Найти() — это на порядки быстрее, чем запрос на каждой итерации.

Что вернёт обращение к реквизиту битой ссылки?

Обращение к реквизитам битой ссылки не вызывает исключение — платформа возвращает строку вида «<Объект не найден> (…guid…)» для ссылочных полей или значения по умолчанию. Это опасно тем, что ошибка проявляется не сразу, а в виде некорректных данных в отчётах и документах.

Нужно ли проверять пометку удаления при поиске объекта?

Да, если найденный объект будет использоваться в новых документах или справочниках. Помеченный на удаление объект формально существует, но его использование приведёт к ошибкам при удалении помеченных. Добавьте в запрос условие НЕ ПометкаУдаления или обработайте этот случай отдельно — например, снимите пометку или создайте новый элемент.

Итог

Что важно запомнить

Пустая() проверяет заполненность переменной, а не существование записи в базе. Реальное существование подтверждает только запрос ВЫБРАТЬ ПЕРВЫЕ 1 или ПолучитьОбъект() с проверкой на Неопределено. Ищите объекты по уникальным ключам (код, GUID, ИНН), учитывайте пометку удаления и не вызывайте ПолучитьОбъект() в циклах ради одной проверки.