План работы:
- Подключаемся к FTP серверу на основании обязательных данных (адрес сервера, имя пользователя)
- Опрашиваем каждую папку сервера на предмет совпадения по максе с помощью рекурсии
- Выводим полученные данные в табличный документ.
Подключаемся к ftp серверу:
&НаКлиенте
Функция ПодключитьсяКFTPСерверу(ИмяУзла = "", Порт = 21, ИмяПользователя = "anonymous", Пароль = "pochta@mail.ru", ПассивноеСоединение = Ложь, ТаймАут = 10)
Попытка
Состояние("Подключаюсь к FTP серверу ...");
ФТП = Новый FTPСоединение( ИмяУзла,
Порт,
"",
"",
,
ПассивноеСоединение,
ТаймАут);
Исключение
Возврат ОписаниеОшибки();
КонецПопытки;
Возврат ФТП;
КонецФункции
Все реквизиты необходимые для подключения функция получает через параметры. Это делает функцию универсальной. В операторных скобках "попытка" выполняется подключение к FTP серверу и в случае удачи возвращает объект FTP. Если в процессе подключения возникли ошибки, то функция вернёт строку с содержанием этой ошибки. К серверу подключились можно переходить ко 2 части плана, а именно рекурсивному опросу.
&НаКлиенте
//перебирает файлы на ФТП сервере рекурсивно
Процедура ПолучитьФайлыРекурсивно(ФТП = Неопределено, Каталог = "", МаскаФайлов = Неопределено)
//без соединения опрашивать будет нечего
Если ФТП = Неопределено Тогда
Возврат;
КонецЕсли;
Состояние("Веду опрос каталога: " + Каталог);
Попытка
МасивFTPФайлов = ФТП.НайтиФайлы(Каталог,
"*",
Ложь);
Исключение
Сообщить(
"Во время рекурсивного поиска файлов произошла исключительная ситуация:" +
ОписаниеОшибки(),
СтатусСообщения.Важное);
Возврат;
КонецПопытки;
Для Каждого ЭлементМассива Из МасивFTPФайлов Цикл
Если ЭлементМассива.ЭтоФайл() Тогда
Если МаскаФайлов.НайтиПоЗначению("*" + ЭлементМассива.Расширение) <> Неопределено Тогда
СтрокаТЗ = Объект.Файлы.Добавить();
СтрокаТЗ.Путь = "ftp://" + ФТП.Сервер + ЭлементМассива.Путь + ЭлементМассива.Имя;
СтрокаТЗ.РасширениеФайла = ЭлементМассива.Расширение;
СтрокаТЗ.ДатаПоследнегоИзменения = ЭлементМассива.ПолучитьВремяИзменения();
СтрокаТЗ.Размер = Окр(ЭлементМассива.Размер() / 1024, 2);
КонецЕсли;
ИначеЕсли ЭлементМассива.ЭтоКаталог()
И ЭлементМассива.ПолноеИмя <> Лев(Каталог, СтрДлина(Каталог) - 1)
И ЭлементМассива.Имя <> "."
И ЭлементМассива.Имя <> ".." Тогда
ПолучитьФайлыРекурсивно(ФТП, ЭлементМассива.ПолноеИмя, МаскаФайлов);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Понять как работает рекурсивная процедура проще всего по схеме:
Так как в массиве файлов, возвращаемым методом НайтиФайлы, есть и каталоги и файлы мы не выйдем из цикла пока не будет ни единого каталога. То есть мы опросим весь сервер. В процессе работы выполняется и 3 пункт нашей программы - заполнение табличной части информацией. Осталось только увязать наши механизмы в управляющей процедуре.
&НаКлиенте
Процедура ОпроситьFTP(Команда)
ФТП = ПодключитьсяКFTPСерверу( Объект.FTPСервер,
Объект.Порт,
Объект.ИмяПользователя,
Объект.Пароль,
Объект.ПассивноеСоединение,
Объект.ТаймАут);
Если ТипЗнч(ФТП) <> Тип("Строка") Тогда
СтрокаМасок = Объект.МаскаФайлов;
СписокМасок = РазбитьСтрокуНаПодстроки(СтрокаМасок, ";");
Объект.Файлы.Очистить();
ПолучитьФайлыРекурсивно(ФТП, Объект.ОтносительныйКаталог, СписокМасок);
Элементы.Закладки.ТекущаяСтраница = Элементы.РезультатыОпроса;
//Элементы.Файлы.Обновить();
//Сообщить("Нашлось: " + Объект.Файлы.Количество());
Иначе
Предупреждение(ФТП, 10);
КонецЕсли;
КонецПроцедуры
Вотсобственно и всё. В качестве бонуса приведу процедурку выгружающую результаты опроса в эксель.
&НаКлиенте
Процедура ВыгрузитьВЭксель(Команда)
Экс = Новый COMОбъект("excel.application");
Книга = Экс.Workbooks.add();
//удалим не нужные листы
Для н = -Книга.Worksheets.Count По -2 Цикл
Книга.Worksheets(1).Delete();
КонецЦикла;
Лист = Книга.Worksheets(1);
Лист.Cells(1, 1).Value = "Путь";
Лист.Cells(1, 2).Value = "Тип";
Лист.Cells(1, 3).Value = "Изменён";
Лист.Cells(1, 4).Value = "Размер (кб)";
Лист.Range(Лист.Cells(1, 1), Лист.Cells(1, 4)).Font.Bold = Истина;
Лист.Range(Лист.Cells(1, 1), Лист.Cells(1, 4)).Font.Size = 16;
Лист.Range(Лист.Cells(1, 1), Лист.Cells(1, 4)).Interior.ColorIndex = 24;
Лист.Name = "Содержимое FTP " + Объект.FTPСервер;
Для Каждого СтрокаТЗ Из Объект.Файлы Цикл
Лист.Cells(СтрокаТЗ.НомерСтроки + 1, 1).Value = СтрокаТЗ.Путь;
Лист.Cells(СтрокаТЗ.НомерСтроки + 1, 2).Value = Сред(СтрокаТЗ.РасширениеФайла, 2);
Лист.Cells(СтрокаТЗ.НомерСтроки + 1, 3).Value = СтрокаТЗ.ДатаПоследнегоИзменения;
Лист.Cells(СтрокаТЗ.НомерСтроки + 1, 4).Value = СтрокаТЗ.Размер;
//для чётных строк
МаркерЧётности = (СтрокаТЗ.НомерСтроки + 1) / 2;
Если МаркерЧётности = Цел(МаркерЧётности) Тогда
Область = Лист.Range(Лист.Cells(СтрокаТЗ.НомерСтроки + 1, 1), Лист.Cells(СтрокаТЗ.НомерСтроки + 1, 4));
Область.Interior.ColorIndex = 17;
КонецЕсли;
КонецЦикла;
Лист.UsedRange().Columns.AutoFit();
Экс.visible = Истина;
КонецПроцедуры
Хочу обратить ваше внимание на то, что настройки удалённого ftp сервера могут иметь свои особенности. Например можно запретить анонимному пользователю заходить в папки ниже 3 уровня вложенности, или ограничить по трафику в 200 кб. В связи с этим можно наблюдать не адекватность при выполнении обработки. Сама обработка представлена как показательный рекурсивный механизм и не преследует цель обработать все возможные исключительные ситуации в роботе по протоколу FTP.