Разработчики систем на платформе 1С:Предприятие часто сталкиваются с задачей интеграции внешних отчетов и обработок, хранящихся непосредственно в информационной базе. Традиционный подход с записью бинарных данных на диск во временную директорию имеет ряд очевидных недостатков: от лишней нагрузки на дисковую подсистему (ввод-вывод) до потенциальных проблем с правами доступа и необходимостью ручной очистки диска после завершения работы алгоритма. В этой статье мы подробно проанализируем, можно ли обойтись без временных файлов, разберем ограничения различных типов интерфейсов и рассмотрим современные альтернативные решения.
Для начала вспомним стандартный шаблон, который годами использовался программистами для программного запуска внешних обработок из справочника в обычном приложении. Этот подход подразумевает обязательное физическое сохранение файла на жесткий диск пользователя.
Рассмотрим пример такого кода:
ИмяФайла = ПолучитьИмяВременногоФайла("epf");
СсылкаНаОбработку = Справочники.ВнешниеОбработки.НайтиПоНаименованию("Информация по заказам");
ДвоичныеДанныеФайла = СсылкаНаОбработку.ХранилищеВнешнейОбработки.Получить();
Если ДвоичныеДанныеФайла <> Неопределено Тогда
ДвоичныеДанныеФайла.Записать(ИмяФайла);
Обработка = ВнешниеОбработки.Создать(ИмяФайла);
Форма = Обработка.ПолучитьФорму("Форма");
Форма.Открыть();
КонецЕсли;
Этот код отлично работает, но заставляет платформу выполнять дисковые операции записи и последующего чтения. Попытки современных разработчиков применить новые методы платформы и передать в метод ВнешниеОбработки.Подключить() адрес временного хранилища (схему e1cib/tempstorage) в обычном приложении неизбежно приводят к ошибке метаданных: "Неправильный путь к файлу... Схема не зарегистрирована".
Давайте разберем по шагам, почему архитектура обычного приложения накладывает такие жесткие ограничения:
Создать() ожидает исключительно текстовый путь к физическому файлу (локальному или сетевому).e1cib/data/... или e1cib/tempstorage/... являются частью внутренней веб-архитектуры управляемого интерфейса. Обычное приложение просто не имеет механизмов для непосредственной трансляции и компиляции двоичных данных из этих адресов без промежуточного сохранения на диск.ХранилищеЗначения). Чтобы платформа могла запустить код, ей необходимо прочитать структуру этого файла. Физически это реализуемо только путем воссоздания структуры файла на накопителе информации.Таким образом, для обычных форм классический сценарий с созданием временного файла остается единственным жизнеспособным решением.
В управляемом приложении (тонкий и веб-клиент) ситуация выглядит иначе. Платформа предоставляет штатный механизм подключения обработок напрямую через временное хранилище на сервере без необходимости ручного создания временного файла на стороне клиента.
Проанализируем пример кода, который решает эту задачу в современных конфигурациях:
&НаКлиенте
Процедура ЗапуститьОбработкуИзСправочника(Команда)
Если Не Объект.СсылкаНаОбработку.Пустая() Тогда
// Получаем имя, под которым обработка зарегистрирована в системе
ИмяОбработки = ПодключитьОбработкуНаСервере(Объект.СсылкаНаОбработку);
// Формируем путь к форме внешней обработки
ИмяФормы = СтрШаблон("ВнешняяОбработка.%1.Форма", ИмяОбработки);
// Открываем форму внешней обработки
ОткрытьФорму(ИмяФормы, , ЭтотОбъект);
КонецЕсли;
КонецПроцедуры
&НаСервереБезКонтекста
Функция ПодключитьОбработкуНаСервере(СсылкаНаОбработку)
// Получаем навигационную ссылку на реквизит ХранилищеЗначения, где лежит двоичный файл
АдресОбработки = ПолучитьНавигационнуюСсылку(СсылкаНаОбработку, "ХранилищеОбработки");
// Подключаем обработку во временное хранилище сеанса
ИмяОбработки = ВнешниеОбработки.Подключить(АдресОбработки, , Ложь);
Возврат ИмяОбработки;
КонецФункции
В этом примере метод ПолучитьНавигационнуюСсылку возвращает путь к бинарным данным в базе, а метод ВнешниеОбработки.Подключить() регистрирует внешнюю обработку в текущем сеансе под уникальным именем, которое затем используется для открытия форм.
Многие разработчики полагают, что использование метода ВнешниеОбработки.Подключить(АдресВременногоХранилища) полностью избавляет систему от работы с жестким диском и выполняет все операции исключительно в оперативной памяти (ОЗУ). Это миф.
Файл внешней обработки (с расширением .epf или .erf) по своей сути является сложным структурированным архивом. Он содержит в себе множество XML-описаний метаданных, файлы модулей, макеты и формы. Для того чтобы скомпилировать модули обработки и отобразить интерфейс, платформе физически необходимо распаковать этот архив.
В момент вызова метода Подключить() рабочий процесс сервера 1С (rphost) незаметно для разработчика выполняет следующие действия:
Единственное преимущество этого метода перед "ручным" созданием файла — автоматизация. Разработчику больше не нужно заботиться об уникальности имен файлов на диске, отслеживать права доступа в гостевых ОС и убирать за собой мусор — платформа берет управление жизненным циклом этого кэша на себя и удаляет временные файлы автоматически по завершении сеанса.
Если ваша цель — гарантированное избавление от дисковых операций ввода-вывода (I/O) из соображений производительности или безопасности, стандартные внешние обработки вам не подойдут. В некоторых сценариях альтернативой программированию может стать роботизация действий пользователя через RPA-платформу без подключения внешних файлов. Рассмотрим два альтернативных подхода.
Самым современным и архитектурно верным решением в экосистеме «1С:Предприятие 8.3» является перенос функционала внешних обработок в расширения конфигурации. В качестве примера такого подхода можно привести расширение для обмена 1С с МегаМаркетом, которое встраивается непосредственно в структуру базы. В отличие от внешних обработок, расширения:
Если вы ограничены рамками старой конфигурации (например, на обычных формах), где невозможно использовать расширения или управляемые формы, проблему оптимизации дисковых операций можно решить силами системного администрирования:
TEMP и TMP для учетной записи, под которой запускается служба сервера 1С (или сеанс пользователя), перенаправляются на созданный RAM-диск.ПолучитьИмяВременногоФайла() и запись двоичных данных через Записать() будут физически осуществляться в сверхбыструю оперативную память, минуя медленные дисковые накопители (даже самые быстрые NVMe SSD уступают по скорости ОЗУ).Выбирая между классическим созданием файла и методом Подключить(), обязательно учитывайте настройки безопасности системы:
ВнешниеОбработки.Подключить() платформа по умолчанию запускает код внешней обработки в так называемом безопасном режиме. Это накладывает автоматические ограничения на работу с файловой системой сервера, COM-объектами и внешними API.ВнешниеОбработки.Создать() из временного файла, код по умолчанию выполняется с полными правами текущего пользователя (если безопасный режим не был включен программно явным образом). Будьте внимательны при запуске непроверенных обработок из ненадежных источников.