Как решить проблему обращения к реквизитам через точку в запросах динамических списков внутри расширений 1С

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке расширений для платформы 1С:Предприятие 8.3 программисты часто сталкиваются с неприятной особенностью: заимствованные реквизиты со сложным составным типом (например, ДокументОснование) внутри расширения внезапно «теряют» свою структуру и превращаются в обычную ЛюбуюСсылку (AnyRef). Это приводит к тому, что в конструкторе запроса или в самом тексте запроса динамического списка становится невозможно обратиться к полям через точку, например, получить ДокументОснование.Контрагент. В этой статье мы подробно разберем, почему так происходит, и рассмотрим эффективные методы решения данной проблемы.

Выясняем причину: почему типы превращаются в ЛюбуюСсылку

Проанализируем ситуацию. Когда мы заимствуем форму списка и связанный с ней динамический список в расширение, платформа пытается сопоставить метаданные. Если в основной конфигурации реквизит имеет составной тип, включающий, скажем, пять видов документов, а в расширение вы добавили только один из них (или не добавили вовсе), платформа не может гарантировать целостность типа. В целях безопасности она упрощает тип до ЛюбаяСсылка.

Ситуация осложняется в отраслевых конфигурациях (например, решения от Рарус или БИТ), где цепочки взаимосвязей документов могут быть очень длинными. Если тип реквизита в расширении не совпадает с типом в основной конфигурации, механизм разыменования полей (обращение через точку) блокируется на уровне компиляции запроса внутри расширения.

Решение №1: Программная подмена текста запроса

Рассмотрим метод, предложенный опытными разработчиками: обход ограничений конструктора запросов в расширении путем программной установки текста. Часто конструктор в конфигураторе «ругается» на отсутствие полей, но в режиме «1С:Предприятие» метаданные основной конфигурации доступны в полном объеме.

Разберем по шагам, как это реализовать. Нам необходимо использовать обработчик события ПриСозданииНаСервере формы списка, которую мы перенесли в расширение. Вместо того чтобы мучиться с визуальным редактором динамического списка, мы подготовим текст запроса в обычном текстовом редакторе или консоли запросов и присвоим его программно.

Посмотрим на пример кода:


&НаСервере
Процедура Расш1_ПриСозданииНаСервереПосле(Отказ, СтандартнаяОбработка)
    
    // Получаем текущую схему запроса динамического списка
    ТекстЗапроса = 
    "ВЫБРАТЬ
    |    СписокДокументов.Ссылка КАК Ссылка,
    |    СписокДокументов.Дата КАК Дата,
    |    СписокДокументов.Номер КАК Номер,
    |    СписокДокументов.ДокументОснование КАК ДокументОснование,
    |    СписокДокументов.ДокументОснование.Контрагент КАК КонтрагентОснования,
    |    СписокДокументов.ДокументОснование.СуммаДокумента КАК СуммаОснования
    |ИЗ
    |    Документ.ЗаказПоставщику КАК СписокДокументов";
    
    // Принудительно устанавливаем текст запроса для динамического списка
    Список.ТекстЗапроса = ТекстЗапроса;
    
КонецПроцедуры

Этот способ хорош тем, что он требует минимального заимствования объектов. Нам не нужно тащить в расширение все типы, входящие в ДокументОснование, так как платформа выполнит этот запрос в контексте всей базы данных при запуске приложения.

Решение №2: Использование оператора ВЫРАЗИТЬ (CAST)

Если программная подмена не помогает или вы хотите, чтобы запрос оставался «типизированным» для платформы, проанализируем использование оператора ВЫРАЗИТЬ. Это наиболее корректный с точки зрения SQL способ работы с составными типами.

Когда платформа видит ЛюбуюСсылку, она не знает, к какой именно таблице обращаться в базе данных для получения реквизита через точку. Мы можем явно указать ей путь. Однако помните: чтобы это сработало, целевой тип (например, ПриходнаяНакладная) обязательно должен быть заимствован в расширение.

Пример использования в тексте запроса:


ВЫБРАТЬ
    Заказ.Ссылка,
    ВЫРАЗИТЬ(Заказ.ДокументОснование КАК Документ.ПриходнаяНакладная).Контрагент КАК КонтрагентИзПН
ИЗ
    Документ.ЗаказПоставщику КАК Заказ

Этот подход позволяет избежать ошибки «поле не обнаружено» при сохранении расширения, так как вы явно указываете платформе, какой тип данных ожидается.

Решение №3: Ручное управление составом типов в расширении

Рассмотрим более радикальный, но эффективный метод — принудительное приведение типов заимствованного реквизита к составному виду вручную. Как отмечалось в обсуждении, иногда платформа не дает менять тип заимствованного объекта, ссылаясь на режим совместимости.

Выполним следующие действия для исправления ситуации:

  1. Заимствование типов: Добавьте в расширение все объекты метаданных (документы, справочники), которые входят в состав типа ДокументОснование в основной конфигурации.
  2. Снятие контроля: В свойствах заимствованного реквизита в расширении попробуйте отключить флаг «Проверять значение» (если доступно в вашей версии платформы).
  3. Ручная правка типа: В окне свойств реквизита внутри расширения нажмите на кнопку выбора типа и вручную отметьте галочками все те документы, которые вы заимствовали на шаге 1.

Важный нюанс: Если версия режима совместимости расширения ниже 8.3.15, работа с составными типами будет крайне ограничена. Проверьте, чтобы режим совместимости расширения соответствовал режиму основной конфигурации (или был выше, если это допустимо).

Решение №4: Особенности «ленивого» обновления метаданных

Иногда причина кроется в банальном кэшировании метаданных конфигуратором. Вы можете добавить все необходимые документы в расширение, но конструктор запроса все равно будет видеть ЛюбуюСсылку. Проанализируем, как «встряхнуть» конфигуратор:

  1. После заимствования всех типов документов закройте все окна конструкторов запросов.
  2. Сохраните расширение (Ctrl+S) и обновите конфигурацию базы данных (F7).
  3. В некоторых случаях помогает полное закрытие конфигуратора и его повторный запуск. Только после перезапуска связи между таблицами в контексте расширения обновляются корректно, и «плюсик» слева от реквизита в конструкторе (позволяющий раскрыть поля) снова появляется.

Рекомендации для сложных отраслевых решений

Если вы работаете с конфигурациями вроде ЖКХ или CRM, где реквизитов через точку может быть очень много, лучшей стратегией будет комбинированный подход:

Таким образом, мы выяснили, что проблема «ЛюбойСсылки» в расширениях — это не приговор, а следствие строгого контроля типов платформой. Используя программную подмену текста запроса или явное приведение типов через ВЫРАЗИТЬ, вы сможете успешно переносить формы в расширения, сохраняя всю необходимую функциональность списков.

← На главную