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