К статье
Практический материал

Разработка и Конфигурация · 9 мин

Как получить каталог файла в 1С

Как получить каталог файла в 1С: разбор пути через СтрНайти, работа с объектом Файл, отличия Windows и Linux, типовые ошибки и готовые примеры кода.

Задача получить каталог файла в 1С возникает постоянно: при сохранении выгрузок рядом с исходным файлом, при обработке пакета документов из одной папки, при формировании отчётов с выгрузкой на диск. Встроенной функции «ПолучитьКаталогФайла» во встроенном языке платформы нет, поэтому каталог извлекают либо строковыми операциями, либо через объект Файл.

Оба подхода рабочие, но ведут себя по-разному: строковый разбор не обращается к диску и быстр, а объект Файл даёт дополнительные сведения, но требует осторожности на тонком клиенте и в веб-клиенте. Ниже — конкретные варианты кода, их ограничения и способы проверки результата.

Отдельная тонкость — разделитель пути. На Windows это обратный слэш «\», на Linux-сервере 1С — прямой «/». Если код должен работать на обеих платформах, разделитель нужно определять программно, иначе разбор пути «сломается» при переносе базы на другой сервер.

Что именно считается каталогом файла

Полный путь к файлу состоит из каталога (пути к папке) и имени файла с расширением. Например, в пути C:\Выгрузки\Отчеты\отчет.xlsx каталог — это C:\Выгрузки\Отчеты\, а имя файла — отчет.xlsx. Задача — отделить одно от другого.

Важный нюанс: файл с полным путём может не существовать на диске — путь бывает просто строкой, полученной из настроек, реквизита справочника или ввода пользователя. Строковый разбор работает с любым путём, а обращение к диску за атрибутами — только с реально существующим файлом.

Способ 1: разбор строки через СтрНайти с поиском с конца

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

Функция ПолучитьКаталогФайла(ПолныйПуть) Экспорт

Разделитель = ПолучитьРазделительПути();

Позиция = СтрНайти(ПолныйПуть, Разделитель, НаправлениеПоиска.СКонца);

Если Позиция = 0 Тогда

Возврат ""; // разделителя нет — передано только имя файла

КонецЕсли;

Возврат Лев(ПолныйПуть, Позиция);

КонецФункции

Функция возвращает каталог вместе с завершающим разделителем — это удобно, потому что к результату можно сразу «приклеить» новое имя файла: Каталог + "результат.xml". Если разделитель в конце не нужен, используйте Лев(ПолныйПуть, Позиция - 1).

1c
Каталог = ПолучитьКаталогФайла("C:\Выгрузки\отчет.xlsx");
// Результат: C:\Выгрузки\
НовыйФайл = Каталог + "архив.zip";

Обработайте крайние случаи: пустая строка, путь без разделителя (только имя файла), путь, заканчивающийся на разделитель (это уже каталог, а не файл). В последнем случае функция вернёт исходную строку — обычно это корректно, но зависит от логики вашей обработки.

Способ 2: объект Файл и свойство Путь

Объект Файл предоставляет готовые свойства: Путь (каталог без имени файла), Имя (имя с расширением), ИмяБезРасширения, Расширение. Код получается короче и читаемее.

Файл = Новый Файл("C:\Выгрузки\Отчеты\отчет.xlsx");

Каталог = Файл.Путь; // C:\Выгрузки\Отчеты\

ИмяФайла = Файл.Имя; // отчет.xlsx

Расширение = Файл.Расширение; // .xlsx

Конструктор Новый Файл не требует, чтобы файл существовал на диске — свойства пути разбираются строково. Однако на тонком и веб-клиенте работа с файловой системой ограничена: обращение к локальным путям возможно только в режиме модальных вызовов или после подключения расширения работы с файлами. На сервере ограничений нет, но пути будут серверными, а не клиентскими — это частая причина ошибок в клиент-серверном режиме.

Учёт разделителя пути на Windows и Linux

Если база работает только на Windows, можно искать «\» напрямую. Но при кластере на Linux или при смешанной среде (сервер на Linux, клиенты на Windows) зашитый разделитель приведёт к ошибкам: СтрНайти не найдёт «\» в пути вида /opt/1c/data/file.xml и вернёт 0.

Функция ПолучитьРазделительПути() возвращает разделитель той системы, где выполняется код. Учтите: на сервере и на клиенте разделители могут отличаться, поэтому разбирайте путь там, где он был получен. Если путь пришёл от клиента на сервер — передавайте вместе с ним разделитель клиента или нормализуйте путь заранее.

Сравнение способов

Сравнение вариантов

СтрНайти + Лев

Универсально, работает с любой строкой пути, не зависит от контекста выполнения. Требует вручную обрабатывать крайние случаи.

Объект Файл

Короткий читаемый код, сразу даёт имя, расширение и путь. На тонком и веб-клиенте ограничен, требует осторожности в клиент-серверном режиме.

СтрРазделить по разделителю

Подходит, когда нужны все уровни вложенности пути. Избыточен, если нужен только каталог, и требует склейки массива обратно.

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

Проверка результата и типичные ошибки

После получения каталога полезно убедиться, что он существует и доступен на запись, особенно если дальше планируется сохранение файла. Для этого создайте объект Файл от каталога и вызовите Существует(), а для проверки записи — попробуйте создать временный файл и удалить его.

Контрольные точки

Как проверить результат

Строка каталога не пустая
Норма

Содержит путь с завершающим разделителем

Тревожный признак

Пустая строка — в исходном пути не было разделителя

Каталог существует
Норма

Файл.Существует() возвращает Истина

Тревожный признак

Ложь — путь указан неверно или сетевая папка недоступна

Разделитель соответствует системе
Норма

На Windows — «\», на Linux — «/»

Тревожный признак

Смешанные разделители в одном пути — признак ручной склейки строк

Типичные ошибки
01
Зашитый разделитель «\» — код перестаёт работать на Linux-сервере
02
Поиск первого слэша вместо последнего — каталог обрезается по первому уровню вложенности
03
Разбор клиентского пути на сервере — файл не находится, потому что диск C: сервера и клиента разные
04
Отсутствие проверки пустого результата — дальнейшая склейка даёт путь вида «отчет.xlsx» без каталога и файл падает в рабочий каталог программы

Практические сценарии применения

Сохранение результата рядом с исходным файлом

Типовая задача обработок: пользователь выбрал файл, результат нужно положить в ту же папку. Получите каталог, добавьте новое имя, проверьте доступность записи — и только потом сохраняйте.

Порядок действий
  1. 1
    Получите полный путь от пользователя через ДиалогВыбораФайла или из реквизита
  2. 2
    Извлеките каталог функцией ПолучитьКаталогФайла
  3. 3
    Проверьте, что каталог не пустой и существует
  4. 4
    Склейте каталог с новым именем файла
  5. 5
    Сохраните результат и сообщите пользователю итоговый путь

Обход всех файлов в каталоге

Если нужно обработать все файлы папки, используйте НайтиФайлы(Каталог, "*.xml") — функция вернёт массив объектов Файл, у каждого уже есть свойства ПолноеИмя и Путь. Второй параметр — маска, третий (Истина) включает поиск во вложенных папках.

Выносите функцию получения каталога в общий модуль с признаком «Сервер» и «Вызов сервера» — тогда один и тот же код будет доступен из любых обработок, и не придётся дублировать разбор пути в каждой процедуре.
ПЗ
Практическое замечание
Итог

Что важно запомнить

Каталог извлекается поиском последнего разделителя через СтрНайти с направлением СКонца либо свойством Путь объекта Файл. Разделитель получайте программно, разбирайте путь в том контексте, где он получен, и проверяйте результат перед записью файлов.

Частые вопросы

Есть ли в 1С готовая функция для получения каталога файла?

Отдельной встроенной функции нет. Ближайший готовый вариант — объект Файл со свойством Путь. В типовых конфигурациях на БСП есть аналогичные функции в общих модулях работы с файлами, но они внутри используют те же строковые операции.

Как получить каталог, если путь введён пользователем вручную и может содержать ошибки?

Сначала проверьте, что строка не пустая и содержит разделитель. После извлечения каталога создайте объект Файл и вызовите Существует() — это отсечёт опечатки в пути до попытки записи.

Почему на сервере код не находит файл, хотя на клиенте всё работает?

Потому что сервер 1С видит свою файловую систему, а не диски пользователя. Путь C:\Документы\... существует только на клиенте. Передавайте файл на сервер через временное хранилище (ПоместитьВоВременноеХранилище) и работайте с данными, а не с путём.

Как получить каталог на уровень выше (родительскую папку)?

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

Работает ли разбор пути в веб-клиенте?

Строковый разбор (СтрНайти, Лев) работает везде, включая веб-клиент, потому что не обращается к диску. Объект Файл в веб-клиенте требует подключения расширения работы с файлами и асинхронных вызовов.

Что вернёт функция, если передан сетевой путь вида \\server\share\file.txt?

Корректно вернёт \\server\share\ — последний разделитель находится перед именем файла независимо от того, локальный путь или сетевой. Учитывайте только, что доступ к сетевой папке проверяется отдельно и зависит от прав учётной записи, под которой работает 1С.