При разработке внешних обработок и отчетов в системе «1С:Предприятие» часто возникает задача определить физическое расположение файла, который в данный момент выполняется. Это может быть необходимо для чтения сопроводительных файлов конфигурации, сохранения логов рядом с обработкой или для механизмов саморегистрации.
Давайте подробно разберем, как получить полный путь к файлу обработки в разных режимах работы платформы: в обычном приложении и в управляемых формах (на клиенте и сервере).
В объектной модели платформы 1С у внешних обработок и отчетов существует специальное свойство, которое хранит полный путь к файлу. Это свойство называется ИспользуемоеИмяФайла.
Если мы работаем в модуле объекта обработки или в обычном приложении (толстый клиент, обычные формы), доступ к этому свойству осуществляется через контекст ЭтотОбъект.
Рассмотрим простейший пример кода, который позволяет получить путь:
// Пример кода в модуле объекта или модуле формы обычного приложения
ПолноеИмяФайла = ЭтотОбъект.ИспользуемоеИмяФайла;
Сообщить("Обработка запущена из: " + ПолноеИмяФайла);
Чтобы из полного пути извлечь только каталог, можно воспользоваться стандартными функциями работы со строками или методами файловой системы. Разберем пример разложения полного имени на путь и имя файла:
ПолноеИмяФайла = ЭтотОбъект.ИспользуемоеИмяФайла;
Файл = Новый Файл(ПолноеИмяФайла);
ИмяКаталога = Файл.Путь;
ИмяСамогоФайла = Файл.Имя;
В современных конфигурациях, работающих на управляемых формах (Такси, тонкий клиент), ситуация сложнее. Дело в том, что код формы выполняется на клиенте, и переменная, хранящая данные обработки (обычно она называется Объект), является типом ДанныеФормыСтруктура, а не полноценным объектом ВнешняяОбработкаОбъект.
У типа ДанныеФормыСтруктура нет свойства ИспользуемоеИмяФайла. Если вы попытаетесь обратиться к нему напрямую в клиентском коде формы, вы получите ошибку.
Для решения этой задачи нам необходимо выполнить следующие шаги:
Давайте посмотрим, как это реализуется на практике. Создадим команду формы, которая выводит путь к файлу:
&НаКлиенте
Процедура УзнатьПуть(Команда)
УзнатьПутьНаСервере();
КонецПроцедуры
&НаСервере
Процедура УзнатьПутьНаСервере()
// Преобразуем данные формы в реальный объект обработки
// "Объект" — это имя основного реквизита формы
ОбработкаОбъект = РеквизитФормыВЗначение("Объект");
// Теперь нам доступно свойство ИспользуемоеИмяФайла
ПутьКФайлу = ОбработкаОбъект.ИспользуемоеИмяФайла;
// Выводим сообщение пользователю
Сообщить("Путь на сервере: " + ПутьКФайлу);
КонецПроцедуры
Важное замечание: Метод РеквизитФормыВЗначение создает копию объекта в памяти сервера. Это ресурсоемкая операция, поэтому не стоит вызывать её в часто выполняемых циклах.
Существует критически важный момент, который необходимо учитывать при проектировании логики вашей обработки. Результат работы ИспользуемоеИмяФайла зависит от того, как именно была открыта обработка.
Вариант 1: Меню "Файл — Открыть"
Если вы открываете файл .epf через меню, свойство вернет реальный путь к файлу на диске (или сетевом ресурсе), откуда вы его выбрали.
Вариант 2: Справочник "Дополнительные отчеты и обработки" (БСП)
Если ваша обработка загружена в базу данных (в справочник) и запускается оттуда, платформе необходимо сначала выгрузить её двоичные данные во временный файл. Для таких случаев полезно использовать шаблон дополнительной обработки для БСП.
В этом случае ИспользуемоеИмяФайла вернет путь к временному файлу во временном каталоге пользователя сервера или клиента.
Пример такого пути: C:\Users\User\AppData\Local\Temp\v8_12A4.tmp.
Узнать исходный путь, откуда этот файл был загружен в базу данных разработчиком, средствами самой обработки во время выполнения невозможно, так как эта связь теряется после загрузки двоичных данных в базу.
В некоторых специфических случаях, когда нет возможности обратиться к серверу или нужно узнать путь именно на клиенте без конвертации объекта, можно попытаться прочитать список последних открытых файлов (MRU — Most Recently Used) из настроек пользователя.
Внимание: Этот метод не является документированным и надежным, так как зависит от формата файлов настроек платформы, который может меняться. Однако, рассмотрим его для полноты картины.
Идея заключается в чтении файла 1cv8ccmn.pfl в рабочем каталоге пользователя. Разберем пример реализации функции на клиенте:
&НаКлиенте
Функция ПолучитьПутьТекущегоКталогаВнешнейОбработки()
// Формируем путь к файлу списка недавно использованных файлов
ПутьКФайлуНастроек = Лев(РабочийКаталогДанныхПользователя(), СтрДлина(РабочийКаталогДанныхПользователя())-4) + "1cv8ccmn.pfl";
Текст = Новый ТекстовыйДокумент;
Попытка
Текст.Прочитать(ПутьКФайлуНастроек);
Исключение
Возврат ""; // Не удалось прочитать файл
КонецПопытки;
Для НомерСтроки = 1 По Текст.КоличествоСтрок() Цикл
Стр = Текст.ПолучитьСтроку(НомерСтроки);
// Ищем секцию MRUFileList
Если СтрНайти(Стр, "MRUFileList") > 0 Тогда
// Обычно путь к последнему файлу находится через несколько строк после заголовка
// Смещение (+8) в данном примере подобрано эмпирически и может отличаться в разных версиях
ПотенциальныйПуть = Текст.ПолучитьСтроку(НомерСтроки + 8);
// Очистка строки от кавычек и служебных символов (формат PFL специфичен)
// ... здесь потребуется дополнительный парсинг строки ...
Возврат ПотенциальныйПуть;
КонецЕсли;
КонецЦикла;
Возврат "";
КонецФункции
Мы рекомендуем использовать этот метод только в крайних случаях, так как он ненадежен, не работает в веб-клиенте (из-за отсутствия прямого доступа к файловой системе) и может вернуть путь не к текущей, а к предыдущей открытой обработке.
Подведем итог. Для надежного получения пути к файлу внешней обработки:
ЭтотОбъект.ИспользуемоеИмяФайла.РеквизитФормыВЗначение("Объект").ИспользуемоеИмяФайла.