Как во внешней обработке программно узнать полный путь, откуда она была запущена?

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

При разработке внешних обработок и отчетов в системе «1С:Предприятие» часто возникает задача определить физическое расположение файла, который в данный момент выполняется. Это может быть необходимо для чтения сопроводительных файлов конфигурации, сохранения логов рядом с обработкой или для механизмов саморегистрации.

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

Базовый механизм: Свойство «ИспользуемоеИмяФайла»

В объектной модели платформы 1С у внешних обработок и отчетов существует специальное свойство, которое хранит полный путь к файлу. Это свойство называется ИспользуемоеИмяФайла.

Если мы работаем в модуле объекта обработки или в обычном приложении (толстый клиент, обычные формы), доступ к этому свойству осуществляется через контекст ЭтотОбъект.

Рассмотрим простейший пример кода, который позволяет получить путь:


// Пример кода в модуле объекта или модуле формы обычного приложения
ПолноеИмяФайла = ЭтотОбъект.ИспользуемоеИмяФайла;
Сообщить("Обработка запущена из: " + ПолноеИмяФайла);

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


ПолноеИмяФайла = ЭтотОбъект.ИспользуемоеИмяФайла;
Файл = Новый Файл(ПолноеИмяФайла);
ИмяКаталога = Файл.Путь;
ИмяСамогоФайла = Файл.Имя;

Особенности работы в Управляемых формах (Тонкий клиент)

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

У типа ДанныеФормыСтруктура нет свойства ИспользуемоеИмяФайла. Если вы попытаетесь обратиться к нему напрямую в клиентском коде формы, вы получите ошибку.

Для решения этой задачи нам необходимо выполнить следующие шаги:

  1. Передать управление с клиента на сервер.
  2. На сервере преобразовать данные формы в полноценный объект обработки.
  3. Прочитать нужное свойство у полученного объекта.

Давайте посмотрим, как это реализуется на практике. Создадим команду формы, которая выводит путь к файлу:


&НаКлиенте
Процедура УзнатьПуть(Команда)
    УзнатьПутьНаСервере();
КонецПроцедуры

&НаСервере
Процедура УзнатьПутьНаСервере()
    // Преобразуем данные формы в реальный объект обработки
    // "Объект" — это имя основного реквизита формы
    ОбработкаОбъект = РеквизитФормыВЗначение("Объект");
    
    // Теперь нам доступно свойство ИспользуемоеИмяФайла
    ПутьКФайлу = ОбработкаОбъект.ИспользуемоеИмяФайла;
    
    // Выводим сообщение пользователю
    Сообщить("Путь на сервере: " + ПутьКФайлу);
КонецПроцедуры

Важное замечание: Метод РеквизитФормыВЗначение создает копию объекта в памяти сервера. Это ресурсоемкая операция, поэтому не стоит вызывать её в часто выполняемых циклах.

Нюанс: Запуск обработки из базы данных vs Файл -> Открыть

Существует критически важный момент, который необходимо учитывать при проектировании логики вашей обработки. Результат работы ИспользуемоеИмяФайла зависит от того, как именно была открыта обработка.

Вариант 1: Меню "Файл — Открыть"
Если вы открываете файл .epf через меню, свойство вернет реальный путь к файлу на диске (или сетевом ресурсе), откуда вы его выбрали.

Вариант 2: Справочник "Дополнительные отчеты и обработки" (БСП)
Если ваша обработка загружена в базу данных (в справочник) и запускается оттуда, платформе необходимо сначала выгрузить её двоичные данные во временный файл. Для таких случаев полезно использовать шаблон дополнительной обработки для БСП.

В этом случае ИспользуемоеИмяФайла вернет путь к временному файлу во временном каталоге пользователя сервера или клиента. Пример такого пути: C:\Users\User\AppData\Local\Temp\v8_12A4.tmp.

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

Альтернативный способ: Получение пути через список MRU (На клиенте)

В некоторых специфических случаях, когда нет возможности обратиться к серверу или нужно узнать путь именно на клиенте без конвертации объекта, можно попытаться прочитать список последних открытых файлов (MRU — Most Recently Used) из настроек пользователя.

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

Идея заключается в чтении файла 1cv8ccmn.pfl в рабочем каталоге пользователя. Разберем пример реализации функции на клиенте:


&НаКлиенте
Функция ПолучитьПутьТекущегоКталогаВнешнейОбработки()
    
    // Формируем путь к файлу списка недавно использованных файлов
    ПутьКФайлуНастроек = Лев(РабочийКаталогДанныхПользователя(), СтрДлина(РабочийКаталогДанныхПользователя())-4) + "1cv8ccmn.pfl";
    
    Текст = Новый ТекстовыйДокумент;
    Попытка
        Текст.Прочитать(ПутьКФайлуНастроек);
    Исключение
        Возврат ""; // Не удалось прочитать файл
    КонецПопытки;

    Для НомерСтроки = 1 По Текст.КоличествоСтрок() Цикл
        Стр = Текст.ПолучитьСтроку(НомерСтроки);
        
        // Ищем секцию MRUFileList
        Если СтрНайти(Стр, "MRUFileList") > 0 Тогда
             // Обычно путь к последнему файлу находится через несколько строк после заголовка
             // Смещение (+8) в данном примере подобрано эмпирически и может отличаться в разных версиях
             ПотенциальныйПуть = Текст.ПолучитьСтроку(НомерСтроки + 8);
             
             // Очистка строки от кавычек и служебных символов (формат PFL специфичен)
             // ... здесь потребуется дополнительный парсинг строки ...
             
             Возврат ПотенциальныйПуть;
        КонецЕсли;
    КонецЦикла;
    
    Возврат "";
КонецФункции

Мы рекомендуем использовать этот метод только в крайних случаях, так как он ненадежен, не работает в веб-клиенте (из-за отсутствия прямого доступа к файловой системе) и может вернуть путь не к текущей, а к предыдущей открытой обработке.

Выводы

Подведем итог. Для надежного получения пути к файлу внешней обработки:

  1. В обычном приложении используйте ЭтотОбъект.ИспользуемоеИмяФайла.
  2. В управляемом приложении передавайте управление на сервер и используйте конструкцию РеквизитФормыВЗначение("Объект").ИспользуемоеИмяФайла.
  3. Помните, что при запуске обработки, хранящейся внутри конфигурации или в базе данных, путь будет указывать на временный файл.
← На главную