Путь к файлу, каталогу и базе во встроенном языке 1С 8.3
Содержание
Путь к файлу в 1С получают по-разному в зависимости от того, какой путь нужен. Каталог временных файлов вернёт КаталогВременныхФайлов(), путь к файловой базе — НСтр(СтрокаСоединенияИнформационнойБазы(), "File"), путь к файлу, который выбрал пользователь, — свойство ПолноеИмяФайла диалога ДиалогВыбораФайла. Части пути (имя, расширение, папку) разбирает объект Файл.
Типичная ситуация: программист пишет выгрузку прайса в Excel, у себя на ноутбуке всё работает, а у бухгалтера на сервере терминалов файл «пропадает». Причина почти всегда одна: код получил путь в одном контексте (на сервере), а искали файл в другом (на клиенте). Поэтому ниже для каждого способа сказано, где он выполняется и чей диск видит.
Функции платформы, которые сразу возвращают путь
Для стандартных каталогов писать ничего не нужно: платформа 1С 8.3 даёт готовые функции глобального контекста.
| Функция | Что возвращает | Где работает |
|---|---|---|
КаталогВременныхФайлов() | Каталог временных файлов текущего пользователя ОС | Клиент и сервер |
ПолучитьИмяВременногоФайла("xlsx") | Полный путь к новому уникальному временному файлу | Клиент и сервер |
КаталогПрограммы() | Каталог bin запущенной платформы | Клиент и сервер |
КаталогДокументов() | Папку «Документы» пользователя | Клиент |
РабочийКаталогДанныхПользователя() | Рабочий каталог данных пользователя 1С | Клиент |
ПолучитьРазделительПути() | \ в Windows, / в Linux | Клиент и сервер |
Пример: собрать путь к файлу отчёта в папке «Документы».
&НаКлиенте
Процедура СформироватьПуть(Команда)
Каталог = КаталогДокументов();
Разделитель = ПолучитьРазделительПути();
Если Прав(Каталог, 1) <> Разделитель Тогда
Каталог = Каталог + Разделитель;
КонецЕсли;
ПутьКФайлу = Каталог + "Прайс.xlsx";
Сообщить(ПутьКФайлу);
КонецПроцедуры
Разделитель не пишите вручную. Если базу перенесут на сервер под Linux, код с жёстким \ сломается, а ПолучитьРазделительПути() подстроится сам.
ПолучитьИмяВременногоФайла() удобнее склейки строк: имя уникально, конфликтов при параллельной работе нескольких пользователей не будет. Расширение передаётся без точки. Временный файл платформа сама не удаляет — после работы вызовите УдалитьФайлы(ИмяФайла).
В веб-клиенте функции работы с локальными каталогами требуют расширения для работы с файлами. Для веб-клиента и мобильного клиента предпочтительны асинхронные варианты: НачатьПолучениеКаталогаДокументов(), НачатьПолучениеКаталогаВременныхФайлов().
Путь к файловой базе: разбираем строку соединения
Вопрос «где лежит база» решает функция СтрокаСоединенияИнформационнойБазы(). Она возвращает строку вида:
- 📁 файловый вариант:
File="D:\Bases\Buh"; - 🖥 клиент-серверный:
Srvr="srv1c";Ref="buh_2024";
Из такой строки параметр достаёт функция НСтр(): она понимает формат «Имя=Значение;» и снимает кавычки.
&НаКлиенте
Функция КаталогИнформационнойБазы()
СтрокаСоединения = СтрокаСоединенияИнформационнойБазы();
Каталог = НСтр(СтрокаСоединения, "File");
Если ПустаяСтрока(Каталог) Тогда
// Серверная база: файлового каталога нет
Сервер = НСтр(СтрокаСоединения, "Srvr");
ИмяБазы = НСтр(СтрокаСоединения, "Ref");
Сообщить("Серверная база " + ИмяБазы + " на " + Сервер);
Возврат "";
КонецЕсли;
Возврат Каталог;
КонецФункции
Сам файл данных файловой базы называется 1Cv8.1CD и лежит в этом каталоге. Полный путь к нему: каталог + разделитель + 1Cv8.1CD.
Частая задача — положить файл рядом с базой (например, лог обмена). Делать это можно, но учтите права: у пользователя Windows должна быть запись в каталог базы. Если база на сетевом ресурсе, путь вернётся в том виде, в каком её добавили в список: UNC (\\nas\bases\buh) или буквой диска (Z:\buh). У другого пользователя буква Z: может вести в другое место.
Путь к файлу, который выбрал пользователь
Если путь задаёт человек, используйте диалог выбора. В 8.3 его показывают асинхронно, через описание оповещения.
&НаКлиенте
Процедура ВыбратьФайл(Команда)
Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
Диалог.Фильтр = "Файлы Excel (*.xlsx)|*.xlsx|Все файлы (*.*)|*.*";
Диалог.МножественныйВыбор = Ложь;
Оповещение = Новый ОписаниеОповещения("ВыбратьФайлЗавершение", ЭтотОбъект);
Диалог.Показать(Оповещение);
КонецПроцедуры
&НаКлиенте
Процедура ВыбратьФайлЗавершение(ВыбранныеФайлы, ДополнительныеПараметры) Экспорт
Если ВыбранныеФайлы = Неопределено Тогда
Возврат; // пользователь нажал «Отмена»
КонецЕсли;
ПутьКФайлу = ВыбранныеФайлы[0];
Сообщить(ПутьКФайлу);
КонецПроцедуры
В процедуру завершения приходит массив полных путей или Неопределено, если окно закрыли. Для выбора папки создайте диалог в режиме РежимДиалогаВыбораФайла.ВыборКаталога, путь вернётся в том же массиве.
Разбор пути на части объектом «Файл»
Когда полный путь уже есть, его части не нужно резать через СтрНайти(). Объект Файл делает это сам:
ФайлОбъект = Новый Файл("D:\Обмен\Входящие\Прайс_октябрь.xlsx");
Сообщить(ФайлОбъект.Путь); // D:\Обмен\Входящие\
Сообщить(ФайлОбъект.Имя); // Прайс_октябрь.xlsx
Сообщить(ФайлОбъект.ИмяБезРасширения); // Прайс_октябрь
Сообщить(ФайлОбъект.Расширение); // .xlsx (с точкой)
Сообщить(ФайлОбъект.ПолноеИмя); // весь путь целиком
Две детали, на которых ошибаются:
- 🔹
Путьвозвращается с разделителем на конце. Дописывайте имя файла без лишнего\. - 🔹
Расширениевключает точку. Сравнивайте с".xlsx", а не с"xlsx", и приводите к нижнему регистру черезНРег().
Создание объекта Файл не проверяет, существует ли файл. Это только разбор строки.
Путь к самой внешней обработке
Приём, который нужен при разработке внешних обработок: путь к файлу .epf хранится в свойстве ИспользуемоеИмяФайла объекта обработки. В управляемой форме оно доступно на сервере:
&НаСервере
Функция ПутьКОбработке()
Возврат РеквизитФормыВЗначение("Объект").ИспользуемоеИмяФайла;
КонецФункции
Если обработку открыли из справочника дополнительных отчётов и обработок, свойство вернёт путь к временной копии, а не к исходному файлу. Рядом с такой копией настройки или шаблоны не храните.
Переменные среды Windows: %APPDATA%, %USERPROFILE% и другие
Отдельной функции для чтения переменных окружения во встроенном языке нет. В Windows их получают через COM-объект WScript.Shell:
&НаКлиенте
Функция РаскрытьПеременнуюСреды(Шаблон)
Попытка
Оболочка = Новый COMОбъект("WScript.Shell");
Возврат Оболочка.ExpandEnvironmentStrings(Шаблон);
Исключение
Сообщить("Не удалось прочитать переменную: " + ОписаниеОшибки());
Возврат "";
КонецПопытки;
КонецФункции
// Вызов:
ПапкаПрофиля = РаскрытьПеременнуюСреды("%USERPROFILE%");
ПапкаРоуминга = РаскрытьПеременнуюСреды("%APPDATA%");
Полезные переменные:
| Переменная | Пример значения | Зачем в 1С |
|---|---|---|
%USERPROFILE% | C:\Users\ivanova | Корень профиля пользователя |
%APPDATA% | C:\Users\ivanova\AppData\Roaming | Здесь лежит 1C\1CEStart\ibases.v8i — список баз |
%LOCALAPPDATA% | C:\Users\ivanova\AppData\Local | Кэш клиента 1С (1C\1cv8) |
%TEMP% | C:\Users\ivanova\AppData\Local\Temp | То же, что обычно даёт КаталогВременныхФайлов() |
%COMPUTERNAME% | BUH-PC-07 | Есть и встроенная функция ИмяКомпьютера() |
Ограничения способа:
- ⚠️ COM работает только в Windows. На сервере 1С под Linux и в веб-клиенте этот код упадёт в исключение.
- ⚠️ На сервере переменные будут не пользователя 1С, а учётной записи, под которой запущен рабочий процесс (часто
USR1CV8).%USERPROFILE%укажет в её профиль.
Там, где хватает встроенной функции (КаталогВременныхФайлов(), КаталогДокументов(), ИмяКомпьютера()), используйте её, а не COM.
Клиент или сервер: чей это путь
Это главный источник ошибок. Одна и та же функция в разном контексте смотрит на разные диски.
- 💻
&НаКлиенте— путь на компьютере пользователя (или на сервере терминалов, если он работает через RDP). - 🖥
&НаСервере— путь на компьютере, где работает рабочий процесс сервера 1С. В файловом варианте без веб-сервера «сервер» — это тот же компьютер пользователя, поэтому ошибка там не проявляется. Она всплывает при переходе на клиент-серверный вариант.
Пример: КаталогВременныхФайлов() в процедуре &НаСервере вернёт что-то вроде C:\Users\USR1CV8\AppData\Local\Temp\ на машине сервера 1С. Если передать эту строку на клиент и попытаться открыть файл, его не найдут: на компьютере бухгалтера такой папки нет.
Как передать файл с клиента на сервер
Путь клиента серверу бесполезен, передавать нужно содержимое. Схема для тонкого клиента:
&НаКлиенте
Процедура ЗагрузитьНаСервер(ПутьКФайлу)
Данные = Новый ДвоичныеДанные(ПутьКФайлу);
Адрес = ПоместитьВоВременноеХранилище(Данные, УникальныйИдентификатор);
ОбработатьФайлНаСервере(Адрес);
КонецПроцедуры
&НаСервере
Процедура ОбработатьФайлНаСервере(Адрес)
Данные = ПолучитьИзВременногоХранилища(Адрес);
ИмяНаСервере = ПолучитьИмяВременногоФайла("xlsx");
Данные.Записать(ИмяНаСервере);
// ... чтение файла по ИмяНаСервере ...
УдалитьФайлы(ИмяНаСервере);
КонецПроцедуры
Обратная задача (сервер → клиент) решается так же: сервер кладёт ДвоичныеДанные во временное хранилище, клиент забирает и записывает в свой путь. В веб-клиенте прямое чтение файла по пути недоступно, там используют асинхронные методы помещения файлов с диалогом.
Путь из параметров запуска
Иногда путь задают снаружи: ярлык или планировщик запускает 1С и говорит, какой файл загрузить. Для этого есть ключ командной строки /C. Его значение доступно в коде через свойство глобального контекста ПараметрЗапуска.
"C:\Program Files\1cv8\common\1cestart.exe" ENTERPRISE /F"D:\Bases\Buh" /N"Обмен" /P"пароль" /C"D:\Exchange\in.xml"
&НаКлиенте
Процедура ПриНачалеРаботыСистемы()
Если Не ПустаяСтрока(ПараметрЗапуска) Тогда
ПутьКФайлу = СокрЛП(ПараметрЗапуска);
Сообщить("Файл для загрузки: " + ПутьКФайлу);
КонецЕсли;
КонецПроцедуры
В типовых конфигурациях на БСП ПараметрЗапуска уже используется для служебных команд. Передавайте свои значения с префиксом, например /C"ФайлОбмена=D:\Exchange\in.xml", и разбирайте строку через СтрРазделить(ПараметрЗапуска, ";"). Так ваш код не перехватит чужую команду.
Остальные ключи запуска тоже несут пути:
| Ключ | Что задаёт |
|---|---|
/F"путь" | Каталог файловой базы |
/S"сервер\база" | Серверная база |
/Out"путь" | Файл, куда пишутся служебные сообщения пакетного режима |
/C"строка" | Произвольная строка для кода, ПараметрЗапуска |
Пароль в ярлыке с ключом /P виден любому, кто откроет свойства ярлыка. Для автоматического обмена заведите отдельного пользователя 1С с минимальными правами.
Проверки, ошибки и безопасность при работе с путями
Путь — это внешние данные. Он может указывать на удалённую папку, отключённый сетевой диск или файл, который держит открытым Excel. Защищайте каждую операцию.
Проверка существования и обработка исключений
&НаСервере
Функция ПрочитатьТекст(ПутьКФайлу)
ФайлОбъект = Новый Файл(ПутьКФайлу);
Если Не ФайлОбъект.Существует() Тогда
ВызватьИсключение "Файл не найден: " + ПутьКФайлу;
КонецЕсли;
Если ФайлОбъект.ЭтоКаталог() Тогда
ВызватьИсключение "Указан каталог, а не файл: " + ПутьКФайлу;
КонецЕсли;
Попытка
Текст = Новый ТекстовыйДокумент;
Текст.Прочитать(ПутьКФайлу, КодировкаТекста.UTF8);
Возврат Текст.ПолучитьТекст();
Исключение
ВызватьИсключение "Не удалось прочитать " + ПутьКФайлу + ": "
+ КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
КонецПопытки;
КонецФункции
Проверка Существует() не гарантирует успех: между проверкой и чтением файл могут удалить или заблокировать. Поэтому Попытка нужна всё равно.
Типовые сбои и их причины
Безопасность
- 🔒 Не собирайте путь из ввода пользователя без проверки. Строка
..\..\в имени файла выведет запись за пределы нужной папки. Берите из ввода только имя файла (черезНовый Файл(...).Имя) и склеивайте с известным каталогом. - 🔒 Удаляйте недопустимые символы
\ / : * ? " < > |из имён, которые формируете из данных базы (наименование контрагента в имени файла — частый случай). В типовых конфигурациях на БСП для этого есть готовая функция в общем модулеОбщегоНазначенияКлиентСервер, её имя содержит слова «НедопустимыеСимволы». - 🔒 Внешние обработки и расширения в безопасном режиме не получат доступ к файловой системе. Если в кластере включены профили безопасности, каталоги для чтения и записи нужно разрешить в профиле. Ошибка доступа в таком случае — не баг кода, а настройка администратора.
- 🔒
УдалитьФайлы()с пустой или неверно собранной строкой удалит не то. Перед удалением проверяйте, что путь начинается с ожидаемого каталога.