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