Как реализовать относительный путь к файлу в 1С:Предприятие 8?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

В процессе разработки конфигураций или внешних обработок в среде 1С:Предприятие 8 часто возникает задача обращения к внешним файлам: логам, настройкам в формате .xml или текстовым данным. Типичная ошибка начинающего разработчика — указание жесткого (абсолютного) пути, например, E:\123\2\LOG.log. Такой подход делает код нежизнеспособным, как только база переносится на другой сервер или открывается другим пользователем. В этой статье мы подробно разберем, как сделать путь к файлу динамическим, чтобы система сама понимала, где искать нужный объект, не заставляя пользователя вводить путь вручную.

Важно понимать фундаментальную особенность платформы: 1С не поддерживает относительные пути в стиле операционных систем (например, ..\log.txt) напрямую в методах работы с файлами. Объекты вроде ЧтениеТекста или ТекстовыйДокумент всегда требуют полный путь. Следовательно, наша задача — научиться вычислять этот путь программно.

Способ 1. Использование каталога информационной базы (для файлового варианта)

Проанализируем ситуацию, когда наш файл должен находиться непосредственно в папке с информационной базой. Это удобно для файловых баз, так как файл перемещается вместе с данными. Для этого мы можем использовать функцию СтрокаСоединенияИнформационнойБазы(). Разберем по шагам, как извлечь из нее путь:

Строка соединения для файловой базы выглядит примерно так: File="D:\Bases\MyBase";. Нам нужно отсечь лишние символы. Посмотрим на пример кода:


СтрокаСоединения = СтрокаСоединенияИнформационнойБазы();
// Извлекаем путь, убирая "File=" и кавычки
ПутьКБазе = Сред(СтрокаСоединения, 7, СтрДлина(СтрокаСоединения) - 8);
ПолныйПутьКФайлу = ПутьКБазе + "LOG.log";

НомерСтрLog = Новый ЧтениеТекста;
НомерСтрLog.Открыть(ПолныйПутьКФайлу);

Этот метод отлично подходит для небольших локальных систем, но стоит помнить, что в клиент-серверном варианте (SQL) строка соединения будет содержать имя сервера и базы, а не путь к диску. Поэтому для серверных решений этот способ не применим.

Способ 2. Определение пути к файлу внешней обработки

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


// В модуле внешней обработки
ФайлОбработки = Новый Файл(ЭтотОбъект.ИспользуемоеИмяФайла);
КаталогОбработки = ФайлОбработки.Путь;
ПолныйПутьКФайлу = КаталогОбработки + "LOG.log";

В Управляемом приложении ситуация сложнее, так как код может выполняться на сервере, где файла обработки физически нет. В этом случае рекомендуется передавать путь с клиента на сервер или использовать временные хранилища. Тем не менее, для локальных инструментов администратора этот метод остается крайне эффективным.

Способ 3. Использование стандартных системных каталогов

Зачастую программе не важно, где именно лежит файл, главное — чтобы у текущего пользователя были права на чтение и запись. Для этого 1С предоставляет встроенные функции для доступа к стандартным папкам Windows или Linux. Рассмотрим основные из них:

  1. КаталогВременныхФайлов(): Идеально подходит для логов и промежуточных данных. Эта папка всегда доступна для записи.
  2. КаталогДокументов(): Путь к папке «Мои документы» текущего пользователя.
  3. КаталогПрограммы(): Путь к каталогу, где установлена сама платформа 1С.

Проанализируем пример использования временного каталога:


ИмяФайла = КаталогВременныхФайлов() + "my_temp_log.log";
Чтение = Новый ЧтениеТекста;
// Теперь мы уверены, что путь существует и доступен
Чтение.Открыть(ИмяФайла);

Способ 4. Работа с переменными окружения через COM-объекты

Иногда требуется обратиться к папкам, которые заданы в системных переменных Windows, например, %APPDATA% или %USERPROFILE%. Напрямую 1С их не понимает, но мы можем использовать объект WScript.Shell для их раскрытия. Разберем этот продвинутый метод:


Shell = Новый COMОбъект("WScript.Shell");
// Раскрываем переменную окружения
ПутьAppData = Shell.ExpandEnvironmentStrings("%APPDATA%");
ПолныйПуть = ПутьAppData + "\1C_Logs\LOG.log";

// Далее работаем с файлом как обычно
ФайлЛога = Новый Файл(ПолныйПуть);
Если ФайлЛога.Существует() Тогда
    // выполняем чтение
КонецЕсли;

Этот подход делает ваш путь "относительным" относительно профиля пользователя в операционной системе, что очень удобно для хранения персональных настроек.

Способ 5. Динамический поиск файла в подкаталогах

Если мы знаем только диск (например, E:\) и имя файла, но не знаем точную вложенность папок, мы можем задействовать метод НайтиФайлы. Это позволяет реализовать гибкий поиск. Проанализируем пример поиска во всех подкаталогах:


// Ищем файл LOG.log на диске E в любой папке
НайденныеФайлы = НайтиФайлы("E:\", "LOG.log", Истина);

Для Каждого ТекущийФайл Из НайденныеФайлы Цикл
    Сообщить("Файл найден здесь: " + ТекущийФайл.ПолноеИмя);
    // Берем первый попавшийся и выходим
    НужныйПуть = ТекущийФайл.ПолноеИмя;
    Прервать;
КонецЦикла;

Важное замечание: Поиск по всему диску может занять много времени, поэтому старайтесь максимально ограничивать начальный каталог поиска.

Кроссплатформенность и особенности разделителей

При написании универсального кода, который должен работать и на Windows, и на Linux, никогда не используйте жестко заданный обратный слеш (\). В Linux разделителем является прямой слеш (/). Выясним, как сделать код универсальным:

Используйте функцию ПолучитьРазделительПути(). Проанализируем правильное построение строки пути:


Разделитель = ПолучитьРазделительПути();
ПутьКФайлу = КаталогВременныхФайлов() + Разделитель + "LOG.log";

Такой код будет успешно работать на сервере под любой операционной системой.

Проблема прав доступа при работе на сервере

Выясним причину частой ошибки: код отлично работает на локальном компьютере программиста, но "валится" при выполнении на сервере. Когда код выполняется в контексте сервера (например, в регламентном задании), он запускается от имени системного пользователя (обычно USR1CV8). У этого пользователя часто нет прав на чтение дисков D: или E:.

Рекомендация: Если вам нужно писать логи из серверного кода, используйте КаталогВременныхФайлов() или заранее создайте на сервере папку и дайте пользователю USR1CV8 полные права на нее. В этом случае путь лучше хранить в Константе или Параметрах сеанса, чтобы администратор мог изменить его в любой момент без правки кода.

Подводя итог, мы видим, что "относительный путь" в 1С — это всегда результат динамического вычисления. Используя комбинацию системных функций и объектов для работы с файловой системой, вы сможете создавать надежные и переносимые решения.

← На главную