Как получить всю номенклатуру из родительских папок на основании таблицы значений в 1С

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

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

Способ 1. Использование временной таблицы и вложенного подзапроса

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

Разберем пакетный запрос по шагам:

  1. Помещаем таблицу значений ТаблицаЗаказа во временную таблицу втТаблица.
  2. Во втором запросе выбираем элементы справочника Справочник.Номенклатура, добавляя условие фильтрации ГДЕ Номенклатура.Родитель В (...) с подзапросом к временной таблице.

Посмотрим на пример реализации в коде 1С:


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

Запрос.УстановитьПараметр("Таблица", ТаблицаЗаказа.Выгрузить());
Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать();

Пока Выборка.Следующий() Цикл
	Сообщить(Выборка.Ссылка);
КонецЦикла;

Если требуется получить элементы не только первого уровня вложенности, но и всю иерархию подпапок, вместо оператора В применяется оператор В ИЕРАРХИИ.

Способ 2. Подготовка массива родителей на стороне 1С

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

Разберем по шагам алгоритм действия:

  1. Добавляем в исходную таблицу значений колонку Родитель и заполняем её значениями Стр.Номенклатура.Родитель.
  2. Сворачиваем таблицу значений по колонке Родитель для получения уникальных групп.
  3. Выгружаем колонку в массив через метод ВыгрузитьКолонку() и передаем параметром в запрос.

Посмотрим на пример кода:


ТЗ = ТаблицаЗаказа.Выгрузить();
ТЗ.Колонки.Добавить("Родитель");

Для Каждого Стр Из ТЗ Цикл
	Стр.Родитель = Стр.Номенклатура.Родитель;
КонецЦикла;

ТЗ.Свернуть("Родитель");

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

Запрос.УстановитьПараметр("Родители", ТЗ.ВыгрузитьКолонку("Родитель"));
Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать();

Пока Выборка.Следующий() Цикл
	Сообщить(Выборка.Ссылка);
КонецЦикла;

Причины получения пустой выборки и ошибки обхода

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

  1. Пропуск вызова метода Выбрать(): После выполнения Запрос.Выполнить() необходимо обязательно инициализировать выборку командой Выборка = Результат.Выбрать(). Если обратиться к старой выборке из предыдущего шага, цикл обхода не выполнится.
  2. Несоответствие имен полей: Если в тексте запроса указано поле Номенклатура.Ссылка КАК Ссылка, а в цикле обращения производится к несуществующему полю (например, Выборка.СсылкаНоменклатура), платформа возвращает неопределенное значение или ошибку обращения к свойству.
  3. Пустые значения родителей: У элементов верхнего уровня справочника свойство Родитель может содержать пустую ссылку. При поиске по пустой ссылке результатом выборки также будет пустой список.
← На главную