gifts2017

Рекурсивный поиск каталога среди каталогов.

Опубликовал Николай (betepon) в раздел Администрирование - Поиск данных

Внимание особо умных. Предложенная процедура актуальна для конфигураций на платформе 8.1 и ниже.
В них для функции НайтиФайлы не был реализован рекурсивный поиск в подкаталогах.
Это указано в справке.

Задача
Найти путь к  вложенному каталогу.
Пример

Каталог AST содержит каталоги A1, S1, T1
Каталог A1 содержит каталоги 0001, 0002, 0003
каталог S1 содержит каталоги 1001, 1002, 1003
Каталог Т1 содержит каталоги 2001, 2002, 2003

На входе функции КорневойКаталог = "D:\AST"
                            КаталогПоиска = "1002"
На выходе функции НайденныйПуть = "D:\AST\A1\1002"

Уточнение - имена КаталогПоиска уникальны и не повторяются.
Функция НайтиФайлы не помогает - она ищет их только в текущем каталоге.
Перем СписокКаталогов ;

Функция ФайлСуществует (Знач ПутьКФайлу) Экспорт
    Файл = Новый Файл (ПутьКФайлу);
    Возврат Файл.Существует();
КонецФункции

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

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

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

См. также

Подписаться Добавить вознаграждение
Комментарии
1. Oleg (Romeo_1c_programmer) 19.09.14 15:42
Данная задача решается проще с использованием функции "Найти файлы". Пример кода:

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

...Показать Скрыть
Прикрепленные файлы:
ПоискКаталога.epf
kostyaomsk; DitriX; BigB; +3 Ответить 2
2. Дмитрий Шерстобитов (DitriX) 20.09.14 13:07
Это называется - не люблю читать внимательно справку :)
3. Константин Юрин (kostyaomsk) 21.09.14 14:04
(1) Romeo_1c_programmer, конечно, поглядим на практике когда возникнет необходимость поиска. Нужны разные идеи и алгоритмы. Хотя в 1С стараются не доводить до того чтоб заниматься сложным поиском. Итак проблем хватает с путями на FTP.
4. Николай (betepon) 30.09.14 18:26
(1) Romeo_1c_programmer, (2) DitriX,
Попробуйте процедуру от Romeo_1c_programmer использовать в 8.1
Вас, как и меня, ожидает СЮРПРИЗ - она не работает. "Ошибка - слишком много параметров" ;)))
А правильный синтаксис для 8.1 выглядит так
Результат = НайтиФайлы(Путь, "*");
Но поиск будет производится только в каталоге (Путь). Это написано в справке. И во внутренние каталоги НайтиФайлы () заглянуть не может :))).
Это реализовано только начиная с 8.2

Не волнуйтесь - не Вы первые подсказываете заглянуть в справку и написать код, как это сделал Romeo_1c_programmer.
И не Вы последние ошибаетесь.

Так что для конфигураций ниже 8.2 этот алгоритм пока единственный.