Почему запрос работает в консоли, но возвращает пустой результат в коде модуля 1С?

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

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

Разбор ситуации: Ошибка в параметрах запроса

Проанализируем исходную ситуацию. Программист столкнулся с тем, что отчет в конфигурации «Бухгалтерия предприятия 3.0» не выводит данные. В коде выполнялся поиск дополнительных сведений (Водитель и Автомобиль) и их последующее использование в сложном запросе с левыми соединениями. Рассмотрим фрагмент кода, в котором была допущена критическая ошибка:


// Фрагмент кода из запроса автора
| ГДЕ
| (ВложенныйЗапрос.Водитель В (&Водитель)
| ИЛИ &Водитель = ЗНАЧЕНИЕ(Справочник.ФизическиеЛица.ПустаяСсылка))
| И (ВложенныйЗапрос.Автомобиль В (&Водитель) // ОШИБКА ЗДЕСЬ!
| ИЛИ &Автомобиль = ЗНАЧЕНИЕ(Справочник.Склады.ПустаяСсылка))

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

Важный вывод: В консоли запросов мы заполняем параметры вручную и видим их значения наглядно. В коде, особенно при использовании копирования похожих строк (copy-paste), глаз «замыливается», и такие логические ошибки пропускаются. Всегда проверяйте соответствие имен переменных в методе УстановитьПараметр и в тексте самого запроса.

Типичные причины расхождения результатов запроса

Если вы проверили имена параметров и они верны, но результат всё равно пустой, следует проанализировать ситуацию по шагам. Рассмотрим наиболее частые причины:

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

Оптимизация работы с дополнительными сведениями

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

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


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

// Заполнение параметров...

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

Рекомендации по отладке сложных запросов

Если вы столкнулись с проблемой «в консоли работает, а в коде — нет», выполните следующие действия:

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

Использование инструментов БСП

Поскольку работа ведется в конфигурации «Бухгалтерия предприятия 3.0», которая построена на базе «Библиотеки стандартных подсистем» (БСП), для получения дополнительных сведений эффективнее использовать штатные механизмы. Рассмотрим, как это можно сделать без написания собственных тяжелых запросов к регистру ДополнительныеСведения.

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

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

← На главную