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