Полное имя, каталог и временные файлы: работа с путями во встроенном языке 1С
Содержание
Путь к файлу в 1С получают через объект Файл: Новый Файл(ПолноеИмя) раскладывает строку на каталог (Путь), имя (Имя), имя без расширения и расширение. Для служебных папок есть готовые функции: КаталогВременныхФайлов(), ПолучитьИмяВременногоФайла(), КаталогПрограммы(), КаталогДокументов(). Путь к файловой базе берут из строки соединения: НСтр(СтрокаСоединенияИнформационнойБазы(), "File").
Частое заблуждение — что путь «один на всех». В клиент-серверной 1С тот же вызов в процедуре &НаКлиенте и &НаСервере вернёт папки на разных компьютерах. Отсюда большая часть ошибок вида «файл не найден», хотя файл лежит на месте.
Всё ниже относится к платформе 8.3 и работает в любой конфигурации: БП, ЗУП, УТ или самописной. Это возможности встроенного языка, а не конкретного прикладного решения.
Объект Файл: как разложить полное имя на части
Конструктор Новый Файл(...) не читает диск. Он просто разбирает строку. Поэтому объект можно создать даже для несуществующего файла, а проверить его наличие отдельно.
ФайлОтчета = Новый Файл("C:\Выгрузки\2026\Остатки.xlsx");
ПолноеИмя = ФайлОтчета.ПолноеИмя; // C:\Выгрузки\2026\Остатки.xlsx
Каталог = ФайлОтчета.Путь; // C:\Выгрузки\2026\
ИмяФайла = ФайлОтчета.Имя; // Остатки.xlsx
ИмяБезРасширения = ФайлОтчета.ИмяБезРасширения; // Остатки
Расширение = ФайлОтчета.Расширение; // .xlsx
Если ФайлОтчета.Существует() Тогда
Размер = ФайлОтчета.Размер();
Изменен = ФайлОтчета.ПолучитьВремяИзменения();
КонецЕсли;
Что стоит запомнить про свойства:
- 📁
Путьвозвращает каталог с завершающим разделителем. Склеивать его с именем можно без лишнего"\". - 🔤
Расширениесодержит точку:.xlsx, а неxlsx. - 🔍
Существует(),ЭтоФайл(),ЭтоКаталог()иРазмер()— уже обращение к диску. Вызывайте их там, где файл реально доступен.
Начиная с 8.3.18 у методов есть асинхронные пары: СуществуетАсинх(), ЭтоКаталогАсинх() и другие. На клиенте при запрете модальности и синхронных вызовов используйте их с Ждать:
&НаКлиенте
Асинх Процедура ПроверитьФайл(Команда)
ФайлЗагрузки = Новый Файл(ПутьКФайлу);
Если Не Ждать ФайлЗагрузки.СуществуетАсинх() Тогда
Сообщить("Файл не найден: " + ФайлЗагрузки.ПолноеИмя);
Возврат;
КонецЕсли;
// дальше работа с файлом
КонецПроцедуры
Разбор пути без объекта Файл
Иногда нужен только каталог из строки, а создавать объект не хочется. Ищем последний разделитель с конца строки:
Разделитель = ПолучитьРазделительПути();
Позиция = СтрНайти(ПолноеИмя, Разделитель, НаправлениеПоиска.СКонца);
Каталог = Лев(ПолноеИмя, Позиция); // с разделителем на конце
ИмяФайла = Сред(ПолноеИмя, Позиция + 1);
СтрНайти с направлением поиска доступна с 8.3.6. Функция ПолучитьРазделительПути() вернёт \ в Windows и / в Linux — жёстко прописанный обратный слеш сломается на Linux-сервере.
Временный каталог и служебные папки
Для промежуточных файлов (выгрузка в Excel, распаковка архива, сохранение вложения) не нужно придумывать свою папку. Платформа сама даёт временный каталог текущего пользователя ОС.
| Функция | Что возвращает | Пример результата в Windows |
|---|---|---|
КаталогВременныхФайлов() | Временная папка пользователя ОС, под которым идёт код | C:\Users\buh\AppData\Local\Temp\ |
ПолучитьИмяВременногоФайла("xlsx") | Полное имя нового уникального файла в этой папке | ...\Temp\v8_3A1F_12.xlsx |
КаталогДокументов() | «Документы» пользователя (на клиенте) | C:\Users\buh\Documents\ |
РабочийКаталогДанныхПользователя() | Рабочая папка 1С в профиле пользователя | папка внутри AppData |
КаталогПрограммы() | Каталог bin запущенной платформы | C:\Program Files\1cv8\8.3.24.1548\bin\ |
Типовой шаблон работы с временным файлом:
ИмяВременного = ПолучитьИмяВременногоФайла("xlsx");
ТабличныйДокумент.Записать(ИмяВременного, ТипФайлаТабличногоДокумента.XLSX);
ДвоичныеДанные = Новый ДвоичныеДанные(ИмяВременного);
// ... отправка, сохранение во вложение и т. п.
Попытка
УдалитьФайлы(ИмяВременного);
Исключение
// файл может быть ещё занят, например антивирусом — не роняем обработку
КонецПопытки;
Расширение в ПолучитьИмяВременногоФайла передают без точки. Если передать ".xlsx", на конце окажутся две точки.
Не рассчитывайте, что платформа сама подчистит временные файлы. Удаляйте их кодом сразу после использования. На сервере за месяц работы мусор в Temp легко дорастает до гигабайтов.
Отдельный каталог лучше создавать внутри временного, а не в корне диска. Права на запись туда есть у любого пользователя, а путь не зависит от того, на каком компьютере стоит клиент:
КаталогРаботы = КаталогВременныхФайлов() + "Обмен_" + Строка(Новый УникальныйИдентификатор);
СоздатьКаталог(КаталогРаботы);
// ...
УдалитьФайлы(КаталогРаботы);
Клиент и сервер: почему один вызов даёт два разных пути
В файловом варианте базы клиент и «сервер» работают на одном компьютере. Код &НаСервере видит те же диски, что и пользователь. Поэтому ошибка проявляется только при переносе базы на сервер 1С.
В клиент-серверном варианте:
- Код в
&НаКлиентевыполняется на компьютере пользователя.КаталогВременныхФайлов()вернёт Temp этого пользователя. - Код в
&НаСерверевыполняется в рабочем процессе на сервере 1С. Та же функция вернёт Temp учётной записи, от имени которой запущена служба (часто этоUSR1CV8). - Путь
C:\Выгрузки\Остатки.xlsx, выбранный пользователем, на сервере указывает на диск C: сервера, а не на его компьютер.
Путь, полученный на клиенте, нельзя напрямую передавать в серверную процедуру для чтения файла. Файл нужно передать данными:
&НаКлиенте
Процедура ЗагрузитьФайл(Команда)
// тонкий клиент: читаем файл на компьютере пользователя
Данные = Новый ДвоичныеДанные(ПутьКФайлу);
Адрес = ПоместитьВоВременноеХранилище(Данные, УникальныйИдентификатор);
ЗагрузитьНаСервере(Адрес);
КонецПроцедуры
&НаСервере
Процедура ЗагрузитьНаСервере(Адрес)
Данные = ПолучитьИзВременногоХранилища(Адрес);
ИмяНаСервере = ПолучитьИмяВременногоФайла("xlsx");
Данные.Записать(ИмяНаСервере);
// чтение файла уже по серверному пути
УдалитьФайлы(ИмяНаСервере);
КонецПроцедуры
Обратный путь (с сервера пользователю): сервер кладёт ДвоичныеДанные во временное хранилище через ПоместитьВоВременноеХранилище, клиент получает адрес и сохраняет файл диалогом.
В веб-клиенте прочитать файл по пути на клиенте нельзя. Там файл помещают в хранилище методами помещения файлов с диалогом выбора — найдите их в синтакс-помощнике (Справка → Синтакс-помощник) по слову «Поместить». Принцип тот же: на сервер уходит адрес во временном хранилище, а не путь.
Веб-клиент
В браузере полного пути к файлу на компьютере пользователя вообще нет. Браузер из соображений безопасности отдаёт только имя выбранного файла и его содержимое. Код, который строит логику на C:\... из клиентского диалога, в веб-клиенте работать не будет. Опирайтесь на имя и на данные в хранилище.
Путь к базе, программе и внешней обработке
Каталог файловой информационной базы
СтрокаСоединения = СтрокаСоединенияИнформационнойБазы();
КаталогБазы = НСтр(СтрокаСоединения, "File");
Если ПустаяСтрока(КаталогБазы) Тогда
// клиент-серверная база: каталога на диске у пользователя нет
Сервер = НСтр(СтрокаСоединения, "Srvr");
ИмяБазы = НСтр(СтрокаСоединения, "Ref");
КонецЕсли;
Для файловой базы строка соединения выглядит как File="D:\Базы\Торговля";, и НСтр достаёт из неё путь. Для серверной — Srvr="srv1c";Ref="trade";. Каталога базы там нет: данные лежат в СУБД.
Каталог исполняемых файлов платформы
КаталогПрограммы() возвращает папку bin той версии платформы, которой запущен сеанс. Это полезно, когда нужно найти рядом 1cv8.exe, comcntr.dll или утилиты платформы. На сервере функция вернёт каталог платформы сервера — версия может совпадать, а путь установки отличаться.
ИсполняемыйФайл = КаталогПрограммы() + "1cv8.exe";
Для Linux имя будет 1cv8 без расширения. Если код должен работать на обеих системах, проверяйте тип платформы через Новый СистемнаяИнформация().ТипПлатформы.
Где лежит сама внешняя обработка или отчёт
У объекта внешней обработки и внешнего отчёта есть свойство ИспользуемоеИмяФайла. Внутри модуля объекта:
ПутьКОбработке = ЭтотОбъект.ИспользуемоеИмяФайла;
КаталогОбработки = Новый Файл(ПутьКОбработке).Путь;
Типичная задача — положить рядом с .epf файл настроек или шаблон и читать его. Здесь есть подвох:
- 🖥 В файловом варианте, если обработку открыли через
Файл → Открыть, свойство обычно указывает на исходный файл. - 🌐 В клиент-серверном варианте обработка передаётся на сервер, и свойство может содержать имя временной копии или внутренний адрес, а не исходную папку пользователя.
- 🧩 Обработка, подключённая через «Дополнительные отчёты и обработки», хранится в базе. Файла на диске у неё нет вообще.
Надёжнее хранить шаблоны в макетах самой обработки: ПолучитьМакет("Шаблон") работает при любом способе запуска.
Сетевые папки и UNC-пути
Объект Файл и функции работы с файлами принимают UNC-пути вида \\fileserver\obmen\in\price.xml. Проблемы возникают не в синтаксисе, а в правах и букве диска.
| Ситуация | Что произойдёт | Как исправить |
|---|---|---|
В коде Z:\Обмен\, диск подключён у пользователя | На клиенте работает, на сервере 1С — нет | Использовать \\сервер\папка\ вместо буквы |
| UNC-путь из серверной процедуры | «Нет доступа» или файл не найден | Дать права на папку учётной записи службы 1С |
| Путь Windows на Linux-сервере | Файл не найден | Смонтировать ресурс и указать путь в формате Linux |
| Имя файла в другом регистре на Linux | Файл не найден | Хранить и сравнивать имена в одном регистре |
Почему буква диска не работает
на сервере: подключённые диски существуют в сеансе конкретного пользователя Windows. Служба сервера 1С запускается под своей учётной записью и не видит диск Z:, подключённый бухгалтером.
Права на сетевую папку выдают учётной записи, под которой запущена служба агента сервера 1С. Если это локальная учётная запись, доступ к общей папке на другом компьютере получить не получится — нужна доменная учётная запись службы.
Смена учётной записи службы сервера 1С требует её перезапуска. Перезапуск оборвёт сеансы всех пользователей — делайте это вне рабочего времени и после предупреждения.
Перед чтением из сетевой папки полезно проверить доступ отдельно, чтобы дать пользователю внятное сообщение:
Каталог = Новый Файл("\\fileserver\obmen\in");
Если Не Каталог.Существует() Тогда
ВызватьИсключение "Каталог обмена недоступен с сервера 1С: " + Каталог.ПолноеИмя;
КонецЕсли;
НайденныеФайлы = НайтиФайлы(Каталог.ПолноеИмя, "*.xml", Ложь);
НайтиФайлы возвращает массив объектов Файл. У каждого сразу доступны ПолноеИмя, Имя и остальные свойства — путь склеивать вручную не нужно.
Когда путь выбирает пользователь
Чаще всего путь к файлу появляется из диалога. На клиенте используют ДиалогВыбораФайла:
&НаКлиенте
Асинх Процедура ВыбратьФайл(Команда)
Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
Диалог.Фильтр = "Excel (*.xlsx)|*.xlsx";
Диалог.МножественныйВыбор = Ложь;
Выбранные = Ждать Диалог.ВыбратьАсинх();
Если Выбранные = Неопределено Или Выбранные.Количество() = 0 Тогда
Возврат;
КонецЕсли;
ПутьКФайлу = Выбранные[0];
КонецПроцедуры
Для выбора папки создают диалог в режиме РежимДиалогаВыбораФайла.ВыборКаталога. Выбранный каталог возвращается без завершающего разделителя — добавьте ПолучитьРазделительПути() перед склейкой с именем файла.
На платформах до 8.3.18 вместо ВыбратьАсинх() применяют Диалог.Показать(ОписаниеОповещения) с обработчиком, а результат приходит в процедуру оповещения. Модальный Диалог.Выбрать() в конфигурациях с запретом модальности вызовет ошибку.
Безопасный режим
Внешние обработки, подключённые через «Дополнительные отчёты и обработки», в типовых конфигурациях по умолчанию работают в безопасном режиме. В нём доступ к файловой системе сервера ограничен: Новый Файл(...).Существует() или запись файла могут завершиться ошибкой доступа. Нужны разрешения, которые запрашивает обработка при регистрации, либо профиль безопасности, настроенный администратором.
Почему путь «не находится»: разбор частых ошибок
Большинство проблем с путями сводится к нескольким симптомам. Разбор по ним:
Ещё две ловушки, которые не дают ошибки сразу:
- 🗑 Временный файл не удаляется. Его держит открытый объект:
ЧтениеТекста,ЧтениеXML,ЗаписьТекста. ВызовитеЗакрыть()доУдалитьФайлы. - 📝 Кириллица и пробелы в пути внешней программы. При запуске через
ЗапуститьПриложениеилиКомандаСистемызаключайте путь в кавычки:"""" + ПутьКФайлу + """".
Частые вопросы
Как получить только имя файла без расширения?
Новый Файл(ПолноеИмя) и возьмите свойство ИмяБезРасширения. Если в имени несколько точек, например отчет.2026.xlsx, отбрасывается только последнее расширение.Как узнать путь к рабочему столу пользователя?
WScript.Shell: Новый COMОбъект("WScript.Shell").SpecialFolders("Desktop") — только на клиенте и не в веб-клиенте. Универсальный вариант — дать пользователю выбрать папку диалогом.