Содержание:
1. Простая рекурсивная функция
1. Простая рекурсивная функция
При разработке в 1С иногда возникают задачи получения цепочки связанных друг с другом определенных элементов справочников или документов. Но, несмотря на довольно частое возникновение задач получения различных иерархической схемы данных, в 1С, к сожалению, не предусмотрены типовые механизмы для получения такого рода связанной информации. Для примера получения такой информации рассмотрим задачу получения в 1С 8.3 родителей всех элементов справочника Склады. Чтобы решить данную задачу, можно воспользоваться простой рекурсивной функцией, которая будет получать родителя выбранного элемента справочника в цикле, а на следующем этапе получать родителя полученного родителя элемента. Пример такой функции:
// Функция возвращает массив родителей элемента справочника, полученного на вход.
Функция ПолучитьМассивРодителейЭлемента(ЭлементСправочника)
МассивРодителейЭлемента = Новый Массив;
Пока ПустоеЗначение(ЭлементСправочника.Родитель) = 0 Цикл
МассивРодителейЭлемента.Добавить(ЭлементСправочника.Родитель);
ЭлементСправочника = ЭлементСправочника.Родитель;
КонецЦикла
Возврат МассивРодителейЭлемента;
КонецФункции
Данный метод может использоваться также и для получения всей цепочки документов-оснований списка документов, нужно только подставить вместо элемента справочника нужный нам документ, а вместо родителя проверять на заполненность вариант документа - основания.
2. Запрос в цикле
Хотя приведенная выше простая рекурсивная функция компактна и легка в написании, она имеет существенный для производительности недостаток – обращение через точку в цикле. При обращении каждую итерацию к серверу будут получены не только все ненужные реквизиты элемента справочника или документа, но и все табличные части, привязанные к данному элементу, что увеличит нагрузку на сервер и снизит производительность, получая с сервера большое количество ненужных данных. Например, если мы получаем документ-основание реализации, в которой тысяча строк, то все эти будут переданы с сервера на клиент. Нагрузку можно снизить, заменив обращение через точку выполнением запроса в цикле. В этом случае каждую итерацию цикла будем получать хотя бы только нужный нам реквизит. Но запрос в цикле тоже вещь очень плохая, так как инициирует многократное обращение к серверу, увеличивая время, затрачиваемое на работу цикла. Поэтому гораздо лучше не выполнять запрос в цикле, а создавать в цикле текст запроса, затем выполнить запрос с полученным текстом, получив все нужные данные с сервера только один раз. Рассмотрим пример запроса с динамическим формированием текста запроса в зависимости от уровня родителя справочника в 1С:
Функция ПолучитьМассивРодителейЭлемента (ЭлементСправочника)
МассивРодителейЭлемента = Новый Массив;
УровеньРодителя = ЭлементСправочника.Уровень();
ТекстОбъединить = "";
ТекстРодительЭлемента = "";
ТекстЗапросаВТ = "";
Для инд = 1 По УровеньРодителя Цикл
ТекстРодительЭлемента= ТекстРодительЭлемента+ ".Родитель";
Если инд<> 1 Тогда
ТекстОбъединить= "
|
| ОБЪЕДИНИТЬ ВСЕ
|";
КонецЕсли;
ТекстЗапросаВТ= ТекстЗапросаВТ+ ТекстОбъединить+ "
|ВЫБРАТЬ
| Склады" + ТекстРодительЭлемента+ " КАК Родитель
| ИЗ
| Справочник.Склады КАК Склады
| ГДЕ
| Склады.Ссылка = &ЭлементСправочника";
КонецЦикла;
Запрос = Новый Запрос;
Запрос.Текст = "
|ВЫБРАТЬ
| ВТ_СписокРодителей.Родитель КАК Родитель
|ИЗ
| (" + ТекстЗапросаВТ+ ") КАК ВТ_СписокРодителей";
Запрос.УстановитьПараметр("ЭлементСправочника", ЭлементСправочника);
ВыборкаЗапроса = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
МассивРодителейЭлемента.Добавить(Выборка.Родитель);
КонецЦикла;
Возврат МассивРодителейЭлемента;
КонецФункции
Если заранее известно точное значения уровня вложенности элемента справочника, то запрос можно составлять не динамически, а вручную, сразу указав нужное количество объединений таблиц.
Специалист компании «Кодерлайн»
Александр Суворов