В процессе разработки на платформе 1С:Предприятие мы часто сталкиваемся с задачами, когда в качестве параметра запроса передается ссылка на документ или справочник, тип которого становится известен только во время выполнения программы. Классическая попытка обращения к реквизиту через точку, например Т.Документ.Реквизит, вызывает ошибку, если тип объекта не является строго заданным для данного поля или если реквизит отсутствует у некоторых объектов из перечня возможных типов.
Многие разработчики начинают с использования конструкции ВЫБОР КОГДА ССЫЛКА.... Однако при работе с полями составного типа 1С требует строгого соблюдения типизации. Когда мы используем ВЫБОР, семантический анализатор запросов пытается привести все возможные варианты к одному типу данных. Если мы пытаемся принудительно «превратить» неизвестный объект в конкретный документ с помощью ВЫРАЗИТЬ, мы можем получить ошибку «Несовместимые типы», так как система ожидает единообразия в структуре выборки.
Наиболее надежным, профессиональным и производительным способом решения этой задачи является использование ЛЕВОГО СОЕДИНЕНИЯ с таблицей того объекта, реквизит которого нам нужно получить. Этот метод исключает проблемы с приведением типов, так как запрос работает с физическими таблицами базы данных.
Давайте разберем по шагам, как правильно реализовать этот подход:
ЛЕВОЕ СОЕДИНЕНИЕ с таблицей конкретного документа, например Документ.ЗаказКлиента.Ссылка.NULL, который мы можем легко обработать.Рассмотрим код, который демонстрирует этот подход на практике. Мы предполагаем, что у нас есть параметр &Регистратор, который мы хотим «проверить» на наличие реквизита Подразделение:
ВЫБРАТЬ
&Регистратор КАК ДокументРегистратор
ПОМЕСТИТЬ Т
;
ВЫБРАТЬ
Т.ДокументРегистратор КАК ДокументРегистратор,
ЗаказКлиента.Подразделение КАК Подразделение
ИЗ
Т КАК Т
ЛЕВОЕ СОЕДИНЕНИЕ Документ.ЗаказКлиента КАК ЗаказКлиента
ПО (Т.ДокументРегистратор = ЗаказКлиента.Ссылка)
В данном запросе, если в Т.ДокументРегистратор находится документ, отличный от ЗаказКлиента, условие соединения Т.ДокументРегистратор = ЗаказКлиента.Ссылка не будет выполнено, и поле Подразделение вернет NULL. Это поведение является корректным с точки зрения СУБД.
Часто в бизнес-логике требуется, чтобы отсутствие данных было представлено значением Неопределено, а не NULL. Чтобы добиться такого результата, мы можем обернуть выборку в дополнительную логику:
ВЫБРАТЬ
Документы.ДокументРегистратор КАК ДокументРегистратор,
ВЫБОР
КОГДА ЗаказКлиента.Ссылка ЕСТЬ NULL ТОГДА НЕОПРЕДЕЛЕНО
ИНАЧЕ ЗаказКлиента.Подразделение
КОНЕЦ КАК Подразделение
ИЗ
ВтДокументы КАК Документы
ЛЕВОЕ СОЕДИНЕНИЕ Документ.ЗаказКлиента КАК ЗаказКлиента
ПО Документы.ДокументРегистратор = ЗаказКлиента.Ссылка
Проанализируем преимущества данного подхода:
Ссылка, так как оно проиндексировано.ЛЕВЫХ СОЕДИНЕНИЙ и использовать ЕСТЬNULL для последовательного выбора заполненного значения.ВЫБОР.Используя этот подход, вы навсегда забудете о проблемах с типизацией в запросах при работе с объектами метаданных и обеспечите стабильную работу вашей конфигурации в любых условиях!