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