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

12.09.18

Разработка - Универсальные функции

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

Файлы

ВНИМАНИЕ: Файлы из Базы знаний - это исходный код разработки. Это примеры решения задач, шаблоны, заготовки, "строительные материалы" для учетной системы. Файлы ориентированы на специалистов 1С, которые могут разобраться в коде и оптимизировать программу для запуска в базе данных. Гарантии работоспособности нет. Возврата нет. Технической поддержки нет.

Наименование Скачано Купить файл
all.bsl
.bsl 50,18Kb ver:1
1 2 500 руб. Купить

Подписка PRO — скачивайте любые файлы со скидкой до 85% из Базы знаний

Оформите подписку на компанию для решения рабочих задач

Оформить подписку и скачать решение со скидкой

Вы можете заказать платную доработку или адаптацию этой разработки под вашу конфигурацию на «Бирже заказов».

  • 0% комиссии — оплата напрямую исполнителю;
  • Исполнители любого масштаба — от отдельных специалистов до команд под проект;
  • Прямой обмен контактами между заказчиком и исполнителем;
  • Безопасная сделка — при необходимости;
  • Рейтинги, кейсы и прозрачная система откликов.

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

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

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

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

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

 

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Вступайте в нашу телеграмм-группу Инфостарт

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

См. также

Загрузка и выгрузка в Excel Универсальные функции Программист 1С:Предприятие 8 Россия Бесплатно (free)

Описанный ниже подход позволяет в три шага заполнять формулы в Excel файлы, вне зависимости от ОС сервера (MS Windows Server или Linux). Подход подразумевает отказ от работы с COM-объектом в пользу работы через "объектную модель документа" (DOM).

30.10.2025    5967    Abysswalker    11    

47

Универсальные функции Работа с интерфейсом Программист 1С:Предприятие 8 Бесплатно (free)

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

14.05.2025    10754    DeerCven    15    

64

Универсальные функции Программист 1С:Предприятие 8 1C:Бухгалтерия Бесплатно (free)

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

21.05.2024    62419    dimanich70    86    

177

Универсальные функции Программист 1С:Предприятие 8 1C:Бухгалтерия Абонемент ($m)

Задача: вставить картинку из буфера обмена на форму средствами платформы 1С.

1 стартмани

18.03.2024    8477    7    John_d    13    

59

Универсальные функции Программист Стажер 1С:Предприятие 8 1C:Бухгалтерия Бесплатно (free)

Пришлось помучиться с GUID-ами немного, решил поделиться опытом, мало ли кому пригодится.

12.02.2024    78465    atdonya    31    

75

Универсальные функции Программист 1С:Предприятие 8 Бесплатно (free)

На заключительных этапах, когда идет отладка или доработка интерфейса, необходимо много раз переоткрыть внешний объект. Вот один из способов автоматизации этого.

30.11.2023    11154    ke.92@mail.ru    18    

68
Для отправки сообщения требуется регистрация/авторизация