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