gifts2017

Функция создания вложенных каталогов + ф-ции извлечения имен файлов для 1с 7.7

Опубликовал Александр Тарасенков (tarasenkov) в раздел Программирование - Практика программирования

Расширим возможности ФС.
Вы когда-нибудь пытались создать вложенные папки из 1с?
Как ни странно, стандартной функции для этой операции нет.

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

Так появилась функция глСоздатьКаталог().

А вот пример использования - создание файла приказа на основании шаблона.
На форме расположен объект "СписокЗначений" с именем "спШаблоны".

1. Заполним список шаблонов
// ...
спШаблоны.УдалитьВсе();
ПутьКПапкеШаблонов = КаталогИБ()+"Приказы\\Шаблоны";
Если глСоздатьКаталог(ПутьКПапкеШаблонов) = 1 Тогда
	ФС.УстТекКаталог(ПутьКПапкеШаблонов);
	ИмяШаблона = ФС.НайтиПервыйФайл("*.doc");
	Пока ИмяШаблона <> "" Цикл
		Если Лев(ИмяШаблона, 1) <> "~" Тогда
			спШаблоны.ДобавитьЗначение(ИмяШаблона);
		КонецЕсли;	
		ИмяШаблона = ФС.НайтиСледующийФайл();
	КонецЦикла;	
КонецЕсли;	
// ...

2. Создаем подпапку по имени файла шаблона, и копируем туда файл на основании шаблона.
 //..
ИмяШаблонаКратко = спШаблоны.ПолучитьЗначение(спШаблоны.ТекущаяСтрока());
ИмяШаблонаКраткоБезРасширения = глИзвлечьИмяФайлаБезРасширения(ИмяШаблонаКратко);
ПутьКПапкеГотовых = КаталогИБ() + "Приказы\" + ИмяШаблонаКраткоБезРасширения + "\";
Если глСоздатьКаталог(ПутьКПапкеГотовых) = 0 Тогда
	Возврат;
КонецЕсли;	
		
ИмяШаблона = КаталогИБ()+"Приказы\\Шаблоны\"+ИмяШаблонаКратко;
ИмяФайла = ПутьКПапкеГотовых + ИмяШаблонаКраткоБезРасширения + " "
	+Формат(ТекущаяДата(), "ДГГГГММДД")+" "+СтрЗаменить(ТекущееВремя(), ":", "")+".doc";

Если ФС.СуществуетФайл(ИмяШаблона) = 0 Тогда
	Предупреждение("Шаблон "+ИмяШаблона+" не найден!");
	Возврат;
КонецЕсли;	

ФС.КопироватьФайл(ИмяШаблона, ИмяФайла, 1);
//..

Текст функций:
//-----------------------------------------------------
Функция глСоздатьКаталог(Знач Путь) Экспорт
	
	Пока Прав(Путь, 1) = "\" Цикл
		Путь = Сред(Путь, 1, СтрДлина(Путь) - 1);
	КонецЦикла;	
	
	// Проверим, возможно каталог существует
	Атрибуты = "";
	ФС.АтрибутыФайла(Путь, , Атрибуты);
	Если Сред(Атрибуты, 4, 1) = "1" Тогда
		Возврат 1;
	КонецЕсли;	
	
	спКСозданию = СоздатьОбъект("СписокЗначений");
	
	текПуть = Путь;
	врДлина = СтрДлина(Путь);
	Для к = -врДлина по -1 Цикл
		Если Сред(Путь, -к, 1) = "\" Тогда
			спКСозданию.ДобавитьЗначение(текПуть);
			текПуть = Лев(Путь, -к-1);
			
			// Проверяем наличие текущего уровня
			Атрибуты = "";
			ФС.АтрибутыФайла(текПуть, , Атрибуты);
			фЕстьТекПуть = ?(Сред(Атрибуты, 4, 1) = "1", 1, 0);
			
			Если фЕстьТекПуть = 0 Тогда
				Продолжить;
			КонецЕсли;	
			
			// Пытаемся создать с текущего уровня
			Для н = -спКСозданию.РазмерСписка() по -1 Цикл
				врПутьХ = спКСозданию.ПолучитьЗначение(-н);
				ФС.СоздатьКаталог(врПутьХ);
				Если н = - 1 Тогда
					Атрибуты = "";
					ФС.АтрибутыФайла(врПутьХ, , Атрибуты);
					Если Сред(Атрибуты, 4, 1) = "1" Тогда
						// Удачное создание с текущего уровня
						Возврат 1;
					КонецЕсли;	
				КонецЕсли;	
			КонецЦикла;	
		КонецЕсли;	
	КонецЦикла;	
	
	Предупреждение("Невозможно создать путь: "+РазделительСтрок+Путь, 4);
	Возврат 0;
	
КонецФункции

//-----------------------------------------------------
Функция глИзвлечьИмяФайла(ПолноеИмяФайла) Экспорт

	Файл = "";
	врДлина = СтрДлина(ПолноеИмяФайла);
	Для к = -врДлина по -1 Цикл
		Если Сред(ПолноеИмяФайла, -к, 1) = "\" Тогда
			Файл = Прав(ПолноеИмяФайла, врДлина+к);
			Прервать;
		КонецЕсли;	
	КонецЦикла;	
	
	Возврат(Файл);
КонецФункции

//-----------------------------------------------------
Функция глИзвлечьИмяФайлаБезРасширения(КраткоеИмяФайла) Экспорт

	Файл = "";
	врДлина = СтрДлина(КраткоеИмяФайла);
	Для к = -врДлина по -1 Цикл
		Если Сред(КраткоеИмяФайла, -к, 1) = "." Тогда
			Файл = Лев(КраткоеИмяФайла, -к-1);
			Прервать;
		КонецЕсли;	
	КонецЦикла;	
	
	Возврат(Файл);
КонецФункции


Все таки 1с это сила, даже если чего-то не хватает, всегда можно дописать.

Исправление.
Добавлена проверка на запрещенные символы и наличие в указанном пути файлов.
//-----------------------------------------------------
Функция глСоздатьКаталог(Знач Путь) Экспорт
	
	Пока Прав(Путь, 1) = "\" Цикл
		Путь = Сред(Путь, 1, СтрДлина(Путь) - 1);
	КонецЦикла;	
	
	Если СокрЛП(Путь) = "" Тогда
		Предупреждение("Невозможно создать пустой путь", 4);
		Возврат 0;
	КонецЕсли;	
	
	// Проверим, возможно каталог существует
	Если ФС.СуществуетФайл(Путь) = 1 Тогда
		Атрибуты = "";
		ФС.АтрибутыФайла(Путь, , Атрибуты);
		Если Сред(Атрибуты, 4, 1) = "1" Тогда
			Возврат 1;
		Иначе
			Предупреждение("Невозможно создать путь: "+РазделительСтрок+Путь
			+РазделительСтрок+"Так как существует одноименный файл.", 4);
			Возврат 0;
		КонецЕсли;
	КонецЕсли;	

	спКСозданию = СоздатьОбъект("СписокЗначений");
	
	врДлина = СтрДлина(Путь);
	// Проверка на запрещенные символы
	ЕстьБукваДиска = ?(Найти("abcdefghijklmnopqrstuvwxyz", Нрег(Лев(Путь, 1))) > 0, 1, 0);
	ЗапрещенныеСимволы = "/?|*<>:"""+РазделительСтрок+СимволТабуляции;
	Для к = 1 по врДлина Цикл
		Символ = Сред(Путь, к, 1);
		Если (Найти(ЗапрещенныеСимволы, Символ) > 0) или (КодСимв(Символ) < 32) Тогда
			Если не ((к = 2) и (Символ = ":") и (ЕстьБукваДиска = 1)) Тогда
				Предупреждение("Невозможно создать путь: "+РазделительСтрок+Путь
				+РазделительСтрок+"Так как использованы запрещенные символы.", 4);
				Возврат 0;
			КонецЕсли;
		КонецЕсли;	
	КонецЦикла;	
	// Основной цикл
	текПуть = Путь;
	Для к = -врДлина по -1 Цикл
		Если Сред(Путь, -к, 1) = "\" Тогда
			спКСозданию.ДобавитьЗначение(текПуть);
			текПуть = Лев(Путь, -к-1);
			
			// Проверяем наличие текущего уровня
			Если ФС.СуществуетФайл(текПуть) = 1 Тогда
				Атрибуты = "";
				ФС.АтрибутыФайла(текПуть, , Атрибуты);
				Если Сред(Атрибуты, 4, 1) = "0" Тогда
					Предупреждение("Невозможно создать путь: "+РазделительСтрок+Путь
					+РазделительСтрок+"Так как существует файл:"+РазделительСтрок+текПуть, 4);
					Возврат 0;
				КонецЕсли;
			Иначе
				Продолжить;
			КонецЕсли;	
			
			// Пытаемся создать с текущего уровня
			Для н = -спКСозданию.РазмерСписка() по -1 Цикл
				врПутьХ = спКСозданию.ПолучитьЗначение(-н);
				ФС.СоздатьКаталог(врПутьХ);
				Если н = - 1 Тогда
					Атрибуты = "";
					ФС.АтрибутыФайла(врПутьХ, , Атрибуты);
					Если Сред(Атрибуты, 4, 1) = "1" Тогда
						// Удачное создание с текущего уровня
						Возврат 1;
					Иначе
						Предупреждение("Невозможно создать путь: "+РазделительСтрок+Путь, 4);
						Возврат 0;
					КонецЕсли;	
				КонецЕсли;	
			КонецЦикла;	
		КонецЕсли;	
	КонецЦикла;	

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

См. также

Подписаться Добавить вознаграждение
Комментарии
1. Сhe Burashka (CheBurator) 13.11.07 00:16
хм.. как-то создание вложенных файлов красивше решается.. рекурсией...
а вариант
// Проверим, возможно каталог существует
Атрибуты = "";
ФС.АтрибутыФайла(Путь, , Атрибуты);
Если Сред(Атрибуты, 4, 1) = "1" Тогда
Возврат 1;
КонецЕсли;
..понравился
2. Сhe Burashka (CheBurator) 13.11.07 00:18
ага, все-таки я ее чуток подломал... ;-)
глСоздатьКаталог("c:\Еуые1\еуые2") при условии что еуые2 - существующий файл в папке Еуые1
tarasenkov; +1 Ответить
3. Сhe Burashka (CheBurator) 13.11.07 00:28
аналогично
глСоздатьКаталог("c:\Еуые1\eee*we")
+ еще Добился вывода сообщения "Невозможно создать путь:" - какой именно - не указано ;-)
tarasenkov; +1 Ответить
4. Tarasenkov (tarasenkov) 13.11.07 07:42
Вам бы только ломать :-)
Добавлена защита от взлома :-)
+ Спасибо за конструктивные замечания
5. Сhe Burashka (CheBurator) 13.11.07 12:12
Ну, вообще-то представляется более праивльным искать запрещенные символы в именах каталогов, а не наоборот.. потому как правило, вложенный путь каталогво больше 10 запрещенных символов... ;-) Это я так, побрюзжать...
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа