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