Удаление дублирующихся файлов в томах на диске

05.10.22

Задачи пользователя - Адаптация типовых решений

Типовой механизм хранения файлов позволяет один и тот же файл прикреплять несколько раз. Это бесит наших админов, и по их просьбе был реализован следующий алгоритм.

Скачать исходный код

Наименование Файл Версия Размер
Удаление дублирующихся файлов в томах на диске при типовом хранении файлов в 1с.:
.cfe 10,36Kb
3
.cfe 10,36Kb 3 Скачать
Удаление дублирующихся файлов в томах на диске при типовом хранении файлов в 1с.:
.epf 7,79Kb
3
.epf 7,79Kb 3 Скачать

Мы провели анализ и выяснили, что в базе УТ один и тот же файл прикрепляют к разным документам.

Пример на скрине, один файл прикрепили 139 раз, и это не предел:

 

 

Решили избавиться от данной проблемы.

Суть решения.

1. Прокешировать всё файлы алгоритмом  МД5.

2. Выявить дубли.

3. Удалить лишние файлы, а в Справочнике присоединенных файлов сделать ссылки на уникальные файлы.

Вопрос, куда записывать информацию по файлам. Решил создать индексированный ресурс в регистре сведений Сведения о файлах.

К сожалению, в текущей версии платформы и конфигурации данный механизм нельзя полностью реализовать через расширение,  т.к. нельзя создать доп. ресурс. А перечислять в расширении все имена справочников, в которых есть "...ПрисоединенныеФайлы" проблематично. Это реализация для старой УТ. Для Бухгалтерии всё это вынесено в расширение, которое прикрепляю к данной публикации.

 

 

И в процедуре "перед записью"  в  модуле объекта регистра сведений "СведенияОФайлах" дописывать кеш файла.

//++Семенихин 05.10.2022 ++ Полати // 
//Дозаписываем Хеш по файлу
Процедура ПередЗаписью(Отказ, Замещение)
	Если ОбменДанными.Загрузка Тогда
		Возврат;
	КонецЕсли;
	
	Для Каждого строка из ЭтотОбъект Цикл
		//ПолучимИмяФалаФайл.Строка(Файл)
		//ОбщегоНазначенияКлиентСервер.ПолучитьПолноеИмяФайла(ИмяВременногоКаталога, ИмяФайла)
		Если строка.ТипХраненияФайла = 	Перечисления.ТипыХраненияФайлов.ВТомахНаДиске тогда
			Попытка
				ИмяФайла = ОбщегоНазначенияКлиентСервер.ПолучитьПолноеИмяФайла(строка.Файл.Том.ПолныйПутьWindows,строка.Файл.ПутьКФайлу);
				строка.Пл_КонтрольнаяСумма = MD5ХешФайл(ИмяФайла);
			Исключение
				
			КонецПопытки;	
			
		ИначеЕсли строка.ТипХраненияФайла = Перечисления.ТипыХраненияФайлов.ВИнформационнойБазе тогда
			//Двоичных данных ещё нет, они появятся позже..
			//Надо обрабатывать уже ОбщийМодуль.РаботаСФайламиСлужебный.Модуль.ЗаписатьФайлВИнформационнуюБазу и обновлять
			//сведения о файлах.
			//Пока данный вариант реализации не рассматриваем, Его можно на отдельное рег задание возложить	
			//ДвоичныеДанные = РаботаСФайлами.ДвоичныеДанныеФайла(строка.Файл);
			//строка.Пл_КонтрольнаяСумма = MD5ХешСтрока(ДвоичныеДанные);
			
		КонецЕсли;
	КонецЦикла;

КонецПроцедуры 

 //++Семенихин 05.10.2022 ++ Полати // 
Функция MD5ХешФайл(тСтрока)
 	Хеш = Новый ХешированиеДанных(ХешФункция.MD5);
 
 	Хеш.ДобавитьФайл(тСтрока);
	 
 	Возврат Хеш.ХешСумма; 
КонецФункции

//++Семенихин 05.10.2022 ++ Полати // 
Функция MD5ХешСтрока(тСтрока)
 	Хеш = Новый ХешированиеДанных(ХешФункция.MD5);
 
	 Хеш.Добавить(тСтрока);
 
 	Возврат Хеш.ХешСумма; 
КонецФункции

 

После добавления ресурса его можно заполнить обработкой:

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

 

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

КонецПроцедуры


Процедура ДописатьХешВСведенияОФайлах(Файл)
	
	Попытка
	Запись = РегистрыСведений.СведенияОФайлах.СоздатьМенеджерЗаписи();
	Запись.Файл = Файл;
	Запись.Прочитать();
	Если Запись.Выбран() Тогда
		//Запись.Пл_КонтрольнаяСумма = Пл_КонтрольнаяСумма;
		
		Запись.Записать();
	КонецЕсли;
	Исключение
	 Сообщить("Проблема в файле " + Файл);
	КонецПопытки;
	
	
КонецПроцедуры

После этого обработкой удаляем ненужные файлы и меняем ссылки в справочнике на эксклюзивные файлы. Обработку тоже прилагаю



Процедура УдалитьОдинаковыеФайлы() Экспорт

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


Процедура ПереписатьСправочникПрисоединенныхФайлов(Файл,ГлавныйТом,ГлавныйПутьКФайлу)
	
	ОбъектФайл = Файл.ПолучитьОбъект();
	ОбъектФайл.Том = ГлавныйТом;
	ОбъектФайл.ПутьКФайлу = ГлавныйПутьКФайлу;
	ОбъектФайл.Записать();
	
КонецПроцедуры 

Функция ПолучитьИмяФайлаПоВыборке(ВыборкаДетальныеЗаписи)
	 Возврат ОбщегоНазначенияКлиентСервер.ПолучитьПолноеИмяФайла(ВыборкаДетальныеЗаписи.ФайлТомПолныйПутьWindows,ВыборкаДетальныеЗаписи.ФайлПутьКФайлу);
КонецФункции	

 

Тестировалось на Бухгалтерии 3.0.113.17 и Управление торговлей, редакция 11 (11.4.10.75).

Хеширование присоединенных файлов

См. также

Табличная часть в доп. реквизитах и формирование таблиц в шаблоне docx для 1С:ДО 3.0

Адаптация типовых решений Платформа 1С v8.3 1С:Документооборот Россия Платные (руб)

Расширение конфигурации для «1С:Документооборот КОРП», редакция 3.0. позволяет: 1.использовать произвольные табличные части в качестве дополнительных реквизитов к документу; 2 использовать произвольные табличные части в шаблонах в формате docx для автоматического заполнения таблиц.

29400 руб.

29.06.2023    4868    10    5    

19

Расширение для 1С:УНФ. Автоматическое снятие резервов в Заказах покупателей

Логистика, склад и ТМЦ Адаптация типовых решений Пользователь Платформа 1С v8.3 1С:Управление нашей фирмой 1.6 1С:Управление нашей фирмой 3.0 Россия Управленческий учет Платные (руб)

Чтобы не допустить путаницы с обещаниями клиентам и для четкого контроля исполнения заказов мы используем резервирование товаров. Мы доработали УНФ, чтобы она автоматически отменяла старые резервы и не мешала эффективно продавать.

7200 руб.

02.08.2023    3241    5    0    

22

Каждому менеджеру нужен свой Excel

Адаптация типовых решений Программист Пользователь Платформа 1С v8.3 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Абонемент ($m)

Каждый из нас сталкивается с ситуацией, когда какой-нибудь менеджер показывает свой Excel и рассказывает, как он что-то из 1С копирует в него, снабжает пояснениями, выделяет цветом и т.д. и т.п. Заканчивается все просьбой сделать вот чтобы также было в 1С. И оказывается такой человек (почти с гарантией) либо лучшим продажником, либо каким-то важным, за все отвечающим, - на ком все держится.

2 стартмани

22.04.2024    4347    dimanich70    15    

18

Создать на основании - своя кнопка (БСП). Проблема двух подменю Создать на основании

БСП (Библиотека стандартных подсистем) Адаптация типовых решений Программист Платформа 1С v8.3 1С:ERP Управление предприятием 2 Бесплатно (free)

Понадобилось в подменю "Создать на основании" добавить свою команду, которая открывает обработку. В процессе доработок появилась проблема двух подменю "Создать на основании". В статье о том, как решились проблемы.

01.03.2024    2411    dimanich70    8    

15

Доработка отчета "Связанные документы" (структура подчиненности) для вывода объектов из любого расширения

Адаптация типовых решений Программист Платформа 1С v8.3 1С:Управление торговлей 11 Россия Абонемент ($m)

Доработка типового отчета "Связанные документы" позволяет просто и быстро расширять состав объектов для построения структуры подчиненности документов, используя объекты основной конфигурации и любых расширений.

1 стартмани

27.10.2023    2276    19    avmartynov    14    

44

Печать непроведенных документов для УТ, КА, ERP. Настройка печати по пользователям, документам и печатным формам

Пакетная печать Печатные формы Адаптация типовых решений Универсальные функции Платформа 1С v8.3 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Россия Абонемент ($m)

Расширение для программ 1С:Управление торговлей, 1С:Комплексная автоматизация, 1С:ERP, которое позволяет распечатывать печатные формы для непроведенных документов. Можно настроить, каким пользователям, какие конкретные формы документов разрешено печатать без проведения документа.

2 стартмани

22.08.2023    2488    34    progmaster    8    

4
Вознаграждение за ответ
Показать полностью
Отзывы
2. PLAstic 295 06.10.22 09:24 Сейчас в теме +1 $m
Я вот всё думаю, когда мне хоть какие бонусы начнут капать с плюсов на твоих разработках.
chigsrOck; +1 Ответить
Остальные комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. arsentevpva 06.10.22 09:00 Сейчас в теме
хм.. а ведь работает. Спасибо автору.
2. PLAstic 295 06.10.22 09:24 Сейчас в теме +1 $m
Я вот всё думаю, когда мне хоть какие бонусы начнут капать с плюсов на твоих разработках.
chigsrOck; +1 Ответить
3. human_new 641 06.10.22 09:38 Сейчас в теме
4. SerVer1C 778 06.10.22 09:39 Сейчас в теме
Лучше для хранения файлов использовать файловую систему с возможностью дедупликации.
И почему у вас под хэш тип строка(50) переменная? Думаете, что найдется MD5 длиннее 32 символов?
5. human_new 641 06.10.22 09:41 Сейчас в теме
(4) Хеш всегда 47 символов, не зависит от объема файла. А вот про файловую систему с возможностью дедупликации, пожалуйста, поподробнее, что бы админам переслать
6. Vasvas05 23 06.10.22 10:11 Сейчас в теме
Например, если в одной документы можно изменить файл по правам, а такой же файл в другом месте нельзя, то файлы надо дублировать. В вашем случае экономия пары ГБ, но получиться может хуже.
Может админам выделить 1 Тб? Цены сейчас не такие большие+дедупликация на нем
7. human_new 641 06.10.22 10:16 Сейчас в теме
(6) Справочник присоединенных файлов и так задублированным остается, у него всегда только один владелец, а ссылки на путь до файла подмениваются. Разделение по правам редактирования файлов я в 1с вообще не встречал. Согласен, что с версиями файлов надо ещё обдумывать, если изменяемые файлы хранить но у нас грузят в основном только PDF.
10. Vasvas05 23 06.10.22 11:13 Сейчас в теме
(7)Если в поступление А загрузили 1 скан, затем в поступление Б загрузили этот же скан. После обработки - они будет указывать на 1 файл, все верно? Что делать тогда, если в поступление Б пользователь поймет что совершил ошибку и заменит файл на правильный, в поступление А - тоже будет указывать на этот файл?
11. human_new 641 06.10.22 11:18 Сейчас в теме
(10) Да, Совсем забыл, у нас прикрепление файлов к документам тоже доработано на дату запрета изменения сразу после проведения... А так надо ещё над отборами подумать по срокам давности
13. human_new 641 06.10.22 11:22 Сейчас в теме
(10) Хотя всё тоже решается определенными отборами по сроку давности документов. механизм при этом никак не меняется. А отбор в обработке можете у себя поставить
14. human_new 641 06.10.22 12:01 Сейчас в теме
(10) Кстати, начал думать, А что значит заменит файл, у нас доступ к файлам только у службы 1с. Он может только удалить старый и прикрепить новый и тут всё отработает четко, никакой подмены не будет.
8. brolin 06.10.22 10:34 Сейчас в теме
Как только разработчики 1С сделают хоть один шаг в сторону S3 или любой другой сторонней хранилки - появится и дедупликация на уровне ФС.
9. brolin 06.10.22 10:41 Сейчас в теме
Ну это всё в рамках юмора.
Юрий с обработкой - просто монстр, спасибо большое.

Дедупликация файлов на уровне ФС с точки зрения админов - ну такое. Есть 1С которая по каким-то своим алгоритмам складывает файлы в хранилище. Да, видим, что файлы одинаковые, но мало ли как и по какой причине они были сохранены?
Если же ставится задача о том, что на хранилке с файлами не должно быть одинаковых файлов, то как решить который из 2 файлов верный, а который должен быть удален?
Для меня логически кажется верным, что удалением дублей занимается та же система, что их плодит.
12. Vasvas05 23 06.10.22 11:19 Сейчас в теме
(9)
Для меня логически кажется верным, что удалением дублей занимается та же система, что их плодит.

Система Windows или 1с ? Если привести аналогию, что файлы плодит сервер exchange, тогда дедупликация отлично справляется с файлами, при этом сам exchange не занимается, тем, что надо следить за дублями.
15. brolin 06.10.22 12:09 Сейчас в теме
Да, всё так. exchange использует файловое хранилище на сервере с ролью "файловый сервер" с включенной дедупликацией (типа того: https://learn.microsoft.com/ru-ru/windows-server/storage/data-deduplication/understand).
Поймет ли 1С (на уровне приложения) такое отношение у ней файловой системы - не готов ответить, ни разу не пробовал.
16. Vasvas05 23 06.10.22 13:59 Сейчас в теме
(15)
ни разу не пробовал.

мы используем, при частой перезаписи файлов это спасает от дублирования новых версий на самом диске
17. brolin 06.10.22 14:06 Сейчас в теме
(16)
Огромное спасибо за наводку :)
18. starik-2005 3046 06.10.22 20:09 Сейчас в теме
В детстве, помню, пилил на паскале софтинку, которая удаляла одинаковые файлы (размер + простой XOR CRC 32 бита на асме). Коллегам с универа это позволило сильно уменьшить количество мусора на дисках, которые были совсем не такими большими, аки щаз.
19. starik-2005 3046 06.10.22 23:14 Сейчас в теме
Кстати, аффтор, имей ввиду, что файлы с одной и той же контрольной суммой могут быть разными. Это называется коллизией хеша. Фактически на сообщение из Х бит с хешем в У бит количество коллизий для каждого хеша будет равно 2^(Х-У). Т.е. если сообщение длиннее хеша всего на байт, то на каждый вариант хеша будет 2^8 сообщений. Но это так, математика. Ее все вроде бы знают, так что не принимайте близко к сердцу, если очевидные вещи говорю. Просто в интернетах иногда шутки ходят о том, что самый крутой архиватор - это md5.
Rafaraf; GorkyGorod; asupsam; +3 Ответить
Оставьте свое сообщение