Имя, расширение и каталог из строки пути: разбор средствами 1С:Предприятия 8.3
Содержание
Чтобы получить имя файла из полного пути в 1С, создайте объект Файл и прочитайте его свойство Имя: Новый Файл("C:\Выгрузка\Отчет.xlsx").Имя вернёт Отчет.xlsx. Свойства ИмяБезРасширения, Расширение и Путь дадут остальные части строки. Сам файл на диске для этого не нужен: платформа просто разбирает строку.
Объект Файл закрывает обычные задачи. Сбои начинаются, когда путь пришёл с другой операционной системы, строка оказалась URL с параметрами или путь заканчивается разделителем. Для таких строк надёжнее своя функция на строковых методах: она работает одинаково на клиенте и на сервере.
Чем платформа 1С помогает при работе с путями
В 1С:Предприятии 8.3 нет одной функции вида «ИмяФайлаИзПути()». Задачу решают тремя группами средств.
- 📁 Объект
Файл— разбирает полное имя файла на части и умеет проверять файл на диске. - 🔤 Строковые функции —
СтрНайти,СтрРазделить,Сред,Лев,Прав,СтрДлина. Дают полный контроль над разбором. - 🧩 Библиотека стандартных подсистем (БСП) — в типовых конфигурациях есть готовая функция
ОбщегоНазначенияКлиентСервер.РазложитьПолноеИмяФайла.
Рядом пригодятся служебные функции платформы:
| Функция | Что возвращает |
|---|---|
ПолучитьРазделительПути() | Разделитель пути для ОС, где выполняется код: \ в Windows, / в Linux |
ПолучитьРазделительПутиКлиента() | Разделитель на компьютере пользователя |
ПолучитьРазделительПутиСервера() | Разделитель на сервере 1С |
КаталогВременныхФайлов() | Каталог временных файлов текущего сеанса |
ПолучитьИмяВременногоФайла("xml") | Полное имя уникального временного файла с заданным расширением |
Разделитель не «зашивайте» в код как "\". Если база когда-нибудь переедет на сервер под Linux, код со склеиванием Каталог + "\" + Имя начнёт создавать файлы с обратной косой чертой в названии.
Из чего состоит полное имя файла
Возьмём строку C:\Обмен\2026\Выгрузка.данные.xml и посмотрим, как её видит платформа.
| Часть | Свойство объекта Файл | Значение |
|---|---|---|
| Полное имя | ПолноеИмя | C:\Обмен\2026\Выгрузка.данные.xml |
| Каталог | Путь | C:\Обмен\2026\ |
| Имя с расширением | Имя | Выгрузка.данные.xml |
| Имя без расширения | ИмяБезРасширения | Выгрузка.данные |
| Расширение | Расширение | .xml |
Три детали, на которых чаще всего ошибаются:
- Расширение возвращается с точкой.
.xml, а неxml. СравнениеРасширение = "xml"никогда не дастИстина. - Путь заканчивается разделителем. Склеивать его с именем нужно без дополнительного
\:Путь + Имя. - Расширение — это всё после последней точки. У файла
archive.tar.gzрасширение.gz, а имя без расширения —archive.tar.
Регистр символов платформа не меняет. Если пользователь сохранил файл как ОТЧЕТ.XLSX, свойство Расширение вернёт .XLSX. Для проверок приводите строку к нижнему регистру через НРег().
Как извлечь имя файла в коде: рабочие примеры
Способ 1. Объект Файл
Самый короткий и читаемый вариант:
ПолноеИмяФайла = "C:\Обмен\2026\Выгрузка.данные.xml";
ФайлНаДиске = Новый Файл(ПолноеИмяФайла);
ИмяФайла = ФайлНаДиске.Имя; // Выгрузка.данные.xml
ИмяБезРасширения = ФайлНаДиске.ИмяБезРасширения; // Выгрузка.данные
Расширение = ФайлНаДиске.Расширение; // .xml
Каталог = ФайлНаДиске.Путь; // C:\Обмен\2026\
Проверка расширения без учёта регистра и без точки:
РасширениеБезТочки = НРег(Сред(ФайлНаДиске.Расширение, 2));
Если РасширениеБезТочки = "xml" Тогда
// загружаем как XML
КонецЕсли;
Сред(Строка, 2) отрезает первый символ — точку. Если расширения нет, свойство вернёт пустую строку, и Сред тоже вернёт пустую строку, ошибки не будет.
Способ 2. Поиск последнего разделителя через СтрНайти
С платформы 8.3.6 у СтрНайти есть параметр направления поиска. Ищем последний разделитель с конца строки и берём всё, что после него. Функция учитывает оба разделителя, поэтому одинаково разбирает пути Windows и Linux на любой ОС.
Функция ИмяФайлаИзПути(Знач ПолноеИмяФайла) Экспорт
ПолноеИмяФайла = СокрЛП(ПолноеИмяФайла);
ПозицияОбратной = СтрНайти(ПолноеИмяФайла, "\", НаправлениеПоиска.СКонца);
ПозицияПрямой = СтрНайти(ПолноеИмяФайла, "/", НаправлениеПоиска.СКонца);
ПозицияРазделителя = Макс(ПозицияОбратной, ПозицияПрямой);
// Если разделителя нет, позиция 0 и вернётся вся строка
Возврат Сред(ПолноеИмяФайла, ПозицияРазделителя + 1);
КонецФункции
Проверим на примерах:
| Входная строка | Результат |
|---|---|
C:\Обмен\Выгрузка.xml | Выгрузка.xml |
/home/usr1cv8/upload/price.csv | price.csv |
\\srv-files\share\Акт.pdf | Акт.pdf |
Акт.pdf | Акт.pdf |
C:\Обмен\ | пустая строка |
Последняя строка — это не ошибка функции, а честный ответ: в пути нет имени файла, это каталог.
Способ 3. Расширение и имя без расширения своими силами
Дополним функцию разбором по последней точке:
Функция РазобратьИмяФайла(Знач ПолноеИмяФайла) Экспорт
Результат = Новый Структура("Каталог, Имя, ИмяБезРасширения, Расширение", "", "", "", "");
ПолноеИмяФайла = СокрЛП(ПолноеИмяФайла);
ПозицияРазделителя = Макс(
СтрНайти(ПолноеИмяФайла, "\", НаправлениеПоиска.СКонца),
СтрНайти(ПолноеИмяФайла, "/", НаправлениеПоиска.СКонца));
Результат.Каталог = Лев(ПолноеИмяФайла, ПозицияРазделителя);
Результат.Имя = Сред(ПолноеИмяФайла, ПозицияРазделителя + 1);
ПозицияТочки = СтрНайти(Результат.Имя, ".", НаправлениеПоиска.СКонца);
Если ПозицияТочки > 1 Тогда
Результат.ИмяБезРасширения = Лев(Результат.Имя, ПозицияТочки - 1);
Результат.Расширение = НРег(Сред(Результат.Имя, ПозицияТочки + 1));
Иначе
Результат.ИмяБезРасширения = Результат.Имя;
КонецЕсли;
Возврат Результат;
КонецФункции
Для C:\Обмен\Акт.сверки.PDF функция вернёт: каталог C:\Обмен\, имя Акт.сверки.PDF, имя без расширения Акт.сверки, расширение pdf — без точки и в нижнем регистре, как удобно для сравнений.
Условие ПозицияТочки > 1 отсекает имена, которые начинаются с точки, вроде .gitignore или .htaccess. Такую строку функция считает именем без расширения.
Способ 4. СтрРазделить — когда нужны все уровни пути
СтрРазделить режет строку по каждому символу из второго параметра. Передаём оба разделителя сразу:
Части = СтрРазделить("D:\Архив\2025\Декабрь\Реестр.xlsx", "\/", Ложь);
// Части[0] = "D:", Части[1] = "Архив", ..., Части[4] = "Реестр.xlsx"
Если Части.Количество() > 0 Тогда
ИмяФайла = Части[Части.ВГраница()];
КонецЕсли;
Третий параметр Ложь выбрасывает пустые элементы. Из-за этого у пути с завершающим разделителем D:\Архив\2025\ последним элементом станет 2025 — имя последней папки. Это удобно, когда нужно именно имя каталога, и опасно, когда вы ждёте имя файла.
Способ 5. Платформа до 8.3.6 или старый режим совместимости
Если СтрНайти с направлением поиска недоступна, пройдите строку с конца циклом:
Функция ИмяФайлаИзПутиЦиклом(Знач ПолноеИмяФайла) Экспорт
ДлинаСтроки = СтрДлина(ПолноеИмяФайла);
Для Сч = 1 По ДлинаСтроки Цикл
Позиция = ДлинаСтроки - Сч + 1;
Символ = Сред(ПолноеИмяФайла, Позиция, 1);
Если Символ = "\" Или Символ = "/" Тогда
Возврат Сред(ПолноеИмяФайла, Позиция + 1);
КонецЕсли;
КонецЦикла;
Возврат ПолноеИмяФайла;
КонецФункции
Цикл идёт от последнего символа к первому и останавливается на первом встреченном разделителе. Строки путей короткие, так что по скорости разницы с СтрНайти вы не заметите.
Получение имени файла на клиенте и на сервере
Объект Файл доступен и на клиенте, и на сервере. Но выполняется он там, где выполняется код, и разделитель берёт от этой ОС. Отсюда главная ловушка.
Сценарий: пользователь в Windows выбрал файл C:\Загрузка\Прайс.xlsx. Клиент передал строку на сервер, сервер работает под Linux. На сервере Новый Файл(Строка).Имя разбирает строку по правилам Linux, где \ — обычный символ, а не разделитель. Результат может оказаться не тем, что вы ждали.
Как избежать:
- ✅ Разбирайте путь на клиенте, где он получен, и передавайте на сервер уже готовое имя файла.
- ✅ Если разбор нужен на сервере — используйте функцию из способа 2, которая ищет оба разделителя.
- ✅ Не передавайте на сервер путь клиента как место, откуда читать файл. Сервер не видит диск пользователя. Файл передают через временное хранилище, а имя — отдельным параметром.
Веб-клиент и выбор файла пользователем
В веб-клиенте браузер не отдаёт странице реальный путь к файлу на компьютере пользователя. Поэтому строим логику не на разборе полного пути, а на имени, которое возвращает платформа при помещении файла.
В актуальных версиях платформы метод ПоместитьФайлНаСерверАсинх возвращает ОписаниеПомещенногоФайла. У него есть свойство СсылкаНаФайл, а у неё — Имя и Расширение. Это и есть то, что нужно сохранить вместе с двоичными данными:
&НаКлиенте
Асинх Процедура ЗагрузитьФайл(Команда)
Описание = Ждать ПоместитьФайлНаСерверАсинх(, , , , УникальныйИдентификатор);
Если Описание = Неопределено Или Описание.ПомещениеФайлаОтменено Тогда
Возврат;
КонецЕсли;
ИмяФайла = Описание.СсылкаНаФайл.Имя;
ЗагрузитьНаСервере(Описание.Адрес, ИмяФайла);
КонецПроцедуры
Синхронные методы проверки файла на диске (Существует(), ЭтоФайл(), Размер()) в веб-клиенте без расширения работы с файлами не работают. Свойства Имя, Расширение, Путь к диску не обращаются, но для проверок в клиентском коде используйте асинхронные варианты: СуществуетАсинх(), ЭтоФайлАсинх().
Тонкий клиент и ДиалогВыбораФайла
В тонком клиенте диалог выбора отдаёт полный путь. Пример с асинхронным показом диалога:
&НаКлиенте
Асинх Процедура ВыбратьФайл(Команда)
Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
Диалог.Фильтр = "Таблицы Excel (*.xlsx)|*.xlsx";
ВыбранныеФайлы = Ждать Диалог.ВыбратьАсинх();
Если ВыбранныеФайлы = Неопределено Тогда
Возврат;
КонецЕсли;
Для Каждого ПолноеИмя Из ВыбранныеФайлы Цикл
Сообщить(Новый Файл(ПолноеИмя).Имя);
КонецЦикла;
КонецПроцедуры
У самого диалога есть свойство Каталог — папка, из которой выбирали файлы. Оно пригодится, чтобы при следующем открытии диалога начать с той же папки.
Нестандартные строки и обработка ошибок разбора
Разбор строки ошибок не вызывает. Проблема в другом: функция тихо возвращает не то значение, и дальше по коду сохраняется файл с пустым или кривым именем. Проверяйте результат до использования.
Что встречается на практике:
- 🔚 Путь заканчивается разделителем.
C:\Обмен\— это каталог. Перед разбором решите, что вам нужно: имя файла (тогда пустая строка — повод остановиться) или имя папки (тогда уберите завершающий разделитель и разбирайте снова). - ␣ Пробелы и переводы строк. Путь, скопированный из письма или ячейки Excel, часто несёт пробел или
Символы.ПСв конце.СокрЛП()в начале функции снимает проблему. - 🔗 URL вместо пути. У строки
https://site.ru/files/price.xlsx?v=3имя файла — до вопросительного знака. Отрежьте параметры перед разбором. - 🔀 Смешанные разделители.
C:/Обмен\Выгрузка.xml— функция из способа 2 справится, потому что ищет максимальную позицию из двух. - 📛 Недопустимые символы. Имя, полученное из внешней системы, может содержать
:,*,?,",<,>,|. Windows такой файл не сохранит.
Отрезаем параметры URL:
ПозицияВопроса = СтрНайти(СтрокаАдреса, "?");
Если ПозицияВопроса > 0 Тогда
СтрокаАдреса = Лев(СтрокаАдреса, ПозицияВопроса - 1);
КонецЕсли;
ИмяФайла = ИмяФайлаИзПути(СтрокаАдреса);
Чистим имя от запрещённых символов перед сохранением:
Функция БезопасноеИмяФайла(Знач ИмяФайла) Экспорт
Запрещенные = "\/:*?""<>|";
Для Сч = 1 По СтрДлина(Запрещенные) Цикл
ИмяФайла = СтрЗаменить(ИмяФайла, Сред(Запрещенные, Сч, 1), "_");
КонецЦикла;
Возврат СокрЛП(ИмяФайла);
КонецФункции
Двойная кавычка внутри строки 1С записывается как "", поэтому в строке Запрещенные она одна, а в коде — две.
Проверку «имя не пустое» ставьте сразу после разбора: Если ПустаяСтрока(ИмяФайла) Тогда ... ВызватьИсключение .... Сообщение об ошибке со строкой исходного пути сэкономит время при разборе логов.
Альтернативы: БСП, НайтиФайлы и временные файлы
Готовая функция БСП
В типовых конфигурациях на Библиотеке стандартных подсистем (Бухгалтерия 3.0, ЗУП 3.1, УТ 11 и другие) есть функция ОбщегоНазначенияКлиентСервер.РазложитьПолноеИмяФайла. Она принимает полное имя и возвращает структуру с полями ПолноеИмя, Путь, Имя, Расширение, ИмяБезРасширения.
Части = ОбщегоНазначенияКлиентСервер.РазложитьПолноеИмяФайла(ПолноеИмяФайла);
ИмяФайла = Части.Имя;
Модуль клиент-серверный, так что вызов работает в любом контексте. Перед использованием откройте общий модуль в конфигураторе и посмотрите описание функции: состав параметров и формат расширения (с точкой или без) лучше проверить по своей версии БСП, а не по памяти.
НайтиФайлы: имена уже готовы
Если имена нужны для файлов из каталога, разбирать строки не придётся. НайтиФайлы возвращает массив объектов Файл, у каждого уже есть Имя и Расширение:
Найденные = НайтиФайлы("C:\Обмен\Входящие", "*.xml", Ложь);
Для Каждого НайденныйФайл Из Найденные Цикл
Сообщить(НайденныйФайл.Имя + " — " + НайденныйФайл.Путь);
КонецЦикла;
Третий параметр Ложь означает поиск без подкаталогов. Передайте Истина, чтобы обойти вложенные папки.
Временные файлы
ПолучитьИмяВременногоФайла("xlsx") возвращает полное имя в каталоге временных файлов. Если нужно только сгенерированное имя — например, чтобы записать его в журнал, — примените к результату любой способ выше. Сами временные файлы после работы удаляйте через УдалитьФайлы(), иначе они копятся на сервере.
Сравнение способов
| Способ | Когда подходит | Ограничения |
|---|---|---|
Объект Файл | Путь получен на той же машине | Разделитель берётся от ОС, где выполняется код |
СтрНайти с конца | Пути из обменов, писем, с другого сервера | Платформа 8.3.6 и новее |
СтрРазделить | Нужны все уровни пути или имя папки | Завершающий разделитель даёт имя каталога, а не файла |
| Функция БСП | Типовая конфигурация | Нет в нетиповых базах без БСП |
Цикл через Сред | Старые платформы и режимы совместимости | Больше кода |
НайтиФайлы | Работа с содержимым каталога | Только для файлов, которые реально есть на диске |
Частые ошибки разработчиков
- ❌ Сравнивают расширение без точки с результатом
Файл.Расширение. Свойство возвращает.pdf. Либо сравнивайте с точкой, либо отрежьте её черезСред(…, 2). - ❌ Считают расширением всё после первой точки. Для
Счет.от.01.10.pdfпоиск первой точки даст «расширение»от.01.10.pdf. Ищите последнюю точку. - ❌ Хранят только полный путь клиента в реквизите документа. Через месяц файл переедет, и путь станет бесполезным. Сохраняйте имя файла отдельным реквизитом, а сам файл — в присоединённых файлах или хранилище значения.
- ❌ Восстанавливают имя из
ДвоичныеДанные. Двоичные данные хранят только содержимое. Имя теряется в момент помещения во временное хранилище, если не передать его рядом.
Частые вопросы
Как получить имя каталога информационной базы?
СтрокаСоединенияИнформационнойБазы(). Она вернёт строку вида File="C:\Базы\Бухгалтерия";. Значение между кавычками после File= и есть каталог базы. Для клиент-серверной базы в строке будут Srvr и Ref — имя сервера и имя базы на нём.Как получить имя последней папки в пути?
СтрРазделить(Путь, "\/", Ложь) и возьмите последний элемент массива.Обращается ли Новый Файл к диску при чтении свойства Имя?
Имя, ИмяБезРасширения, Расширение, Путь вычисляются из строки. Файла может не быть вовсе. К диску обращаются методы Существует(), Размер(), ПолучитьВремяИзменения() и их асинхронные варианты.Как собрать полный путь обратно из каталога и имени?
Файл.Путь, он уже заканчивается разделителем: Каталог + ИмяФайла. Если каталог пришёл из настроек, проверьте последний символ через Прав(Каталог, 1) и при необходимости добавьте ПолучитьРазделительПути().Можно ли получить имя файла, который пользователь перетащил на форму?
ПараметрыПеретаскивания.Значение. Проверьте его тип в отладчике: для файлов это объект с собственным свойством Имя или массив таких объектов. Читайте имя из свойства, а не разбирайте строку.