Доработка функции ОбщегоНазначения.ЗаменитьСсылки для автоматической чистки или свёртки табличных частей

Программирование - Универсальные функции

2
Стандартная обработка по замене дублей ругается на документ с неуникальными строками. Предполагается, что их нужно либо а) удалить, либо б) свернуть. Я немного модифицировал код функции ОбщегоНазначения.ЗаменитьСсылки, встроив в него вызов процедуры, переопределяемой в модуле менеджера соответствующего документа. И в этом модуле менеджера мы уже сами определяем - удалить или свернуть. Ну и вообще там чего хошь можно с этой коллекцией сделать - сам же ж процедуру пишешь...

В функции ОбщегоНазначения.ЗаменитьСсылки можно вставить вызов переопределяемых обработчиков событий по технологии как в БСП, переопределив их в модулях менеджеров этих требующих уникальности строк документов.

Суть метода быстрее всего понять из этого куска кода:

Функция ИзмененныеОбъектыПриЗаменеВОбъекте(ПараметрыВыполнения, МестоИспользования, ОбрабатываемыеСтроки)

Вместо вызова ЗаменитьВКоллекцииСтрок(...) в типовой вставляем наш кусок кода:

	// Табличные части
	Для Каждого Элемент Из Описание.ТабличныеЧасти Цикл
		СтандартнаяОбработка = Истина;
		Если МодульМенеджера <> Неопределено Тогда
			МодульМенеджера.ПриЗаменеВКоллекцииСтрок(
				"ТабличныеЧасти",
				Элемент.Имя,
				Объект,
				Объект[Элемент.Имя],
				Элемент.СписокПолей,
				ПарыЗамен,
				СтандартнаяОбработка);
		КонецЕсли;
			
		// несмотря на наличие вызова модуля - применяем стандартную обработку
		Если СтандартнаяОбработка Тогда
			ЗаменитьВКоллекцииСтрок(
				"ТабличныеЧасти",
				Элемент.Имя,
				Объект,
				Объект[Элемент.Имя],
				Элемент.СписокПолей,
				ПарыЗамен);
		КонецЕсли;
	КонецЦикла;

 

Конечно надо инициализировать МодульМенеджера. Я это делаю в том же модуле ОбщегоНазначения

Функция ИзмененныеОбъектыПриЗаменеВОбъекте(ПараметрыВыполнения, МестоИспользования, ОбрабатываемыеСтроки)
	МодульМенеджера = ПараметрыВыполнения.МодулиМенеджеровПриЗаменеВКоллекцииСтрок[ТипЗнч(Данные)];

Конечно надо инициализировать это соответствие, и пр...  (эту всю кухню смотрите в исходниках, про неё в статье читать скучно, не говоря о том чтобы писать)

[Не намного, но всё же] веселее писать про модуль менеджера документа. Вот пример для УстановкаЦенНоменклатуры:

Процедура ПриЗаменеВКоллекцииСтрок(ВидКоллекции, ИмяКоллекции, Объект, Коллекция, Знач СтруктураПолей, Знач ПарыЗамен, СтандартнаяОбработка) Экспорт
	
	Если ВидКоллекции = "ТабличныеЧасти" Тогда
		Если ИмяКоллекции = "Товары" Тогда
			СтандартнаяОбработка = Ложь;
			ПоискИУдалениеДублей.УдалитьДублиВКоллекцииСтрок(ВидКоллекции, ИмяКоллекции, Объект, Коллекция, СтруктураПолей, ПарыЗамен);
		КонецЕсли;
		
	ИначеЕсли ВидКоллекции = "Движения" Тогда
		
		Если ИмяКоллекции = "РегистрСведений.ЦеныНоменклатуры" Тогда
			СтандартнаяОбработка = Ложь;
			ПоискИУдалениеДублей.УдалитьДублиВКоллекцииСтрок(ВидКоллекции, ИмяКоллекции, Объект, Коллекция, СтруктураПолей, ПарыЗамен);			
		КонецЕсли;
		
	КонецЕсли;
	
	
КонецПроцедуры

Вот пример процедуры общего модуля ПоискИУдалениеДублей - это чтобы не писать в каждом модуле менеджера документа одно и то же - вынес случаи а) и б) в общий модуль:

Процедура УдалитьДублиВКоллекцииСтрок(ВидКоллекции, ИмяКоллекции, Объект, Коллекция, Знач СтруктураПолей, Знач ПарыЗамен) Экспорт
	
	// не представляю какие там бывают коллекции, но 
	Если Не СтруктураПолей.Свойство("Номенклатура") Тогда
		Возврат;
	КонецЕсли;
	
	РабочаяКоллекция = Коллекция.Выгрузить();
	ПараметрыОтбора = Новый Структура("Номенклатура");
	
	СоответствиеЦелевыхСсылок = ОбщегоНазначения.СоответствиеЗначенийСоответствия(ПарыЗамен);
	мСоответствиеЦелевыхСсылок = Новый Соответствие;
	
	Для каждого ЭлементЦелевыхСсылок Из СоответствиеЦелевыхСсылок Цикл
		
		ПараметрыОтбора.Номенклатура = ЭлементЦелевыхСсылок.Ключ;
		Если РабочаяКоллекция.НайтиСтроки(ПараметрыОтбора).Количество() > 0 Тогда
			мСоответствиеЦелевыхСсылок.Вставить(ЭлементЦелевыхСсылок.Ключ, Истина); // надо переносить данные, потому что из ОбщегоНазначения вернулось ReadOnly соответствие
		КонецЕсли;
		
	КонецЦикла;
	
	Модифицировано = Ложь;
	Для каждого Пара Из ПарыЗамен Цикл
	
		ЦелеваяСсылка = Пара.Значение;
		ПараметрыОтбора.Номенклатура = Пара.Ключ;
		НайденныеСтроки = РабочаяКоллекция.НайтиСтроки(ПараметрыОтбора);
		Н = НайденныеСтроки.Количество() - 1;
		Пока Н >= 0 Цикл
			ТекущаяСтрока = НайденныеСтроки[Н];
			Если Не мСоответствиеЦелевыхСсылок[ЦелеваяСсылка] = Истина Тогда
				// присваиваем вручную в первой встречной строке товара целевую ссылку
				//ЗарегистрироватьФактЗамены(Данные, СтрокаТовара.Номенклатура, ЦелеваяСсылка, "ТабличныеЧасти", "Товары", ТаблицаТоваров.Индекс(СтрокаТовара), "Номенклатура");
				ТекущаяСтрока.Номенклатура = ЦелеваяСсылка;
				мСоответствиеЦелевыхСсылок.Вставить(ЦелеваяСсылка, Истина);
			Иначе
				РабочаяКоллекция.Удалить(ТекущаяСтрока);
			КонецЕсли;
			
			Модифицировано = Истина;
			
		    Н = Н - 1;
		КонецЦикла;
	
	КонецЦикла;
	
	Если Модифицировано Тогда
		Коллекция.Загрузить(РабочаяКоллекция);
	КонецЕсли;
	
КонецПроцедуры

Какие там бывают коллекции - я до сих пор не представляю. Названия нужных ВидКоллекции ловил в отладчике.

Ещё есть элегантный кусок модуля ПоискИУдалениеДублейПереопределяемый, вот он:

#Область ПрограммныйИнтерфейс

// Определить объекты, в модулях менеджеров которых предусмотрена возможность параметризации 
// алгоритма поиска дублей с помощью экспортных процедур ПараметрыПоискаДублей, ПриПоискеДублей 
// и ВозможностьЗаменыЭлементов.
//
// Параметры:
//   Объекты - Соответствие - объекты, в модулях менеджеров которых размещены экспортные процедуры.
//       ** Ключ     - Строка - полное имя объекта метаданных, подключенного к подсистеме "Поиск и удаление дублей".
//                              Например, "Справочник.Контрагенты".
//       ** Значение - Строка - имена экспортных процедур, определенных в модуле менеджера.
//                              Могут быть указаны:
//                              "ПараметрыПоискаДублей",
//                              "ПриПоискеДублей",
//                              "ВозможностьЗаменыЭлементов".
//                              Каждое имя должно начинаться с новой строки.
//                              Если указана пустая строка, то в модуле менеджера определены все процедуры.
//++ Альберт -- Поиск и замена дублей. Переопределение замены ссылок в документах
//				"ПриЗаменеВКоллекцииСтрок"
//-- Альберт -- Поиск и замена дублей. Переопределение замены ссылок в документах
//
// Пример:
//  1. В справочнике определены все процедуры:
//  Объекты.Вставить(Метаданные.Справочники.Контрагенты.ПолноеИмя(), "");
//
//  2. Определены только процедуры ПараметрыПоискаДублей и ПриПоискеДублей:
//  Объекты.Вставить(Метаданные.Справочники.ЗадачиПроекта.ПолноеИмя(), "ПараметрыПоискаДублей
//                   |ПриПоискеДублей");
//
Процедура ПриОпределенииОбъектовСПоискомДублей(Объекты) Экспорт
	
	//++ Альберт -- Поиск и замена дублей. Переопределение замены ссылок в документах
	Объекты.Вставить(Метаданные.Документы.УстановкаЦенНоменклатуры.ПолноеИмя(), "ПриЗаменеВКоллекцииСтрок");
	Объекты.Вставить(Метаданные.Документы.РегистрацияЦенНоменклатурыПоставщика.ПолноеИмя(), "ПриЗаменеВКоллекцииСтрок");
	Объекты.Вставить(Метаданные.Документы.РегистрацияОстатковНоменклатурыПоставщика.ПолноеИмя(), "ПриЗаменеВКоллекцииСтрок");
	Объекты.Вставить(Метаданные.Документы.ЗаказПоставщику.ПолноеИмя(), "ПриЗаменеВКоллекцииСтрок");
	Объекты.Вставить(Метаданные.Документы.ПоступлениеТоваровУслуг.ПолноеИмя(), "ПриЗаменеВКоллекцииСтрок");
	//-- Альберт -- Поиск и замена дублей. Переопределение замены ссылок в документах
	
КонецПроцедуры

#КонецОбласти

Во вложении один файл с исходниками, разбитый по областям - именам тех модулей, куда надо вставлять код.

P.S. Друзья, я это никогда нигде не внедрял, (на своей фирме оно как-то само создалось) поэтому могут быть ляпы типа "забыл ещё модуль такой-то". Не судите строго, спрашивайте, догружу недостающие :)

2

Скачать файлы

Наименование Файл Версия Размер
all.bsl
.bsl 50,18Kb
12.09.18
0
.bsl 1 50,18Kb Скачать

См. также

Сортировка: Древо
В этой теме еще нет сообщений.
Оставьте свое сообщение