Тома хранения файлов / Удаление лишних файлов из тома / Модуль формы

файл
///////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2024, ООО 1С-Софт
// Все права защищены. Эта программа и сопроводительные материалы предоставляются 
// в соответствии с условиями лицензии Attribution 4.0 International (CC BY 4.0)
// Текст лицензии доступен по ссылке:
// https://creativecommons.org/licenses/by/4.0/legalcode
///////////////////////////////////////////////////////////////////////////////////////////////////////

#Область ОбработчикиСобытийФормы

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	
	ТомХраненияФайлов = Параметры.ТомХраненияФайлов;
	
	ЗаполнитьТаблицуЛишнихФайлов();
	КоличествоЛишнихФайлов = ЛишниеФайлы.Количество();
	
	ПутьДня = Формат(ТекущаяДатаСеанса(), "ДФ=ггггММдд") + ПолучитьРазделительПути();
	
	СкопироватьФайлыПередУдалением                = Ложь;
	Элементы.ПутьКПапкеДляКопирования.Доступность = Ложь;
	
	Если ОбщегоНазначения.ЭтоМобильныйКлиент() Тогда
		ПоложениеКоманднойПанели = ПоложениеКоманднойПанелиФормы.Авто;
	КонецЕсли;
	
КонецПроцедуры

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

#Область ОбработчикиСобытийЭлементовШапкиФормы

&НаКлиенте
Процедура ДекорацияПодробнееНажатие(Элемент)
	
	ПараметрыОтчета = Новый Структура();
	ПараметрыОтчета.Вставить("СформироватьПриОткрытии", Истина);
	ПараметрыОтчета.Вставить("Отбор", Новый Структура("Том", ТомХраненияФайлов));
	
	ОткрытьФорму("Отчет.ПроверкаЦелостностиТома.ФормаОбъекта", ПараметрыОтчета);
	
КонецПроцедуры

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

&НаКлиенте
Процедура ПутьКПапкеДляКопированияПриИзменении(Элемент)
	
	ПутьКПапкеДляКопирования                     = ОбщегоНазначенияКлиентСервер.ДобавитьКонечныйРазделительПути(ПутьКПапкеДляКопирования);
	Элементы.ФормаУдалитьЛишниеФайлы.Доступность = ЗначениеЗаполнено(ПутьКПапкеДляКопирования);
	
КонецПроцедуры

&НаКлиенте
Процедура СкопироватьФайлыПередУдалениемПриИзменении(Элемент)
	
	Если Не СкопироватьФайлыПередУдалением Тогда
		ПутьКПапкеДляКопирования                      = "";
		Элементы.ПутьКПапкеДляКопирования.Доступность = Ложь;
		Элементы.ФормаУдалитьЛишниеФайлы.Доступность  = Истина;
	Иначе
		Элементы.ПутьКПапкеДляКопирования.Доступность = Истина;
		Если ЗначениеЗаполнено(ПутьКПапкеДляКопирования) Тогда
			Элементы.ФормаУдалитьЛишниеФайлы.Доступность = Истина;
		Иначе
			Элементы.ФормаУдалитьЛишниеФайлы.Доступность = Ложь;
		КонецЕсли;
	КонецЕсли;
	
КонецПроцедуры

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

#Область ОбработчикиКомандФормы

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

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

#Область СлужебныеПроцедурыИФункции

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

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

&НаСервере
Процедура ЗаполнитьТаблицуЛишнихФайлов()
	
	ТаблицаФайловНаДиске = РаботаСФайламиВТомахСлужебный.ЛишниеФайлыВТоме();
	ПутьКТому = СокрЛП(РаботаСФайламиВТомахСлужебный.ПолныйПутьТома(ТомХраненияФайлов));
	
	МассивФайлов = НайтиФайлы(ПутьКТому,"*", Истина);
	Для Каждого Файл Из МассивФайлов Цикл
		
		Если Не Файл.ЭтоФайл() Тогда
			Продолжить;
		КонецЕсли;
		
		НоваяСтрока = ТаблицаФайловНаДиске.Добавить();
		НоваяСтрока.Имя              = Файл.Имя;
		НоваяСтрока.ИмяБезРасширения = Файл.ИмяБезРасширения;
		НоваяСтрока.ПолноеИмя        = Файл.ПолноеИмя;
		НоваяСтрока.Путь             = Файл.Путь;
		НоваяСтрока.Расширение       = Файл.Расширение;
		НоваяСтрока.СтатусПроверки   = НСтр("ru = 'Лишние файлы (есть в томе, но сведения о них отсутствуют)'");
		НоваяСтрока.Количество       = 1;
		НоваяСтрока.Том              = ТомХраненияФайлов;
		
	КонецЦикла;
	
	РаботаСФайламиВТомахСлужебный.ЗаполнитьЛишниеФайлы(ТаблицаФайловНаДиске, ТомХраненияФайлов);
	ТаблицаФайловНаДиске.Индексы.Добавить("СтатусПроверки");
	МассивЛишнихФайлов = ТаблицаФайловНаДиске.НайтиСтроки(
		Новый Структура("СтатусПроверки", НСтр("ru = 'Лишние файлы (есть в томе, но сведения о них отсутствуют)'")));
	
	Для Каждого Файл Из МассивЛишнихФайлов Цикл
		НоваяСтрока = ЛишниеФайлы.Добавить();
		ЗаполнитьЗначенияСвойств(НоваяСтрока, Файл);
		НоваяСтрока.ОтносительныйПуть = СтрЗаменить(НоваяСтрока.ПолноеИмя, ПутьКТому, "");
	КонецЦикла;
	
	ЛишниеФайлы.Сортировать("Имя");
	
КонецПроцедуры

&НаКлиенте
Процедура ПравоЗаписиВКаталог(ИсходноеОповещение)
	
	Если ПустаяСтрока(ПутьКПапкеДляКопирования) Тогда
		ВыполнитьОбработкуОповещения(ИсходноеОповещение, Истина);
		Возврат
	КонецЕсли;
	
	ИмяКаталога = ПутьКПапкеДляКопирования + "ПроверкаДоступа\";
	
	ПараметрыУдаленияКаталога  = Новый Структура("ИсходноеОповещение, ИмяКаталога", ИсходноеОповещение, ИмяКаталога);
	ОповещениеСозданияКаталога = Новый ОписаниеОповещения("ПослеСозданияКаталога", ЭтотОбъект, ПараметрыУдаленияКаталога, "ПослеОшибкиСозданияКаталога", ЭтотОбъект);
	НачатьСозданиеКаталога(ОповещениеСозданияКаталога, ИмяКаталога);
	
КонецПроцедуры

&НаКлиенте
Процедура ПослеОшибкиСозданияКаталога(ИнформацияОбОшибке, СтандартнаяОбработка, ДополнительныеПараметры) Экспорт
	
	ОбработатьОшибкуПравДоступа(ИнформацияОбОшибке, ДополнительныеПараметры.ИсходноеОповещение);
	
КонецПроцедуры

&НаКлиенте
Процедура ПослеСозданияКаталога(Результат, ДополнительныеПараметры) Экспорт
	
	НачатьУдалениеФайлов(Новый ОписаниеОповещения("ПослеУдаленияКаталога", ЭтотОбъект, ДополнительныеПараметры, "ПослеОшибкиУдаленияКаталога", ЭтотОбъект), ДополнительныеПараметры.ИмяКаталога);
	
КонецПроцедуры

&НаКлиенте
Процедура ПослеУдаленияКаталога(ДополнительныеПараметры) Экспорт
	
	ВыполнитьОбработкуОповещения(ДополнительныеПараметры.ИсходноеОповещение, Истина);
	
КонецПроцедуры

&НаКлиенте
Процедура ПослеОшибкиУдаленияКаталога(ИнформацияОбОшибке, СтандартнаяОбработка, ДополнительныеПараметры) Экспорт
	
	ОбработатьОшибкуПравДоступа(ИнформацияОбОшибке, ДополнительныеПараметры.ИсходноеОповещение);
	
КонецПроцедуры

&НаКлиенте
Процедура ОбработатьОшибкуПравДоступа(ИнформацияОбОшибке, ИсходноеОповещение)
	
	ШаблонОшибки = НСтр("ru = 'Некорректная папка для копирования.
		|Возможно учетная запись, от лица которой работает
		|сервер 1С:Предприятия, не имеет прав доступа к указанной папке.
		|
		|%1'");
	
	ТекстОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ШаблонОшибки, ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке));
	ОбщегоНазначенияКлиент.СообщитьПользователю(ТекстОшибки, , , "ПутьКПапкеДляКопирования");
	
	ВыполнитьОбработкуОповещения(ИсходноеОповещение, Ложь);
	
КонецПроцедуры

// Параметры:
//   ОтчетОбОшибках - ТабличныйДокумент
//   МассивФайловСОшибками - Массив из см. СтруктураОшибки
//
&НаСервере
Процедура СформироватьОтчетОбОшибках(ОтчетОбОшибках)

	ТабличныйМакет = Справочники.ТомаХраненияФайлов.ПолучитьМакет("МакетОтчета");
	
	ОбластьЗаголовок = ТабличныйМакет.ПолучитьОбласть("Заголовок");
	ОбластьЗаголовок.Параметры.Описание = НСтр("ru = 'Проблемные файлы:'");
	ОтчетОбОшибках.Вывести(ОбластьЗаголовок);
	
	ОбластьСтрока = ТабличныйМакет.ПолучитьОбласть("Строка");
	
	Для Каждого ФайлСОшибкой Из РеквизитФормыВЗначение("ФайлыСОшибками") Цикл
		ОбластьСтрока.Параметры.Название = ФайлСОшибкой.Имя;
		ОбластьСтрока.Параметры.Ошибка = ФайлСОшибкой.Ошибка;
		Область = ОтчетОбОшибках.Вывести(ОбластьСтрока);
		Область.ВысотаСтроки = 0;
		Область.АвтоВысотаСтроки = Истина;
	КонецЦикла;
	
КонецПроцедуры

&НаКлиенте
Процедура ПодключениеРасширенияРаботыСФайламиЗавершение(РасширениеПодключено, ДополнительныеПараметры) Экспорт
	
	Если Не РасширениеПодключено Тогда
		ПоказатьПредупреждение(, НСтр("ru = 'Не установлено расширение для работы с 1С:Предприятием. Действие не доступно.'"));
		Возврат;
	КонецЕсли;
	
	ПапкаДляКопирования = Новый Файл(ПутьКПапкеДляКопирования);
	ПапкаДляКопирования.НачатьПроверкуСуществования(Новый ОписаниеОповещения("ПроверкаСуществованияКаталогаЗавершение", ЭтотОбъект));
	
КонецПроцедуры

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

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

&НаКлиенте
Процедура УдалитьФайлыТомов(ФайлыДляУдаления)
	РезультатУдаления = УдалитьФайлыТомовНаСервере(ФайлыДляУдаления);
	ЧислоУдаленныхФайлов = РезультатУдаления.Удалено;
	ФайлыСОшибками.Очистить();
	Для Каждого ОшибкаУдаления Из РезультатУдаления.ОшибкиУдаления Цикл
		ЗаполнитьЗначенияСвойств(ФайлыСОшибками.Добавить(), ОшибкаУдаления);
	КонецЦикла;
	
	ПослеОбработкиФайлов();
КонецПроцедуры

&НаСервереБезКонтекста
Функция УдалитьФайлыТомовНаСервере(Файлы)
	Возврат РаботаСФайламиВТомахСлужебный.УдалитьФайлыТомов(Файлы);
КонецФункции

&НаКлиенте
Процедура ПослеПолученияФайловССервера(ПолученныеФайлы, Контекст) Экспорт
	ФайлыДляУдаления = Новый Массив;
	Для Каждого Файл Из Контекст.ФайлыДляУдаления Цикл
		ФайлыДляУдаления.Добавить(Файл.Ключ);
	КонецЦикла;
		
	УдалитьФайлыТомов(ФайлыДляУдаления);
КонецПроцедуры

&НаКлиенте
Процедура ОшибкаПослеПолученияФайловССервера(ИнформацияОбОшибке, СтандартнаяОбработка, Контекст) Экспорт
	ФайлыСОшибками.Очистить();
	ФайлСОшибкой = ФайлыСОшибками.Добавить();
	ФайлСОшибкой.Ошибка = ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке);
	ПослеОбработкиФайлов();
КонецПроцедуры

&НаСервере
Функция ПодготовитьФайлыНаСервере(ФайлыДляУдаления)
	Результат = Новый Массив;
	Для Каждого Файл Из ФайлыДляУдаления Цикл
		ДвоичныеДанные = Новый ДвоичныеДанные(Файл.Ключ);
		Адрес = ПоместитьВоВременноеХранилище(ДвоичныеДанные);
		ИмяФайла = Файл.Значение.ОтносительныйПуть;
		Результат.Добавить(Новый ОписаниеПередаваемогоФайла(ИмяФайла, Адрес))
	КонецЦикла;
	Возврат Результат;
КонецФункции

&НаКлиенте
Процедура ПослеОбработкиФайлов()

	Если ЧислоУдаленныхФайлов <> 0 Тогда
		ТекстОповещения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru = 'Удалено файлов: %1'"),
			ЧислоУдаленныхФайлов);
		ПоказатьОповещениеПользователя(
			НСтр("ru = 'Завершено удаление лишних файлов.'"),,
			ТекстОповещения, БиблиотекаКартинок.ДиалогИнформация);
	КонецЕсли;
	
	Если ФайлыСОшибками.Количество() > 0 Тогда
		ОтчетОбОшибках = Новый ТабличныйДокумент;
		СформироватьОтчетОбОшибках(ОтчетОбОшибках);
		ОтчетОбОшибках.Показать(НСтр("ru = 'Удаление лишних файлов из тома'"));
	КонецЕсли;
	
	Закрыть();
	
КонецПроцедуры

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

Связанные материалы