Почему ВыполнитьПакетСПромежуточнымиДанными возвращает пустой результат в отладчике, а в консоли данные есть?

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

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

Суть проблемы и работа метода

Метод ВыполнитьПакетСПромежуточнымиДанными появился в платформе 8.3.10 и стал незаменимым инструментом. В отличие от стандартного ВыполнитьПакет, который возвращает массив результатов только для инструкций ВЫБРАТЬ, новый метод возвращает результаты для всех частей пакета, включая те, где данные помещаются во временные таблицы (ПОМЕСТИТЬ).

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

Различие в контексте исполнения и типах параметров

Первая и самая частая причина — неявное различие в типах передаваемых параметров. В коде конфигурации параметр может иметь тип ДокументОбъект, в то время как запрос ожидает ДокументСсылка. Хотя 1С часто выполняет автоматическое приведение типов, при работе с временными таблицами и левыми соединениями это может привести к тому, что условие связи ПО не сработает.

Рассмотрим пример запроса из обсуждения:


ВЫБРАТЬ &ДокОтгрузки КАК Ссылка 
ПОМЕСТИТЬ ВТ_ДокументыОтгрузки ; 

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ РАЗЛИЧНЫЕ 
    ЕСТЬNULL(ХозрасчетныйСубконто.Значение, НЕОПРЕДЕЛЕНО) КАК Партия 
ПОМЕСТИТЬ ВТ_Партии 
ИЗ ВТ_ДокументыОтгрузки КАК ВТ_ДокументыОтгрузки 
ЛЕВОЕ СОЕДИНЕНИЕ РегистрБухгалтерии.Хозрасчетный.Субконто КАК ХозрасчетныйСубконто 
    ПО ВТ_ДокументыОтгрузки.Ссылка = ХозрасчетныйСубконто.Регистратор 
    И (ХозрасчетныйСубконто.ВидДвижения = ЗНАЧЕНИЕ(ВидДвиженияБухгалтерии.Кредит)) 
    И (ХозрасчетныйСубконто.Вид = ЗНАЧЕНИЕ(ПланВидовХарактеристик.ВидыСубконтоХозрасчетные.Партии)) 
ИНДЕКСИРОВАТЬ ПО Партия ;

Для исключения ошибок типизации в первой части пакета рекомендуется использовать явное приведение типа через функцию ВЫРАЗИТЬ или обращение к реальной таблице базы данных. Посмотрим на два варианта исправления:

  1. Использование выражения: ВЫБРАТЬ ВЫРАЗИТЬ(&ДокОтгрузки КАК Документ.РеализацияТоваровУслуг) КАК Ссылка ПОМЕСТИТЬ ВТ_ДокументыОтгрузки
  2. Выборка из существующей таблицы: ВЫБРАТЬ таблица.Ссылка КАК Ссылка ПОМЕСТИТЬ ВТ_ДокументыОтгрузки ИЗ Документ.РеализацияТоваровУслуг КАК таблица ГДЕ таблица.Ссылка = &ДокОтгрузки

Синхронизация параметров через XML

Чтобы исключить влияние человеческого фактора при ручном заполнении параметров в консоли, воспользуемся методом выгрузки запроса в XML. В современных конфигурациях на базе БСП (Библиотеки стандартных подсистем) существует функция, позволяющая получить полную структуру запроса со всеми установленными значениями параметров.

Проанализируем шаги для точной отладки:

  1. В точке останова (перед выполнением запроса) вычислите выражение: ОбщегоНазначения.ЗапросВСтрокуXML(Запрос)
  2. Скопируйте полученную XML-строку.
  3. Откройте консоль запросов БСП (входит в состав инструментов разработчика или доступна в меню "Еще" некоторых документов).
  4. Используйте команду "Заполнить из XML" или "Загрузить из XML".

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

Транзакционный контекст и RLS

Метод ВыполнитьПакетСПромежуточнымиДанными часто запускается внутри транзакции проведения документа. В этот момент данные в регистре (например, РегистрБухгалтерии.Хозрасчетный.Субконто) могут быть уже изменены или помечены к удалению, но еще не зафиксированы. Консоль запросов, запущенная параллельно, работает в другом сеансе и может не видеть "грязных" данных текущей транзакции.

Также не стоит забывать про RLS (Record Level Security). В коде запрос выполняется от имени пользователя с ограниченными правами. Метод ВыполнитьПакетСПромежуточнымиДанными честно учитывает эти ограничения. Если консоль запросов запущена под полными правами, результат ожидаемо будет отличаться.

Особенности работы с Менеджером временных таблиц

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

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

Запрос.МенеджерВременныхТаблиц.Таблицы[0].ПолучитьДанные().Выгрузить()

Важно помнить, что индекс таблицы соответствует порядку её создания в пакете. Если в табло менеджер отображается как Неопределено, значит, он не был назначен объекту запроса явно, и временные таблицы существуют только внутри области видимости метода Выполнить.

Использование левых соединений и ЕСТЬNULL

Проанализируем конструкцию ЕСТЬNULL(ХозрасчетныйСубконто.Значение, НЕОПРЕДЕЛЕНО). В контексте запросов 1С НЕОПРЕДЕЛЕНО является литералом определенного типа. Если левое соединение не находит соответствия в правой таблице, поле ХозрасчетныйСубконто.Значение становится NULL. Замена NULL на НЕОПРЕДЕЛЕНО может привести к тому, что в дальнейшем фильтры по этой колонке в последующих частях пакета не сработают так, как ожидается, если там сравнивается с пустой ссылкой или другим типом.

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

Рекомендации по стабильной отладке

Для минимизации "чудес" при отладке пакетных запросов придерживайтесь следующих правил:

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

← На главную