1с скопировать справочник с иерархией

Обновлено: 04.07.2024

Как скопировать иерархический справочник?

Доброго времени суток!
Имеется иерархический справочник. Необходимо скопировать одну из его групп, со всеми вложенными элементами и уровнями.

Под семерку нашел пример:


//************************************************** ***** Процедура КопированиеГруппСпр ( СпрТекГруппа , СпрНовГруппа ) СпрНом = СоздатьОбъект ( "Справочник.Номенклатура " ) ; НовГр = СоздатьОбъект ( "Справочник.Номенклатура " ) ; СпрНом . ИспользоватьРодителя ( СпрТекГруппа ) ; СпрНом . ВыбратьЭлементы ( 1 ) ; Пока СпрНом . ПолучитьЭлемент ( 1 ) > 0 Цикл Если ( СпрНом . ЭтоГруппа ( ) = 1 ) и ( СпрНом . Уровень ( ) - 1 = СпрТекГруппа . Уровень ( ) ) Тогда Сообщить ( СпрНом ) ; НовГр . ИспользоватьРодителя ( СпрНовГруппа ) ; НовГр . НоваяГруппа ( ) ; НовГр . Наименование = СпрНом . Наименование ; НовГр . Записать ( ) ; КопированиеГруппСпр ( СпрНом , НовГр ) ; КонецЕсли ; КонецЦикла ; КонецПроцедуры //************************************************** **** Процедура Сформировать ( ) КопированиеГруппСпр ( СпрТекГруппа , СпрНовГруппа ) ; КонецПроцедуры //************************************************** **** Где:СпрТекГруппа - группа справочника откуда нужно выполнять переносСпрНовГруппа - группа справочника куда нужно выполнять перенос

Попытался переделать его под восьмерку, но пока ничего не выходит :(

Вот что получилось:


Перем СпрТекГруппа , СпрНовГруппа ; Процедура КнопкаВыполнитьНажатие ( Кнопка ) СпрТекГруппа = Справочники . Номенклатура . НайтиПоКоду ( "0 11" ) ; КопированиеГруппСпр ( СпрТекГруппа , СпрНовГруппа ) ; КонецПроцедуры Процедура КопированиеГруппСпр ( СпрТекГруппа , СпрНовГруппа ) СпрНом = Справочники . Номенклатура ; НовГр = Справочники . Номенклатура ; ; Выборка = СпрНом . Выбрать ( СпрТекГруппа ) ; Пока Выборка . Следующий ( ) Цикл //Если (Выборка.ЭтоГруппа() = 1) и (Выборка.Уровень() - 1 = СпрТекГруппа.Уровень()) Тогда Если ( Выборка . ЭтоГруппа ) Тогда Сообщить ( СпрНом ) ; НовЭл = НовГр . СоздатьГруппу ( ) ; //НовЭл.Родитель(СпрНовГрупп а); НовЭл . Наименование = Выборка . Наименование ; НовЭл . Записать ( ) ; Сообщить ( НовЭл . Код ) ; КопированиеГруппСпр ( Выборка , НовЭл ) ; КонецЕсли ; КонецЦикла ; КонецПроцедуры
Цикл проходит один раз, создается новая группа и уже на втором кругу цикла вываливает ошибку:


: Ошибка при вызове метода контекста ( Выбрать ) : Несоответствие типов ( параметр номер ' 1 ' ) Выборка = СпрНом . Выбрать ( СпрТекГруппа ) ; по причине:Несоответствие типов ( параметр номер ' 1 ' )
Да и с условием этим


Если ( Выборка . ЭтоГруппа ( ) = 1 ) и ( Выборка . Уровень ( ) - 1 = СпрТекГруппа . Уровень ( ) )
я никак не разберусь :(

(7) Улыбнуло :) 1C. Конфигуратор. Но, как бы, там нет голосового помощника, который по запросу "нужен оброботка файл Копирование группы Контрагенты с иерархией вложенных элементов" создаст необходимую обработку. Если Вы не знаете, как создаются обработки, то прям "срочно" вряд ли сможете написать.

(8) Да ладно, на Мисте зареган - можно идти ЕРП внедрять, по 4500 в час))

(0) а подчиненные/зависимые справочники - с ними что при копировании делать?

(0) Тебе надо КД 2. До утра сможешь разобраться и все сделать. Ютуб в помощь. И подчиненные справочники туда же.

3) база-приемник: запускаем обработку, натравливаем на xml-файл (см.п.2), загружаем.

(11)(12) Не факт, что речь про перенос данных из одной базы в другую. Я это понял как то, что человеку зачем-то нужна копия группы в контрагентах с иерархией(то-ли только папки, то ли и элементы). Но я этот вывод сделал на основании слов "копировать" и "обработка". Мой семантический анализатор не заменил их на "перенос данных" :)

Да-да -да..дайте ТС какую-нить г..поделку, потом будет тема про 6000000 вложенных групп..
:)

(17) Где использование РодительКопирования? (В отборе выборки, что логично).
Не учтено, что при копировании нужно и иерархичность копировать (копия родителя элемента должна быть родителем копии элемента).

Когда я нажимаю кнопку «Копировать», я хочу, чтобы она копировала элементы и папки в папке, которую я щелкнул.
Простите за мой русский. Буду рад, если вы мне поможете.

(14) +1
(17) и что конкретно не получилось? там еще много чего (возможно) надо проставить, кроме кода и наименования

копирование сработало. но он скопировал все элементы, а не только выбранную мной папку, и не выгружал элемент в папку

(22) не пойдет, сделай свою, стандартная кнопка для стандартного копирования

(23) Так у тебя ВыбратьИерархически без отбора и значение Родитель не копируется. (18)

(26)я бы не стал путать стандартный с своими фантазиями, либо стандартное поведение надо отключить, а стнадартнойобработки там нет. стандартное поведение не записывает копируемый объект, только по кнопке ОК, поэтому "вохмоэного" родителя на момент создания/записи всей иерархии еще не будет

Не получится, в ПриКопировании нет нового объекта, РодительКопирования - объект с которого копируется, а не новый, который копируется. Он появится только вместе с формой нового элемента/группы. Создать программно свою новую ссылку, заполнить всю иерархию и тд можно, но от появления стандартного окна нового элемента похоже не избавиться. Так что сделай свою кнопку, постановщику задачи скажи что нибудь интересное.
пс. я смотрел на ОФ, может конечно в УФ что то по другому происходит

Можно попробовать скопировать иерархию после записи, опираясь на доп свойства, заполненные при копировании.

можно, но будет сложно для тс да и спалится на задании

mne nada tolko 1 raz. 1 papka est i papka est 5000+ kontragent. xo4y kopirovat eto papka

тогда не надо это лепить в ПриКопировании, обработка, в ней кнопка, на ней этот код + все советы dubolom с (18)

правда будут еще тонкости с иерархией и определением нужного родителя

Уже почти 50 и еще никто не спросил "зачем"? И не сказал "тебе это не надо"? Непорядок!

Оптимист верит, что мы живем в лучшем из миров. Пессимист боится, что так оно и есть.

.
Неожиданно для нас
Он устроил мастер класс.

Звдание: Впишите недостающую строку.

Если ничего не хочется делать - можно взять эту функцию из конвертации данных

(3) это явно интереснее очередного задротства фиксина.

тут юзеры по одному элементу копируют и такого воротят, что же начнется когда папками копировать будут?
(4) Смысл этой функции рассскажи?
вот первый идиотский вариант:
записать элемент в процедуре ПриКопировании и скопировать подчиненные элементы. Работает криво.
вот второй идиотский вариант:
создать подчиненные элементы, используя сцылку нового. Не работает вообще.

(8) Конфигурация КД сделана на подчиненных справочниках, есть возможность копировать правила с подчиненными и заменять влядельца (есть правила для одной конвертации - такие же будут для другой)

что вы на человека наезжаете? Гений хочет с общественностью поделиться опытом и знаниями, а вы все опохабите.
(13) по кнопочке Ф9! При чем здесь конвертация?
(16) я хочу проверить, есть ли тут не дятлы?
(17) жалко на мисте плюсиков нет. на инфостарте он их любит клянчить.
(13) как скопировать с подчиненными я знаю, там нюанс в другом - когда вызывается ПриКопировании, ссылки еще нет.
что-то у меня никаких идей.
скажем чтобы просто в справочнике можно было интерактивно скопировать несколько элементов а не один, то можно для списка поставить множественное выделение, ну и само собой обработку.
А чтобы скопировать с подчиненными справочниками? Ну просто аккуратно перебрать каждый и создать новые подчинив их скопированному
(18) подменить F9 несложно, главное, чтобы была функция, умеющая правильно копировать. В КД она есть. Я для себя ее брал. Возможно можно написать и более оптимально. Поскольку код функции от 1С известен - можно сравнить, что лучше. У меня обычно не хватает времени. Она точно работает.
(11) Врядли, скорее всего через УстановитьСсылкуНового и в транзакции.
(21) а далее, далее, ПриКопировании у объекта нет ссылки. Допустим юзверь нажал Ф9, потом отказался, а элементы уже созданы. Мозгами шевели, умник, при чем здесь приКопировании
(23) Писать не просят, просят идею. А я скажу, да блин, у меня так и сделано. Или - не чувак, у меня круче. Ибо круче чем у меня быть не может однозначно. У меня идеально сделано.

(25)
Не по ссылке нового.
Вот в 1це пишу, кстати.
В справочнике пимВалюты поставил обработчики:

<pre>
На выходе имею:

Что за бред, почему ссылка нового не поддерживается?

А если при копировании сохранять объект копирования и признак копирования, а подчиненные уже ПослеЗаписи() фигачить?
2(26) Можно все в транзакцию завернуть.. ну так, в порядке бреда.
В подписке ссылка уже есть, т.к. ПриЗаписи в объекте уже отработано
чё то я не догоняю, как соотносится тема и "Писать не просят, просят идею. ". Кто кого просит?

(32) Не гони, в ПриКопировании элемента еще нет.
(34) Не, там тоже объекта еще нет. К тому же это на уровне формы, а я на уровне объекта сделал.
(31) В порядке бреда если только.

У меня красивое решение. ДУМАЙТЕ, ДЯТЛЫ!

(37) вот загнул? А оно нам надо, в пятницу. под вечер - ДУМАТЬ!

Сказал бы в среду, до обеда, можно было бы и подумать, а так - есть что сказать - ГОВОРИ. нет, дык нефиг народ баломутить.

>>> У меня красивое решение. ДУМАЙТЕ, ДЯТЛЫ!
епт, это уже комплексы видать. )))
(39) Ну комплексы не комплексы, а до 38 го поста дошли, решения еще не придумали. Кто вы после этого? ;-)

может я чего не понимаю.

вот из БП кусок. форма элемента спр. Валюты

Фиксин, опять изобрел велосипед с квадратными колесами, после употребления очередной дозы мухоморов
предупреждаю, по аккуратней в выражениях, а то тебя и опустить могут
осталось только применить это к нашему случаю - и вуаля.
Но копировать нужно только при копировании, а не вдругих случаях! ;-)
(48) Какой нафиг горячо.
Выдрал код из рабочей базы 3 летней давности

(49) В коде (43) есть изюминка - Записать(); в процедуре ПриЗаписи()

Зачем можешь объяснить?

смотрб в отладчике в модуле объекта ПередЗаписью - пустота.
смотрю в ПриЗаписи - есть ссылка.

У меня какой-то другой отладчик?

(54) может в программу Мастер-Класс входит перекомпиляция ядра, но Гений считает что люди к этому не готовы?
(56) ты при создании элемента копированием сразу его записываешь?
(58) из (0) следовало несколько другое, имхо:
<нужно чтобы когда пользователь создавал элемент справочника А копированием (F9), при этом копировались все подчиненные элементы>
При копировании юзверем соответственно откроется форма элемента справочника в которой будет доступно ПараметрОбъектКопирования. Остальное можно запхнуть в процедуру ПослеЗаписи(). Какие еще извращения требуются?
+61 при редактировании в диалоге соответственно. Извращаться придется только при редактивовании в списке.
Хотя в списке есть процедура ПередНачаломДобавления(Отказ>, <Копирование>, <Родитель>, <Группа>) - в которой можно отследить факт копирования. Остается только выяснить - можно ли здесь отловить объект копирования и ссылку на добавляемый элемент справочника. Но с этим нет времени возиться.
Короче при копировании элемента всяко будет работа с формами - как- то здесь все это упущено вместе с событиями форм.

особенно в гениТальном решении мне понравился блок:

хотя ситуацию с родителем надо конечно обрабатывать отдельно
(0) Да это фигня. Я вот очень удивился когда выяснил что в снеговике так же как и в клюшках нельзя делать групповые операции с элементами справочников, списков и т.д. Например мы выбираем мышью при нажатом Ctrl ряд объектов и они все охренительно выделены (вот прогресс!), потом я могу одним движением (. ) руки всех их пометить на удаление, перести в другую группу и т.д. Этого до сих пор почему то нет. Подумай над тем как это сделать, а потом устрой тут мастер-класс. :)
(66)наверно я что-то не понял, при множественном выделении работает множественная пометка на удаление и перенос в другую группу штатными методами
(66) э-э-э, как только ставим режим выделения "Множественный" - так сразу это работает
я лично записывал элемент, а потом если пользователь отказ делал при выборе - удалял его.
(69)при копировании подчиненного иерархического справочника необходимо менять ссылки на родителя в подчиненных эмлементах чтобы не получилось, что у родителя и дочернего элемента владельцы разные
(67)(68) У меня не работает. Что я делаю не так?
(Запуская конфу. )
Иногда создается впечатление, что под ником Гений 1С пишут все кому не лень.
(61) отрабатывать события на уровне формы - это не наш метод. К тому же если пользователь щелкнет записать дважды в одной форме, нужно чтобы во второй раз подчиненные элементы не скопировались.
(72) перетаскивать в группу можно если разрешить драг и дроп, тогда писать ничего не надо. НАсчет групповой пометки на удаление не знаю - а что, сложно кнопку с обработчиком повесить? Для каждого Эл из ВыделенныеЭлементы и т.п.

(75)да, опечатка, но это не дает тебе право меня оскорблять

По ходу Фиксин наконец-то открыл для себя методы ПолучитьСсылку() и УстановитьСсылкуНового() :))
(77) Ну почему же. Повод дает. Про метод Скопировать() я забыл, чесгря.

открыл карточку фиксина на инфостаре и офигел рейтинг за 800. и 4 страници ссылок на его опусы (большенство по 5-10 плюсов) то есть ни кому нафиг не нужны. Наверно если писать статьи копированием из синтаксиса помошника можно больше заработать!

Сергей, тебе самому не стыдно такие вещи публиковать? Ведь я уверен, что среди твоего мусора наверно есть и стоящие вещи, только своими гЕниальными мелочами ты только хуже себе делаешь.

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

Как вариант можно перебрать родителей через ИЛИ, например так


Номенклатура.Родитель = Номенклатура1.Ссылка
ИЛИ Номенклатура.Родитель.Родитель = Номенклатура1.Ссылка
ИЛИ Номенклатура.Родитель.Родитель.Родитель = Номенклатура1.Ссылка
ИЛИ Номенклатура.Родитель.Родитель.Родитель.Родитель = Номенклатура1.Ссылка


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

Это мое первое сочинение для Инфостарта

В запросе, в соединении нельзя указать например: ЛЕВОЕ СОЕДИНЕНИЕ . Ссылка В ИЕРАРХИИ(ТЗ.Ссылка )

Внизу приведены процедуры, которые позволяют все же сравниться с иерархией

идея в том что бы подготовить такую таблицу значений, где была бы информация



Первая колонка Вторая колонка

Родитель Родитель.Родитель

Родитель Родитель.Родитель.Родитель

и так далее для каждой группы в первой колонке, всег вышестоящие группы во второй

и использовать это для этой задачи

Где можно будет указать . СОединение Номенклатура.Родитель = ТЗ.Родитель и далее обрабатывается

условие с Вышестоящими родителями

итак процедуры

/// это основная процедура где и нужно произвести соединение по иерархии

Процедура КнопкаВыполнитьНажатие ( Кнопка )

М = Новый МенеджерВременныхТаблиц ;

Запрос = Новый Запрос ;
Запрос . УстановитьПараметр ( "Номенклатура" , Номенклатура );

ПолучитьНаборРодителей ( М );
Запрос . МенеджерВременныхТаблиц = М ;

// это конечно можно сразу в условии ГДЕ в ИЕРАРХИИ решить
// это просто пример
Запрос . Текст =

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

РЕзультат = Запрос . Выполнить (). Выгрузить ();
ЭлементыФормы . ТЗ_1 . Значение = Результат . Скопировать ();


// Эти две процедуры создают ТЗ с группами

// первая процедура выбирает все группы

// вторая заполняет ТЗ вышестоящими родителями для родителя первой колонки

Процедура ПолучитьНаборРодителей ( МенВремТаблиц )


НовТЗСоВсемиРодителями = Новый ТаблицаЗначений ;
ТипНоменклатура = Новый ОписаниеТипов ( "СправочникСсылка.Номенклатура" );
НовТЗСоВсемиРодителями . Колонки . Добавить ( "ПервыйРодитель" , ТипНоменклатура );
НовТЗСоВсемиРодителями . Колонки . Добавить ( "РодительГдеТоНадНоменклатурой" , ТипНоменклатура );

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

НовТЗСоВсемиРодителями . Сортировать ( "ПервыйРодитель" );

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

Процедура ПолучитьВсехРодителей ( ТЗ , Родитель , РодительНадРодителем )

Если РодительНадРодителем . Пустая () Тогда
Возврат;
КонецЕсли;

стрТЗ = ТЗ . Добавить ();
стрТЗ . ПервыйРодитель = Родитель ;
стрТЗ . РодительГдеТоНадНоменклатурой = РодительНадРодителем ;

ПолучитьВсехРодителей ( ТЗ , Родитель , РодительНадРодителем . Родитель );

Читайте также: