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