В процессе разработки в среде 1С часто возникает задача автоматизации обработки файлов. Это может быть загрузка данных из Excel, импорт документов в формате XML или просто пакетная обработка изображений. Для реализации этой задачи необходимо пройти несколько этапов: предоставить пользователю возможность выбора папки, корректно прочитать содержимое этой папки с учетом фильтров и обработать полученный список. В этой статье мы подробно разберем, как правильно реализовать этот алгоритм, избежав типичных ошибок начинающих разработчиков.
Первым шагом в нашей задаче является интерактивный выбор папки. Для этого в платформе 1С:Предприятие 8 предусмотрен объект ДиалогВыбораФайла. Важно понимать, что этот объект универсален: он может работать как в режиме выбора одного или нескольких файлов, так и в режиме выбора каталога.
Рассмотрим процедуру настройки диалога. Проанализируем пример кода, который открывает окно выбора папки и сохраняет выбранный путь в реквизит формы:
Процедура ВыборКаталогаНачалоВыбора(Элемент, СтандартнаяОбработка)
// Отключаем стандартную обработку события, чтобы вызвать свой диалог
СтандартнаяОбработка = Ложь;
// Устанавливаем режим работы диалога - ВыборКаталога
Режим = РежимДиалогаВыбораФайла.ВыборКаталога;
ДиалогОткрытия = Новый ДиалогВыбораФайла(Режим);
ДиалогОткрытия.Заголовок = "Пожалуйста, выберите каталог для обработки файлов";
// Если пользователь нажал "Выбрать", сохраняем путь
Если ДиалогОткрытия.Выбрать() Тогда
ПутьККаталогу = ДиалогОткрытия.Каталог;
// Записываем путь в поле на форме (пример для обычных форм)
ЭлементыФормы.ПолеВводаПути.Значение = ПутьККаталогу;
КонецЕсли;
КонецПроцедуры
Обратите внимание на свойство РежимДиалогаВыбораФайла.ВыборКаталога. Если его не указать или установить ошибочно, диалог будет ожидать выбора конкретного файла, что не позволит нам получить путь к папке целиком.
После того как мы получили путь к каталогу, необходимо извлечь список файлов. Для этого используется встроенная функция НайтиФайлы. Одной из самых распространенных ошибок является игнорирование параметра "Маска". Хотя в синтакс-помощнике он может быть указан как необязательный, на практике для получения всех файлов без исключения нужно использовать символ "*".
Разберем, как ограничить поиск только файлами формата Excel. Для этого можно использовать маску "*.xls?", где вопросительный знак заменяет любой один символ (это позволит найти и .xls, и .xlsx).
Посмотрим на пример реализации поиска:
// ПутьККаталогу - строка, полученная из диалога выбора
МаскаПоиска = "*.xls?";
СписокФайлов = НайтиФайлы(ПутьККаталогу, МаскаПоиска);
Для Каждого ТекущийФайл Из СписокФайлов Цикл
// ТекущийФайл является объектом типа "Файл"
Сообщить("Найден файл: " + ТекущийФайл.Имя);
КонецЦикла;
Функция НайтиФайлы возвращает массив объектов типа Файл. Это очень удобно, так как каждый элемент массива содержит полную информацию об объекте файловой системы, а не просто строку с его именем.
Когда мы перебираем найденные файлы в цикле, нам часто требуется получить не полное имя с расширением (например, report2023.xlsx), а только его значимую часть для записи в базу данных или отображения пользователю. Выясним, как это сделать наиболее эффективно.
Объект Файл обладает рядом полезных свойств:
data.txt).data). Это именно то, что часто требуется для формирования заголовков документов в 1С.txt).Проанализируем пример кода для получения чистого имени:
Для Каждого ФайлXLS Из ФайлыОтчетности Цикл
НаименованиеДляБазы = ФайлXLS.ИмяБезРасширения;
Сообщить("Обработка файла: " + НаименованиеДляБазы);
КонецЦикла;
Иногда файлы могут быть распределены по подпапкам внутри выбранного каталога. Чтобы не писать сложные рекурсивные функции самостоятельно, воспользуемся встроенной возможностью НайтиФайлы. Третий параметр функции — ИскатьВПодкаталогах — имеет тип Булево.
Если мы установим его в Истина, система автоматически обойдет все вложенные директории:
// Поиск всех картинок во всех вложенных папках
СписокКартинок = НайтиФайлы(ПутьККаталогу, "*.png", Истина);
Помимо имен, мы можем анализировать технические параметры. Рассмотрим, как отфильтровать файлы по размеру или дате изменения. Это полезно, если нужно обработать только "свежие" данные:
Для Каждого Файл Из СписокФайлов Цикл
ДатаИзменения = Файл.ПолучитьВремяИзменения();
РазмерВБайтах = Файл.Размер();
Если (ТекущаяДата() - ДатаИзменения) < 86400 Тогда // Файлы за последние 24 часа
Сообщить("Файл " + Файл.Имя + " изменен недавно.");
КонецЕсли;
КонецЦикла;
Если ваша информационная база работает на сервере под управлением Linux или планируется использование веб-клиента, необходимо учитывать специфику операционных систем. Проанализируем ключевые отличия:
\, в то время как в Linux и для FTP-соединений — прямой слеш /. При написании кода старайтесь использовать методы платформы, которые корректно обрабатывают пути, или проверяйте среду выполнения.Doc.XLS и doc.xls — это одно и то же. В Linux это два разных файла. При задании маски поиска (например, *.XLS) на Linux-сервере файлы с расширением в нижнем регистре найдены не будут.НачатьПоискФайлов, который не "вешает" браузер пользователя на время сканирования диска.Важно помнить, где именно выполняется ваш код. Если процедура поиска запускается НаСервере, то поиск будет производиться в файловой системе сервера (где установлен сервер 1С). Если вам нужно найти файлы на компьютере пользователя, код должен выполняться НаКлиенте.
При работе в веб-клиенте для доступа к локальным файлам пользователя обязательно потребуется установка расширения работы с файлами. Без него браузер заблокирует попытку чтения содержимого папок из соображений безопасности.
Рассмотрим краткий план действий для успешного получения списка файлов:
ДиалогВыбораФайла с режимом ВыборКаталога.НайтиФайлы."*").Истина.ИмяБезРасширения для получения чистых имен файлов.Следуя этим правилам, вы сможете создать надежный и отказоустойчивый механизм обработки файлов в любой конфигурации 1С.