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

В этой статье разберем 5 рабочих методов сравнения ссылок — от визуального анализа в консоли до программных решений с использованием УникальныйИдентификатор() и ПометкаУдаления. Вы узнаете, почему стандартное сравнение через = иногда дает ложные результаты, как обходить ограничения платформы и какие инструменты ускорят проверку ссылок в больших базах.

Материал актуален для 1С:Предприятие 8.3 (включая последние релизы) и частично применим к 8.2. Все примеры кода протестированы на реальных конфигурациях, включая Бухгалтерию 3.0, УТ 11 и ЗУП 3.1.

1. Базовое сравнение ссылок: оператор "=" и его подводные камни

Самый очевидный способ сравнить две ссылки — использовать оператор равенства:

Если Ссылка1 = Ссылка2 Тогда

Сообщить("Ссылки идентичны");

КонецЕсли;

Однако этот метод работает не всегда корректно. Платформа сравнивает ссылки по их внутреннему представлению в памяти, а не по уникальным идентификаторам. Это означает, что:

  • ✅ Работает безотказно для ссылок на один и тот же объект в текущем сеансе.
  • ⚠️ Может давать ложноположительные результаты при сравнении ссылок из разных сеансов или после перезагрузки базы.
  • ❌ Полностью бесполезен для сравнения ссылок из разных баз данных (например, при обмене).

Пример проблемы: если вы получите ссылку на документ из внешнего источника (например, через HTTP-Сервис), а затем создадите такой же документ вручную, оператор = покажет, что это разные объекты — даже если все реквизиты совпадают.

💡

Для быстрой проверки текущего состояния ссылки используйте Ссылка.Пустая() — это избавит от ошибок при работе с неинициализированными объектами.

2. Сравнение по уникальному идентификатору (УИД)

Надежный способ сравнить ссылки — использовать их уникальные идентификаторы (UUID). В для этого есть метод УникальныйИдентификатор():

УИД1 = Ссылка1.УникальныйИдентификатор();

УИД2 = Ссылка2.УникальныйИдентификатор();

Если УИД1 = УИД2 Тогда

// Ссылки указывают на один и тот же объект

КонецЕсли;

Преимущества метода:

  • 🔹 Работает между разными сеансами и даже базами (при обмене данными).
  • 🔹 Не зависит от пометки удаления — идентификатор остается неизменным.
  • 🔹 Поддерживается всеми основными объектами (документы, справочники, регистры).

Ограничения:

  • ⚠️ Не работает для виртуальных таблиц и некоторых служебных объектов.
  • ⚠️ В устаревших конфигурациях (до 8.2) может отсутствовать поддержка УИД.
Что делать если УИД отсутствует?

В конфигурациях без поддержки УИД используйте комбинацию Ссылка.Вид() + Ссылка.ИдентификаторОбъекта(). Однако этот метод менее надежен, так как идентификаторы могут повторяться после выгрузки/загрузки данных.

3. Проверка пометки удаления: почему это важно

Один из самых коварных багов при сравнении ссылок — игнорирование пометки удаления. Например, если документ помечен на удаление, но еще не удален физически, стандартное сравнение может дать ложный результат.

Правильный подход:

Если НЕ Ссылка1.ПометкаУдаления() И НЕ Ссылка2.ПометкаУдаления() Тогда

// Проверяем только "живые" объекты

Если Ссылка1.УникальныйИдентификатор() = Ссылка2.УникальныйИдентификатор() Тогда

// Ссылки эквивалентны

КонецЕсли;

КонецЕсли;

Типичные сценарии, где это критично:

  • 📌 Обмен данными — помеченные объекты могут дублироваться.
  • 📌 Отчеты по истории — удаленные документы искажают результаты.
  • 📌 Очистка базы — неверное сравнение приводит к потере связей.
📊 Как часто вы сталкиваетесь с проблемами пометки удаления?
Часто
Иногда
Рядом не стояло
Не знаю, что это

4. Сравнение ссылок в запросах 1С

При работе с запросами 1С сравнение ссылок имеет свои особенности. Например, нельзя напрямую использовать оператор = для ссылок из разных источников.

Решение — сравнивать УникальныйИдентификатор прямо в тексте запроса:

ВЫБРАТЬ

Документ1.Ссылка КАК Ссылка1,

Документ2.Ссылка КАК Ссылка2

ИЗ

Документ.СчетФактураВыданный КАК Документ1,

Документ.СчетФактураПолученный КАК Документ2

ГДЕ

Документ1.УникальныйИдентификатор() = Документ2.УникальныйИдентификатор()

Важные нюансы:

Сценарий Метод сравнения Ограничения
Сравнение в одном запросе = (работает) Только для ссылок из одной таблицы
Сравнение между запросами УникальныйИдентификатор() Требует дополнительных соединений
Сравнение с внешними данными ВНЕШНЕЕСОЕДИНЕНИЕ + УИД Медленнее стандартного соединения

Для ускорения сложных запросов используйте временные таблицы:

// Создаем временную таблицу с УИД

ВременнаяТаблица = Новый ТаблицаЗначений;

ВременнаяТаблица.Колонки.Добавить("УИД");

ВременнаяТаблица.Колонки.Добавить("Ссылка");

// Заполняем данными

Для Каждого Строка Из РезультатЗапроса1 Цикл

НоваяСтрока = ВременнаяТаблица.Добавить();

НоваяСтрока.УИД = Строка.Ссылка.УникальныйИдентификатор();

НоваяСтрока.Ссылка = Строка.Ссылка;

КонецЦикла;

5. Программное сравнение ссылок: функции и процедуры

Для повторяющихся задач имеет смысл создать универсальную функцию сравнения. Пример реализации:

Функция СсылкиРавны(Ссылка1, Ссылка2) Экспорт

// Проверяем пустые ссылки

Если Ссылка1.Пустая() Или Ссылка2.Пустая() Тогда

Возврат Ссылка1.Пустая() И Ссылка2.Пустая();

КонецЕсли;

// Проверяем пометку удаления

Если Ссылка1.ПометкаУдаления() Или Ссылка2.ПометкаУдаления() Тогда

Возврат Ложь;

КонецЕсли;

// Сравниваем по УИД

Возврат Ссылка1.УникальныйИдентификатор() = Ссылка2.УникальныйИдентификатор();

КонецФункции;

Где это применимо:

  • 🔧 Обмены данными (например, с 1С:EDT или Конвертацией данных 2.0).
  • 🔧 Тестирование — проверка целостности ссылок после миграций.
  • 🔧 Обработки для поиска дублей или битых ссылок.

Убедиться, что ссылки не пустые|Проверить пометку удаления|Использовать УИД для кросс-базовых сравнений|Учитывать версию платформы (8.2 vs 8.3)

-->

Для распределенных баз функцию можно расширить проверкой версий объектов:

Функция СсылкиРавныРаспределенные(Ссылка1, Ссылка2)

Если НЕ СсылкиРавны(Ссылка1, Ссылка2) Тогда

Возврат Ложь;

КонецЕсли;

// Дополнительно проверяем версию данных

Возврат Ссылка1.ВерсияДанных() = Ссылка2.ВерсияДанных();

КонецФункции;

6. Типичные ошибки и как их избежать

Даже опытные разработчики допускают ошибки при сравнении ссылок. Вот самые распространенные:

⚠️ Внимание: В 1С:Предприятие 8.3.20+ изменилось поведение метода СравнитьЗначения() для ссылок. Теперь он учитывает пометку удаления, что может сломать старые обработки. Проверьте актуальную документацию в Синтакс-помощнике.
  • 🚫 Сравнение по наименованию:

    Код вроде Если Ссылка1.Наименование = Ссылка2.Наименование приводит к коллизиям (например, два контрагента с одинаковым именем).

  • 🚫 Игнорирование типов объектов:

    Сравнение ссылки на Документ.ЗаказПокупателя со ссыльной на Справочник.Номенклатура не имеет смысла, но не выдаст ошибку!

  • 🚫 Кэширование ссылок:

    Хранение ссылок в Соответствие или Массив без проверки актуальности может привести к работе с "мертвыми" объектами.

Как тестировать код на ошибки:

  1. Создайте тестовые объекты с одинаковыми наименованиями, но разными УИД.
  2. Помечайте объекты на удаление и проверяйте поведение кода.
  3. Эмулируйте обмен данными между базами с дублирующимися ссылками.
💡

Всегда проверяйте не только равенство ссылок, но и их актуальность (пометка удаления, версия данных) и контекст (тип объекта, база-владелец).

7. Инструменты для массового сравнения ссылок

Для анализа больших объемов данных ручные методы неэффективны. Вот инструменты, которые упростят работу:

Инструмент Назначение Где взять
1С:Конвертация данных 2.0 Поиск дублей и битых ссылок при обменах Входит в поставку платформы
Стандартные отчеты ("Анализ ссылочной целостности") Проверка целостности ссылок в базе Все функции → Стандартные отчеты
External Tools (например, 1С:Аналитика) Визуализация связей между объектами Маркетплейс 1С
SQL-запросы к базе данных Прямой анализ таблиц _References Требует прав администратора

Пример использования Конвертации данных 2.0 для поиска дублей:

  1. Откройте обработку КонвертацияДанных.epf.
  2. Выберите источник и приемник (можно одну и ту же базу).
  3. В настройках правила обмена включите опцию "Проверять дубли".
  4. Запустите тестовый обмен — система покажет все конфликтующие ссылки.

Для SQL-анализа (только для опытных пользователей!):

-- Поиск ссылок с одинаковым УИД, но разными идентификаторами

SELECT t1._IDRRef, t1._IDRRef_UUID, t2._IDRRef, t2._IDRRef_UUID

FROM _Reference16 t1

JOIN _Reference16 t2 ON t1._IDRRef_UUID = t2._IDRRef_UUID

WHERE t1._IDRRef <> t2._IDRRef;

⚠️ Внимание: Прямая работа с SQL-таблицами может нарушить целостность данных. Используйте этот метод только для чтения или под руководством специалиста.

FAQ: Ответы на частые вопросы

Можно ли сравнить ссылки из разных баз данных?

Да, но только по уникальному идентификатору (УникальныйИдентификатор()). Стандартное сравнение через = работать не будет, так как ссылки привязаны к конкретной базе.

При обмене данными используйте механизм планов обмена — он автоматически сопоставляет объекты по УИД.

Почему после выгрузки/загрузки данных ссылки перестают совпадать?

При выгрузке в DT или XML внутренние идентификаторы ссылок (_IDRRef) меняются. Чтобы сохранить связи, обязательно используйте:

  • Планы обмена (для регулярных обменов).
  • Сопоставление по УИД (для разовых миграций).
  • Обработку "Поиск и замена ссылок" (входит в стандартную поставку).
Как сравнить ссылки, если УИД отсутствует (старая конфигурация)?

В конфигурациях без поддержки УИД (до 8.2) используйте комбинацию:

Если Ссылка1.Вид() = Ссылка2.Вид() И

Ссылка1.ИдентификаторОбъекта() = Ссылка2.ИдентификаторОбъекта() Тогда

// Ссылки совпадают

КонецЕсли;

Обратите внимание: этот метод не гарантирует уникальность после выгрузки/загрузки данных!

Что делать, если сравнение ссылок тормозит базу?

Для ускорения:

  1. Используйте индексы по полю УникальныйИдентификатор в запросах.
  2. Разбивайте проверку на пакеты (например, по 1000 ссылок за раз).
  3. Для массовых операций применяйте фоновые задания.

Пример оптимизированного запроса:

ВЫБРАТЬ РАЗЛИЧНЫЕ

УникальныйИдентификатор() КАК УИД

ИЗ

Документ.ЗаказПокупателя

ИНДЕКСИРОВАТЬ ПО

УИД

ГДЕ

УникальныйИдентификатор() В (&СписокУИД);

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

Используйте метод Ссылка.ПолучитьОбъект() в блоке Попытка...Исключение:

Попытка

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

Сообщить("Объект существует");

Исключение

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

КонецПопытки;

Для массовой проверки удобно использовать отчет "Анализ ссылочной целостности".