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

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

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

Диагностика: почему цикл обхода выборки не выполняется

Первый шаг при поиске проблемы — проверка выполнения запроса через отладчик. Если при пошаговой отладке указатель сразу переходит со строки Пока Выборка.Следующий() Цикл на КонецЦикла, это означает, что РезультатЗапроса пуст (содержит 0 строк).

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

  1. Несовпадение типов параметров. В консоли запросов разработчик часто указывает параметры вручную (например, строкой или конкретной датой). В коде же в параметр &Дата передается значение реквизита формы. Если в запросе выполняется условие франПериоды.Наименование = &Дата, а стандартный реквизит Наименование является строкой, передача значения с типом Дата приведет к тому, что условие никогда не выполнится.
  2. Некорректная конкатенация в условии ПОДОБНО. Склеивание спецсимволов "%" непосредственно в тексте запроса ухудшает читаемость и может приводить к ошибкам синтаксиса. Корректный подход — передавать готовую строку поиска целиком в параметр запроса.
  3. Неявное декартово произведение таблиц (CROSS JOIN). Если в секции ИЗ таблицы перечислены через запятую без явного соединения, отсутствие хотя бы одной подходящей строки во второй таблице полностью обнуляет итоговый результат выборки.

Исправление передачи параметров и условий запроса

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


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	франПодписка.Контрагент КАК Контрагент,
    |	ВЫРАЗИТЬ(франПодписка.Комментарий КАК СТРОКА(150)) КАК Комментарий,
    |	франПериоды.Наименование КАК ПериодНаименование,
    |	франВидыПодписок.Ссылка КАК ВидПодписки
    |ИЗ
    |	Документ.франПодписка КАК франПодписка
    |		ЛЕВОЕ СОЕДИНЕНИЕ Справочник.франВидыПодписок КАК франВидыПодписок
    |		ПО франПодписка.ВидПодписки = франВидыПодписок.Ссылка
    |		ЛЕВОЕ СОЕДИНЕНИЕ Справочник.франПериоды КАК франПериоды
    |		ПО франПодписка.Период = франПериоды.Ссылка
    |ГДЕ
    |	франПодписка.Комментарий ПОДОБНО &ИмяСотрудника
    |	И франПериоды.Наименование = &ПериодНаименование";

// Формируем строковый параметр для условия ПОДОБНО
Запрос.УстановитьПараметр("ИмяСотрудника", "%" + СокрЛП(ИмяСотрудника) + "%");

// Если поиск идет по строковому наименованию периода, приводим дату к строке нужного формата:
Запрос.УстановитьПараметр("ПериодНаименование", Формат(Дата, "ДФ=dd.MM.yyyy"));

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

Исправление ошибки сопоставления полей выборки

Обратим внимание на частую логическую ошибку при ручном заполнении строк в цикле. В исходном коде реквизиту строки Контрагент присваивалось поле Выборка.Ссылка, которое соответствовало виду подписки, а не контрагенту:


// Ошибочный вариант:
НоваяСтрока.Контрагент = Выборка.Ссылка;

// Корректный вариант:
НоваяСтрока.Контрагент = Выборка.Контрагент;

Для исключения подобных опечаток и ускорения разработки рекомендуется использовать процедуру ЗаполнитьЗначенияСвойств. Она автоматически сопоставляет одноименные поля выборки и колонки табличной части:


Список.Очистить();

Выборка = РезультатЗапроса.Выбрать();
Пока Выборка.Следующий() Цикл
    НоваяСтрока = Список.Добавить();
    ЗаполнитьЗначенияСвойств(НоваяСтрока, Выборка);
КонецЦикла;

Оптимальный способ: заполнение через метод «Загрузить»

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

Разберем готовый оптимизированный пример:


Процедура СформироватьНажатие(Элемент)
    
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |	франПодписка.Контрагент КАК Контрагент,
        |	ВЫРАЗИТЬ(франПодписка.Комментарий КАК СТРОКА(150)) КАК Комментарий,
        |	франВидыПодписок.Ссылка КАК ВидПодписки
        |ИЗ
        |	Документ.франПодписка КАК франПодписка
        |		ЛЕВОЕ СОЕДИНЕНИЕ Справочник.франВидыПодписок КАК франВидыПодписок
        |		ПО франПодписка.ВидПодписки = франВидыПодписок.Ссылка
        |		ЛЕВОЕ СОЕДИНЕНИЕ Справочник.франПериоды КАК франПериоды
        |		ПО франПодписка.Период = франПериоды.Ссылка
        |ГДЕ
        |	франПодписка.Комментарий ПОДОБНО &ИмяСотрудника
        |	И франПериоды.Наименование = &ПериодНаименование";
    
    Запрос.УстановитьПараметр("ИмяСотрудника", "%" + СокрЛП(ИмяСотрудника) + "%");
    Запрос.УстановитьПараметр("ПериодНаименование", Формат(Дата, "ДФ=dd.MM.yyyy"));
    
    РезультатЗапроса = Запрос.Выполнить();
    
    Если Не РезультатЗапроса.Пустой() Тогда
        ТаблицаРезультата = РезультатЗапроса.Выгрузить();
        Список.Очистить();
        Список.Загрузить(ТаблицаРезультата);
    Иначе
        Список.Очистить();
        Предупреждение("По заданным условиям данные не найдены.");
    КонецЕсли;
    
КонецПроцедуры

Важный момент: при использовании метода Загрузить имена псевдонимов в блоке ВЫБРАТЬ запроса должны строго совпадать с именами колонок табличной части Список.

← На главную