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