Почему возникает ошибка с полем "Регистратор" в запросе из расширения 1С и как ее исправить?

Программист 1С v8.3 (Управляемые формы) Управленческий учет Финансы и профессиональные услуги
← На главную

При разработке с использованием расширений конфигурации в 1С часто возникает ситуация, когда код, идеально работающий в основной конфигурации, перестает функционировать после переноса в расширение. Особенно часто это касается запросов, обращающихся к полю Регистратор в регистрах накопления. Система может выдавать не самые очевидные ошибки, например, "несовместимые типы ССЫЛКА" или просто ругаться на синтаксис запроса.

Давайте подробно разберем, почему так происходит и какие шаги нужно предпринять, чтобы "подружить" запрос с расширением.

Выясним причину: почему расширение "не видит" Регистратор?

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

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

Однако, когда запрос выполняется в контексте расширения, у расширения по умолчанию нет этой информации. Оно "знает" только о тех объектах, которые в него явно добавлены (захвачены). Если в расширение не добавлены все типы документов, которые могут быть регистраторами, для платформы составной тип поля Регистратор является неполным или неопределенным. Из-за этой нехватки метаданных платформа не может корректно проверить синтаксис запроса и выдает ошибку.

Важный момент: недостаточно добавить в расширение только тот документ, по которому вы делаете отбор в условии ГДЕ. Для корректной синтаксической проверки запроса расширение должно знать обо всех возможных типах, которые может содержать поле Регистратор.

Разберем по шагам: как исправить ошибку

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

Предположим, у нас есть запрос, который перестал работать после переноса в общий модуль расширения:


Запрос.Текст =
"ВЫБРАТЬ
|    солКапиталДУОбороты.Период КАК ДатаДокумента,
|    солКапиталДУОбороты.Портфель КАК Портфель
|ПОМЕСТИТЬ ВТДатаПортфель
|ИЗ
|    РегистрНакопления.солКапиталДУ.Обороты(
|            &ДатаНач,
|            &ДатаКон,
|            Регистратор,
|            Организация = &Организация
|                И Договор = &Договор) КАК солКапиталДУОбороты
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ
|    ДенежныеСредстваУОбороты.Период,
|    ДенежныеСредстваУОбороты.Портфель
|ИЗ
|    РегистрНакопления.ДенежныеСредстваУ.Обороты(
|            &ДатаНач,
|            &ДатаКон,
|            Регистратор,
|            Организация = &Организация
|                И Договор = &Договор) КАК ДенежныеСредстваУОбороты
|ГДЕ
|    ДенежныеСредстваУОбороты.Регистратор ССЫЛКА Документ.ПереводДС";

Здесь система выдает ошибку на строку ...Регистратор ССЫЛКА Документ.ПереводДС, даже если мы добавили в расширение и сам регистр ДенежныеСредстваУ, и документ ПереводДС.

Шаг 1: Полный анализ задействованных объектов

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

Это только верхушка айсберга. Теперь нам нужен полный список регистраторов для каждого регистра.

Шаг 2: Определение и добавление ВСЕХ регистраторов в расширение

Это самый важный шаг. Нам нужно для каждого регистра из списка выше найти все документы, которые могут делать по нему движения.

  1. Откройте основную (не расширение) конфигурацию в конфигураторе.
  2. Найдите в дереве метаданных первый регистр из вашего запроса, например, РегистрНакопления.солКапиталДУ.
  3. Откройте его свойства и перейдите на вкладку "Регистраторы". Вы увидите полный список документов.
  4. Повторите эту операцию для второго регистра — РегистрНакопления.ДенежныеСредстваУ.
  5. Теперь у вас есть два списка документов. Все без исключения документы из обоих списков необходимо добавить в ваше расширение. Для этого в расширении нажмите "Добавить", найдите нужные документы и добавьте их.

После добавления всех документов-регистраторов расширение получит полную информацию о составном типе поля Регистратор для каждого из используемых регистров. Теперь платформа сможет корректно проверить конструкцию ССЫЛКА и выполнить запрос без ошибок.

Альтернативные и обходные пути

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

1. Использование функции ТИПЗНАЧЕНИЯ()

Иногда можно обойти строгую проверку типов, используя функции времени выполнения. Вместо конструкции ССЫЛКА можно использовать сравнение типов.

Было:


|ГДЕ
|    ДенежныеСредстваУОбороты.Регистратор ССЫЛКА Документ.ПереводДС

Стало:


|ГДЕ
|    ТИПЗНАЧЕНИЯ(ДенежныеСредстваУОбороты.Регистратор) = ТИП(Документ.ПереводДС)

Этот способ не всегда решает проблему полностью, так как синтаксический анализатор все равно может споткнуться на самом факте использования поля Регистратор в параметрах виртуальной таблицы или в списке полей ВЫБРАТЬ. Однако для условий ГДЕ он может сработать.

2. Упрощение запроса и обработка в коде

Если по каким-то причинам захват всех регистраторов невозможен (например, их слишком много и это сильно утяжеляет расширение), можно пойти на компромисс, пожертвовав производительностью.

  1. Убираем "Регистратор" из запроса. Удалите периодичность "Регистратор" из параметров виртуальных таблиц и все упоминания этого поля из секций ВЫБРАТЬ, ГДЕ и СГРУППИРОВАТЬ ПО.
  2. Получаем более широкую выборку. Выполняем запрос и получаем данные без детализации до регистратора.
  3. Обрабатываем результат в коде 1С. Далее в цикле обходим результат запроса и для нужных записей выполняем дополнительную проверку или получаем данные регистратора отдельным запросом. Этот метод значительно медленнее, но является рабочим обходным путем.

3. Использование консоли запросов

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

4. Обновление платформы

Проблема была описана для платформы версии 8.3.14. Механизм расширений постоянно дорабатывается. В более свежих версиях платформы 1С:Предприятие многие подобные проблемы, связанные с доступом к метаданным, были решены. Если есть возможность, рассмотрите обновление платформы — это может избавить вас от необходимости выполнять все вышеописанные действия.

← На главную