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