В практике разработчика 1С часто возникает ситуация, когда в справочниках появляются объекты с идентичными наименованиями или кодами. Особенно остро эта проблема проявляется при настройке обменов данными между различными конфигурациями (например, между производственной базой и 1С:Бухгалтерия 3.0). В таких условиях стандартные методы поиска могут вести себя непредсказуемо. Рассмотрим подробно, как ведут себя встроенные функции платформы и как гарантированно найти нужный объект.
Разберем ситуацию: у нас есть два склада с одинаковым названием "Склад готовой продукции" и одинаковым кодом "00001". Один из них является рабочим, а второй помечен на удаление (возможно, он остался от старых обменов или был создан ошибочно). Если мы попытаемся использовать стандартный метод НайтиПоНаименованию("Склад готовой продукции"), платформа вернет нам первый попавшийся объект, который предоставит система управления базами данных (СУБД).
Проанализируем ключевые особенности работы этих методов:
НайтиПоКоду() и НайтиПоНаименованию() возвращают ссылку на объект, даже если он помечен на удаление. Встроенного фильтра "только живые объекты" у них нет.Самым надежным способом программного обращения к конкретному объекту является использование его Уникального Идентификатора (GUID). В 1С ссылка (Ref) в таблицах СУБД — это и есть GUID. Если мы точно знаем идентификатор нужного нам склада, мы можем избежать неопределенности поиска.
Рассмотрим пример кода, в котором мы проверяем, относится ли склад документа к списку разрешенных (или исключаемых) объектов, используя строковое представление GUID:
// Определяем GUID нужных складов (получаем их заранее из базы)
GUIDОбъекта01 = "fd6a1058-c83c-11e7-915f-001e676f8a27";
GUIDОбъекта02 = "3e0fae54-d423-11e7-a02f-001e676f8a27";
// Получаем строковое представление GUID склада из текущего документа
GUIDСкладаДокумента = Строка(ОбъектДокумент.Склад.УникальныйИдентификатор());
Если (GUIDСкладаДокумента = GUIDОбъекта01) ИЛИ (GUIDСкладаДокумента = GUIDОбъекта02) Тогда
// Выполняем действия для найденных складов
КонецЕсли;
Важный нюанс типизации: Обратите внимание, что метод УникальныйИдентификатор() возвращает объект типа УникальныйИдентификатор, а не строку. Для корректного сравнения с литералом строки необходимо использовать функцию Строка(). Однако, с точки зрения производительности, в высоконагруженных циклах лучше один раз создать объект идентификатора и сравнивать типы напрямую, не преобразуя их в текст постоянно.
Если мы не знаем точного GUID, но нам нужно найти "правильный" объект среди дублей (например, тот, который не помечен на удаление), использование НайтиПо... становится невозможным. В этом случае мы должны использовать механизм запросов. Запрос позволяет гибко настроить условия отбора.
Проанализируем пример запроса, который находит актуальный склад, исключая помеченные на удаление:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 1
| Склады.Ссылка КАК Ссылка
|ИЗ
| Справочник.Склады КАК Склады
|ГДЕ
| Склады.Наименование = &Наименование
| И НЕ Склады.ПометкаУдаления";
Запрос.УстановитьПараметр("Наименование", "Склад готовой продукции");
РезультатЗапроса = Запрос.Выполнить();
Если НЕ РезультатЗапроса.Пустой() Тогда
Выборка = РезультатЗапроса.Выбрать();
Выборка.Следующий();
НужнаяСсылка = Выборка.Ссылка;
КонецЕсли;
Использование ВЫБРАТЬ ПЕРВЫЕ 1 гарантирует, что мы получим только один результат, а условие НЕ ПометкаУдаления отсеет "мусорные" записи, которые часто возникают при некорректной работе обменов.
Ситуация, когда помеченный на удаление объект "оживает" или дублируется при каждом обмене, обычно связана с настройками синхронизации. Посмотрим на причины этого явления:
ЛЕВОЕ СОЕДИНЕНИЕ в сложных запросах.Если вам нужно обработать тысячи документов, вызов НайтиПоКоду() или выполнение отдельного запроса в цикле для каждого документа — это грубая ошибка проектирования. Это приведет к огромному количеству обращений к серверу БД.
Рассмотрим правильный алгоритм массовой обработки:
Соответствие (Map), где ключом будет ссылка, а значением — структура данных склада.Соответствию в оперативной памяти. Это ускоряет работу программы в десятки и сотни раз.Если склады, которые вам нужно исключить или отобрать, являются константными (постоянными для логики системы), подумайте о создании предопределенных элементов в конфигураторе. В коде к ним можно будет обращаться напрямую: Справочники.Склады.Цех1. Это полностью исключает необходимость поиска и делает код устойчивым к любым изменениям наименований или кодов пользователями в режиме "1С:Предприятие".
Подведем итог: для разовых задач в консоли кода допустимо использовать поиск по наименованию с последующей проверкой ПометкаУдаления. Для надежной программной логики, особенно в обменах, следует использовать поиск по УникальныйИдентификатор или специализированные запросы.