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

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

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

Почему нельзя обращаться к табличной части через точку?

Многие разработчики на начальном этапе пытаются написать запрос вида: Документ.Клиент.КонтактнаяИнформация.НомерТелефона. Платформа 1С выдает ошибку, так как табличная часть является самостоятельным набором данных. В базе данных она представлена отдельной таблицей, связанной с владельцем через ссылку. Чтобы получить доступ к этим данным, необходимо использовать механизм соединений (JOIN) в языке запросов.

Решение: использование левого соединения (LEFT JOIN)

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


ВЫБРАТЬ
    Документ.Ссылка КАК Ссылка,
    Документ.Номер КАК Номер,
    КлиентКонтактнаяИнформация.Представление КАК Телефон
ИЗ
    Документ.ор_Заказ КАК Документ
ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ФизическиеЛица.КонтактнаяИнформация КАК КлиентКонтактнаяИнформация
ПО Документ.Клиент = КлиентКонтактнаяИнформация.Ссылка

Использование ЛЕВОЕ СОЕДИНЕНИЕ важно, так как если у клиента не заполнена контактная информация, мы все равно хотим получить данные о самом заказе (номер, дату и т.д.).

Почему данные могут пропадать или дублироваться?

В типовых конфигурациях 1С табличная часть КонтактнаяИнформация является универсальной. В ней хранятся и телефоны, и адреса, и почтовые ящики. Если мы сделаем простое соединение, как показано выше, для каждого клиента мы получим столько строк, сколько записей контактной информации у него заведено. Если у клиента есть и телефон, и email, в выборке будет два дубля по строке заказа. Более того, если в макете вы используете поле НомерТелефона, а в таблицу попала строка с Email, значение окажется пустым.

Как правильно фильтровать контактную информацию?

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


ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ФизическиеЛица.КонтактнаяИнформация КАК КлиентКонтактнаяИнформация
ПО Документ.Клиент = КлиентКонтактнаяИнформация.Ссылка
    И (КлиентКонтактнаяИнформация.Тип = ЗНАЧЕНИЕ(Перечисление.ТипыКонтактнойИнформации.Телефон))
    И (КлиентКонтактнаяИнформация.Вид = ЗНАЧЕНИЕ(Справочник.ВидыКонтактнойИнформации.ТелефонДомашнийФизическиеЛица))

Обратите внимание на следующие важные моменты:

  1. Используйте представление: Вместо прямого доступа к полю с номером телефона лучше использовать поле Представление, так как оно уже содержит отформатированную строку, готовую для вывода в печатную форму.
  2. Фильтрация в соединении: Все условия отбора по виду и типу контактной информации обязательно указывайте именно в секции ПО. Если перенести их в секцию ГДЕ, левое соединение превратится в обычное внутреннее соединение, и вы потеряете всех клиентов, у которых телефон не заполнен.
  3. Несколько видов данных: Если вам нужно получить и телефон, и email одновременно, лучше сделать два разных левых соединения с разными условиями по Виду контактной информации. Это позволит вывести данные в разные колонки результирующей выборки.

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

← На главную