Почему не выгружаются данные из запроса в таблицу значений на форме и как правильно использовать оператор ПОДОБНО?

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

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

Анализируем первую причину: Ошибки в формировании шаблона для оператора ПОДОБНО

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

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


// ОШИБКА: Добавление лишних кавычек
Запрос.УстановитьПараметр("ШаблонПоиска", "'%" + Наименование + "%'"); 

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

Правильный подход к формированию параметра:


НаименованиеДляПоиска = "Ессентуки";
// Формируем шаблон без лишних кавычек
Запрос.УстановитьПараметр("ШаблонПоиска", "%" + НаименованиеДляПоиска + "%");

В тексте самого запроса условие должно выглядеть следующим образом:


|ГДЕ
|   Номенклатура.Наименование ПОДОБНО &ШаблонПоиска

Разбираем логику соединения таблиц и фильтрации

Второй критический момент — это использование ЛЕВОЕ СОЕДИНЕНИЕ совместно с условием в секции ГДЕ. Посмотрим на структуру запроса: мы выбираем документы во временную таблицу, а затем присоединяем к ним табличную часть Товары. Если мы накладываем фильтр по номенклатуре в секции ГДЕ, наше "Левое соединение" превращается во "Внутреннее".

Проанализируем ситуацию: если в документе нет товара, подходящего под условие ПОДОБНО, вся строка (включая данные документа) будет отсечена из итоговой выборки. Если ваша задача — увидеть все документы, но только с определенными товарами, условие фильтрации необходимо переносить в секцию ПО (условие связи).

Пример оптимизированного соединения:


|ВЫБРАТЬ
|   ВыборкаПоступления.Ссылка КАК Документ,
|   ПоступлениеТовары.Номенклатура
|ИЗ
|   ВыборкаПоступления КАК ВыборкаПоступления
|       ЛЕВОЕ СОЕДИНЕНИЕ Документ.ПоступлениеТоваров.Товары КАК ПоступлениеТовары
|       ПО ВыборкаПоступления.Ссылка = ПоступлениеТовары.Ссылка
|       И ПоступлениеТовары.Номенклатура.Наименование ПОДОБНО &ШаблонПоиска

В таком варианте, если товар не найден, в поле Номенклатура будет стоять NULL, но сам документ из результата не исчезнет.

Проблема области видимости и выгрузки в таблицу значений

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

Проанализируем фрагмент кода:


Результат = Запрос.Выполнить();
Инфа = Результат.Выгрузить();

Если Инфа — это просто переменная внутри процедуры, то после завершения работы процедуры данные будут потеряны. Чтобы данные отобразились в таблице на форме, необходимо:

  1. Убедиться, что на форме создан Реквизит с типом ТаблицаЗначений.
  2. Если это управляемые формы, использовать метод ЗначениеВРеквизитФормы или загружать данные непосредственно в табличную часть объекта.
  3. Если мы работаем с таблицей значений, которая является реквизитом формы, необходимо использовать метод Загрузить.

Пример корректного отображения данных:


РезультатЗапроса = Запрос.Выполнить();
// Загружаем данные в реквизит формы (ТаблицаЗначений)
ЭтаФорма.ТЗ_ДанныеНаФорме.Загрузить(РезультатЗапроса.Выгрузить());

Работа с периодами дат: ловушка границ

Посмотрим на то, как задаются границы периода. В 1С тип Дата всегда содержит время. Если вы передаете в параметр запроса дату без указания времени (например, '20210101'), 1С трактует это как начало дня — 00:00:00.

Разберем пример из практики: КонДата = НачалоДня(Дата('20210101')); Если документ был создан 1 января 2021 года в 10 утра, он не попадет в выборку МЕЖДУ, так как его время больше, чем 00:00:00.

Рассмотрим золотое правило работы с периодами:

Использование КонецДня для начальной даты (как в рассматриваемом случае) приведет к потере всех документов, созданных в течение первого дня периода.

Методика отладки "пустых" запросов

Если вы столкнулись с тем, что запрос ничего не возвращает, рекомендуем следовать проверенному алгоритму:

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

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

← На главную