Как обойти ошибку «Поле не найдено» при обращении к Регистратору в запросе расширения 1С?

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

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

Почему возникает ошибка обращения к Регистратору в расширении?

Для начала проанализируем ситуацию с точки зрения архитектуры платформы. В основной конфигурации 1С тип Регистратор является составным и включает в себя все документы, которые могут делать движения по конкретному регистру. Когда мы пишем в запросе Регистратор.Дата, платформа неявно создает левое соединение со всеми таблицами документов-регистраторов.

В расширении действует принцип минимально необходимых метаданных. Если вы добавили в расширение только регистр бухгалтерии Хозрасчетный, но не добавили в него все документы, которые являются его регистраторами, платформа «не видит» состав типа. Для расширения поле Регистратор становится ссылкой на неопределенный набор объектов, у которых может и не быть поля Дата. Именно поэтому возникает ошибка валидации.

Решение 1. Добавление всех объектов-регистраторов в расширение

Самый прямой, но трудоемкий путь — привести метаданные расширения в соответствие с запросом. Рассмотрим этот процесс по шагам:

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

Проанализируем минусы этого подхода: если регистраторов десятки, расширение становится тяжелым, а его поддержка при обновлении основной конфигурации — затруднительной. Поэтому программисты часто используют более изящные методы.

Решение 2. Использование системных полей регистра (Period вместо Date)

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

Выясним причину, почему это лучше: поле Период принадлежит самому регистру. Если регистр добавлен в расширение, это поле доступно всегда и без лишних соединений. Замените в вашем коде обращение:

ХозрасчетныйОстаткиИОбороты.Регистратор.Дата

на:

ХозрасчетныйОстаткиИОбороты.ПериодСекунда

Это не только решит проблему с расширением, но и значительно ускорит выполнение запроса, так как платформе не придется соединяться с таблицами документов.

Решение 3. Трюк с внешним отчетом (метод «Черного ящика»)

Это практический совет, который часто выручает, когда нужно быстро заставить отчет работать без перетаскивания сотен объектов в расширение. Суть заключается в том, что валидация запроса при загрузке готовой схемы извне проходит менее строго.

Разберем алгоритм действий:

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

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

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

Если нам критично получить данные именно из конкретного типа документа, мы можем явно указать платформе, к какому типу приводить Регистратор. Посмотрим на пример кода:


ВЫБРАТЬ
    ВЫРАЗИТЬ(ХозрасчетныйОстаткиИОбороты.Регистратор КАК Документ.ПоступлениеТоваровУслуг).Комментарий КАК Коммент
ИЗ
    РегистрБухгалтерии.Хозрасчетный.ОстаткиИОбороты(&Начало, &Конец, , , , , ) КАК ХозрасчетныйОстаткиИОбороты

В этом случае нам достаточно добавить в расширение только один документ — ПоступлениеТоваровУслуг. Платформа поймет, что поле Комментарий нужно брать именно из его таблицы. Для всех остальных типов документов в этом поле будет NULL.

Решение 5. Оптимизация через соединения

Рассмотрим ситуацию из сообщения автора темы: он уже присоединяет таблицу Документ.ПоступлениеТоваровУслуг.Товары. В такой ситуации обращение к Регистратор.Комментарий является избыточным и вредным для производительности.

Проанализируем правильный подход. Вместо обращения через точку от составного поля, возьмем данные из уже присоединенной таблицы документа:


ЛЕВОЕ СОЕДИНЕНИЕ Документ.ПоступлениеТоваровУслуг КАК ПоступлениеДок
ПО ХозрасчетныйОстаткиИОбороты.Регистратор = ПоступлениеДок.Ссылка

Теперь в блоке ВЫБРАТЬ мы просто пишем ПоступлениеДок.Комментарий. Это работает стабильно, так как связь идет по конкретной таблице, которая добавлена в расширение.

Итоги и рекомендации

Подводя итог, можно сказать, что наиболее «чистым» решением является использование системных полей регистра (Период) или явное соединение с конкретными таблицами документов. Использование «трюка» с внешним отчетом допустимо в случаях, когда отчет очень сложный и добавление всех метаданных в расширение нецелесообразно. Всегда помните, что обращение через точку от составных типов в запросах — это «антипаттерн» с точки зрения производительности, особенно в расширениях 1С.

← На главную