Ситуация, когда один и тот же текст запроса с идентичными (на первый взгляд) параметрами выдает разные результаты в консоли запросов и в программном модуле — это классическая проблема, с которой сталкиваются даже опытные разработчики. Особенно часто это проявляется при работе со сложными механизмами, такими как Регламентированная отчетность. Проанализируем причины этого явления и разберем по шагам, как найти "утечку" данных.
Первое, что мы должны проверить — это реальное значение параметров, передаваемых в запрос. Рассмотрим ситуацию, описанную в практике: в справочнике контрагентов существует "битая ссылка". В отладчике 1С при просмотре значения такая ссылка может отображаться как Объект не найден, а программно при определенных условиях превращаться в Неопределено.
Выясним причину, почему это критично. В консоли запросов, когда мы заполняем параметры вручную, мы обычно выбираем пустую ссылку конкретного типа (например, Справочники.Контрагенты.ПустаяСсылка()). Однако в коде алгоритм может подставить Неопределено. Для языка запросов 1С это принципиально разные сущности.
Проанализируем пример кода, который может приводить к ошибке:
// Опасный момент: если ссылка битая, результат может быть непредсказуемым
ПараметрОрганизация = Справочники.Организации.НайтиПоКоду("00001");
Если ПараметрОрганизация.Пустая() Тогда
// Здесь может оказаться Неопределено, если объект не найден в базе физически
КонецЕсли;
Запрос.УстановитьПараметр("Организация", ПараметрОрганизация);
Если в консоли вы подставите Пустую ссылку, запрос отработает по условию ГДЕ Организация = &Организация. Если же в коде придет Неопределено, условие не выполнится, и вы получите пустой результат. Всегда проверяйте типы данных функцией ТипЗнч() непосредственно перед выполнением запроса в отладке.
Одной из самых неочевидных причин является ограничение прав доступа на уровне записей. Рассмотрим, как это работает. Консоль запросов чаще всего запускается под пользователем с полными правами (Администратор) или в режиме толстого клиента, где ограничения могут не действовать.
Программный код регламентированного отчета часто выполняется в контексте конкретного пользователя. Если в запросе не указано ключевое слово РАЗРЕШЕННЫЕ, а у пользователя нет прав на чтение хотя бы одной таблицы, участвующей в соединении, запрос в коде вернет пустой результат (или вызовет ошибку), в то время как в консоли под администратором данные будут.
Разберем, как правильно модифицировать запрос для проверки:
// В консоли мы пишем:
ВЫБРАТЬ * ИЗ РегистрНакопления.Продажи
// В коде для безопасности и учета прав:
ВЫБРАТЬ РАЗРЕШЕННЫЕ * ИЗ РегистрНакопления.Продажи
Если после добавления РАЗРЕШЕННЫЕ результат в консоли стал пустым — значит, дело в правах доступа.
В сложных отчетах запросы редко бывают одиночными. Часто используется МенеджерВременныхТаблиц. Посмотрим на ситуацию: вы копируете текст последнего запроса из пакета в консоль. Но этот запрос обращается к временным таблицам, которые были созданы ранее.
Если вы не переносите в консоль весь пакет запросов, создающий эти таблицы, или если МенеджерВременныхТаблиц в коде очищается до момента выполнения финального запроса, данные будут потеряны. Выясним, не теряется ли контекст менеджера между вызовами процедур в модуле отчета. Для корректной отладки используйте Инструменты разработчика, которые позволяют выгрузить все содержимое временных таблиц прямо из памяти сервера.
Если отчет построен на базе СКД, то текст запроса в конфигураторе — это лишь "черновик". В момент выполнения система компоновки динамически изменяет его:
Рассмотрим пример: в СКД установлен отбор по периоду или организации на уровне настроек компоновщика. В коде вы видите "чистый" запрос, а платформа при выполнении добавляет условие ГДЕ.... Чтобы увидеть реальный текст, который уходит на СУБД, необходимо вызывать метод ИсполняемыйТекстЗапроса или использовать замер производительности/трассировку SQL.
Современные конфигурации (на базе БСП) активно используют функциональные опции. Если в запросе используется условие, зависящее от функциональной опции (например, УчетПоСтатьямДДС), и эта опция выключена, 1С может автоматически "обрезать" результаты запроса.
Также проверим параметры сеанса. Например, параметр ТекущаяОрганизация может быть не инициализирован в фоновом задании, которое формирует отчет. В консоли этот параметр заполнен вашим текущим значением, а в серверном контексте выполнения отчета он пуст. Это приводит к тому, что условия в соединениях или блоке ГДЕ отсекают все строки.
Чтобы окончательно решить проблему, рекомендуем следовать данному алгоритму:
ТипЗнч(Параметр) для каждого параметра запроса и сравните его с типом параметра в консоли.Менеджером временных таблиц прямо из контекста выполнения кода.'00010101000000'. В консоли пустая дата часто интерпретируется как отсутствие фильтра, а в реальном запросе — как конкретный (минимальный) момент времени.Параметр.Ссылка.ВерсияДанных вызывает ошибку или объект не отображается в списке, это "битая ссылка". Ее нужно предварительно обрабатывать перед передачей в запрос.Подводя итог, помните: чудес в программировании 1С не бывает. Если консоль выдает результат, а код — нет, значит, существует различие в контексте исполнения (права, параметры сеанса) или в физическом типе передаваемых значений. Тщательный анализ типов данных через табло отладки — ваш главный инструмент решения этой задачи.