Как правильно выполнить соединение в запросе 1С по реквизиту составного типа?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке отчетов и обработок в 1С часто возникает необходимость связать две таблицы, в которых содержатся поля составного типа. Например, у нас есть РегистрНакопления, содержащий поле-ссылку на документ, и РегистрСведений, где нужный реквизит является определяемым типом, включающим множество различных сущностей. Разберемся, как правильно организовать такое соединение и на что обратить внимание при отладке.

Понимание работы составных типов в соединениях

Когда мы выполняем запрос к базе данных, платформа 1С берет на себя формирование корректного SQL-запроса. Если мы используем простое условие соединения вида Регистр1.Объект = Регистр2.Данные, где оба поля являются составными типами, платформа ожидает, что для формирования истинного значения соединения должны совпасть не только внутренние идентификаторы (GUID), но и типы данных этих значений. Если в Регистр1 записана ссылка на СправочникСсылка.Справочник1, а в Регистр2 — ДокументСсылка.Реализация, соединение не произойдет даже при совпадении GUID, так как это разные типы объектов.

Важно помнить, что если вы не обращаетесь к полям через точку (то есть не пытаетесь получить Регистр2.Данные.Дата), использование оператора ВЫРАЗИТЬ не является обязательным для выполнения соединения. Система способна сравнивать составные типы напрямую.

Почему соединение может не возвращать данные?

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

  1. Отсутствие данных в базе. Как показала практика, это причина №1. Прежде чем переписывать запрос, всегда проверяйте содержимое таблиц. Выгрузите данные в консоль запросов и убедитесь, что значения, которые должны соединиться, физически существуют в обеих таблицах.
  2. Различие типов данных. Даже если значение выглядит как «Документ №1», проверьте, нет ли путаницы между объектами с похожими названиями. Используйте функцию ТипЗнч() для проверки типов значений в колонках.
  3. Наличие пустых значений. Если в полях составного типа присутствуют пустые ссылки или значения NULL, помните, что NULL не равен NULL в условиях соединения. Используйте ЕСТЬNULL для приведения таких значений к какому-либо результату, если это требуется логикой вашего отчета.

Алгоритм проверки и отладки запроса

Для того чтобы быть уверенными в корректности вашего кода, рекомендуем придерживаться следующего плана действий:

Шаг 1: Раздельная проверка выборок. Сначала выберите данные из первой и второй таблицы отдельно. Убедитесь, что в них попадают именно те сущности, которые вы ожидаете увидеть.

Шаг 2: Проверка типов значений. Если соединение не срабатывает, выгрузите результаты запросов в ТаблицаЗначений и проверьте типы данных в колонках, участвующих в соединении. Это позволит исключить ошибки, когда в одной таблице хранится СправочникСсылка, а в другой — ДокументСсылка.

Шаг 3: Использование временных таблиц. Если у вас сложный запрос с множеством типов в составе определяемого типа, хорошей практикой будет использование ВременныеТаблицы. Это позволяет сначала отфильтровать нужные типы с помощью ВЫРАЗИТЬ:


ВЫБРАТЬ
    ВЫРАЗИТЬ(Регистр2.Данные КАК Документ.РеализацияТоваровУслуг) КАК ОбъектДляСоединения
ПОМЕСТИТЬ ВТ_Данные
ИЗ
    РегистрСведений.НашРегистр КАК Регистр2
ГДЕ
    Регистр2.Данные ССЫЛКА Документ.РеализацияТоваровУслуг;

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

Заключение

Работа с составными типами в запросах 1С требует внимательности к структуре данных. Помните, что платформа — мощный инструмент, но она работает строго с теми данными, которые в ней содержатся. Если вы уверены в синтаксисе запроса, но не получаете результат, не бойтесь вернуться к проверке исходных данных. В 90% случаев проблема кроется именно в их отсутствии или несоответствии типов в регистре.

← На главную