При работе с внешними обработками в среде «1С:Предприятие 8» разработчики часто сталкиваются с ситуацией, когда код, отлично работающий при отладке, отказывается функционировать в реальных условиях. Типичный сценарий: вы создали внешнюю обработку для импорта данных из файла Excel в документ. При запуске через меню Файл — Открыть всё работает корректно. Но стоит зарегистрировать обработку в справочнике Дополнительные отчеты и обработки, как при попытке прочитать файл система выдает ошибку о том, что включен безопасный режим, и выполнение операции заблокировано.
В этой статье мы подробно разберем, почему возникает эта ошибка, проанализируем механизмы безопасности платформы и рассмотрим несколько способов решения проблемы — от быстрого изменения параметров регистрации до профессиональной настройки точечных разрешений в Библиотеке стандартных подсистем (БСП) и перехода на современные методы чтения файлов без использования COM-объектов.
Для начала разберем по шагам, что происходит в системе, когда мы подключаем обработку как дополнительную. Современные типовые конфигурации построены на базе БСП. Когда внешняя обработка регистрируется в системе, управление ее запуском берет на себя специальная подсистема. По умолчанию для повышения безопасности кода система запускает любые внешние обработки в так называемом безопасном режиме.
Безопасный режим накладывает жесткие ограничения на выполнение программного кода. В этом режиме платформой полностью блокируются следующие действия:
Excel.Application для чтения таблиц).Поскольку чтение файлов Excel стандартным способом часто опирается на создание COM-объекта или прямое обращение к локальным дискам сервера, безопасный режим мгновенно блокирует эти операции, защищая систему от потенциально опасного или вредоносного кода.
Проанализируем самый простой путь, который часто советуют на форумах. Если нам достоверно известно, что обработка безопасна, и мы пишем её исключительно для внутреннего использования, мы можем явно указать системе, что её не нужно запускать в безопасном режиме.
Для этого обратим внимание на модуль объекта нашей внешней обработки. В нем обязательно должна присутствовать экспортная функция СведенияОВнешнейОбработке(), которая передает параметры регистрации в БСП. Найдем строку, отвечающую за безопасный режим, и изменим её значение.
Рассмотрим пример настройки функции регистрации:
Функция СведенияОВнешнейОбработке() Экспорт
ПараметрыРегистрации = Новый Структура;
ПараметрыРегистрации.Вставить("Вид", "ДополнительнаяОбработка");
// Определяем массив назначений (к каким объектам подключается)
МассивНазначений = Новый Массив;
МассивНазначений.Добавить("Документ.ПоступлениеТоваровУслуг");
ПараметрыРегистрации.Вставить("Назначение", МассивНазначений);
ПараметрыРегистрации.Вставить("Наименование", "Загрузка данных из Excel");
ПараметрыРегистрации.Вставить("Версия", "1.0");
// Внимание: отключаем безопасный режим
ПараметрыРегистрации.Вставить("БезопасныйРежим", Ложь);
// Создаем таблицу команд
ТаблицаКоманд = ПолучитьТаблицуКоманд();
ДобавитьКоманду(ТаблицаКоманд, "Прочитать файл Excel", "ПрочитатьФайлExcel", "ВызовКлиентскогоМетода", Истина);
ПараметрыРегистрации.Вставить("Команды", ТаблицаКоманд);
Возврат ПараметрыРегистрации;
КонецФункции
После изменения значения параметра БезопасныйРежим на Ложь необходимо обновить обработку в справочнике Дополнительные отчеты и обработки. При обновлении система может выдать предупреждение о том, что обработка запрашивает небезопасный режим работы. Администратор должен подтвердить это действие.
Важное предупреждение: Начиная с версии платформы 8.3.9, в 1С действует встроенный механизм защиты от опасных действий. Даже если вы установите БезопасныйРежим = Ложь, при первом интерактивном запуске или при регистрации система все равно может выдать предупреждающее диалоговое окно или принудительно ограничить права, если у текущего пользователя в конфигураторе включена защита от опасных действий. Полное отключение безопасного режима не рекомендуется для использования в крупных корпоративных средах, так как это снижает общий уровень безопасности информационной базы.
Что делать, если политика безопасности компании строго запрещает запуск внешнего кода без безопасного режима? Современные стандарты разработки под 1С требуют оставлять БезопасныйРежим = Истина, но при этом явно декларировать точечные разрешения на конкретные ресурсы, которые требуются обработке для работы.
Для чтения Excel-файла нам обычно требуются два разрешения: доступ к каталогу временных файлов на сервере (чтобы временно сохранить загружаемый файл) и доступ к COM-классу Excel (если чтение реализовано через COM-соединение). Запросить их можно через специальное API общего модуля БСП РаботаВБезопасномРежиме.
Разберем по шагам, как модифицировать функцию СведенияОВнешнейОбработке() для запроса необходимых прав:
Функция СведенияОВнешнейОбработке() Экспорт
ПараметрыРегистрации = Новый Структура;
ПараметрыРегистрации.Вставить("Вид", "ДополнительнаяОбработка");
ПараметрыРегистрации.Вставить("Наименование", "Безопасная загрузка Excel");
ПараметрыРегистрации.Вставить("Версия", "1.1");
// Оставляем безопасный режим включенным!
ПараметрыРегистрации.Вставить("БезопасныйРежим", Истина);
// Инициализируем массив для хранения запрашиваемых разрешений
Разрешения = Новый Массив;
// 1. Запрашиваем разрешение на работу с временными файлами на сервере.
// Это необходимо для записи переданного с клиента Excel-файла во временный каталог сервера.
РазрешениеВременныеФайлы = РаботаВБезопасномРежиме.РазрешениеНаИспользованиеКаталогаВременныхФайлов(Истина, Истина);
Разрешения.Добавить(РазрешениеВременныеФайлы);
// 2. Если чтение выполняется через COM-объект Excel.Application,
// запрашиваем явное разрешение на его создание в безопасном режиме.
РазрешениеCOM = РаботаВБезопасномРежиме.РазрешениеНаСозданиеCOMКласса("Excel.Application", "");
Разрешения.Добавить(РазрешениеCOM);
// Добавляем массив разрешений в параметры регистрации
ПараметрыРегистрации.Вставить("Разрешения", Разрешения);
// Создаем таблицу команд
ТаблицаКоманд = ПолучитьТаблицуКоманд();
ДобавитьКоманду(ТаблицаКоманд, "Импорт Excel (Безопасный)", "ИмпортExcel", "ВызовКлиентскогоМетода", Истина);
ПараметрыРегистрации.Вставить("Команды", ТаблицаКоманд);
Возврат ПараметрыРегистрации;
КонецФункции
При регистрации такой обработки в справочнике «Дополнительные отчеты и обработки» БСП проанализирует массив разрешений и выведет администратору понятное окно со списком запрашиваемых прав. Администратор нажимает кнопку «Разрешить выполнение операций», после чего обработка сможет читать файлы и создавать объект Excel, оставаясь при этом в безопасном изолированном контейнере.
Использование COM-объекта Excel.Application на сервере 1С считается устаревшим подходом по нескольким причинам. Во-первых, для его работы на сервере должен быть физически установлен Microsoft Excel, что требует дополнительных лицензий. Во-вторых, этот метод принципиально не работает, если сервер 1С функционирует под управлением операционной системы Linux. В-третьих, COM-процессы часто зависают в оперативной памяти сервера, снижая общую производительность системы.
Современные версии платформы «1С:Предприятие 8» (начиная с 8.3) поддерживают нативное чтение файлов XLSX штатными средствами платформы через объект ТабличныйДокумент. Этот метод работает на любой операционной системе, не требует стороннего ПО и легко выполняется в безопасном режиме без запроса прав на COM-объекты.
Рассмотрим пример реализации импорта файла Excel без использования COM. Сначала на клиенте мы выбираем файл и помещаем его во временное хранилище, а затем на сервере читаем его с помощью табличного документа:
&НаКлиенте
Процедура ИмпортExcel(Команда)
// Настраиваем диалог выбора файла Excel
ДиалогОткрытия = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
ДиалогОткрытия.Фильтр = "Книга Excel (*.xlsx)|*.xlsx|Совместимый формат (*.xls)|*.xls";
ДиалогОткрытия.МножественныйВыбор = Ложь;
ДиалогОткрытия.Заголовок = "Выберите файл для загрузки";
Если ДиалогОткрытия.Выбрать() Тогда
ИмяФайлаКлиент = ДиалогОткрытия.ПолноеИмяФайла;
// Помещаем файл во временное хранилище для передачи на сервер
ОписаниеФайла = Новый ОписаниеПередаваемогоФайла(ИмяФайлаКлиент);
МассивФайлов = Новый Массив;
МассивФайлов.Добавить(ОписаниеФайла);
НачатьПомещениеФайловНаСервер(Новый ОписаниеОповещения("ПослеПомещенияФайла", ЭтотОбъект), МассивФайлов, , Ложь);
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ПослеПомещенияФайла(Результат, ДополнительныеПараметры) Экспорт
Если Результат.Количество() > 0 Тогда
// Получаем адрес временного хранилища, куда загрузился файл
АдресФайлаВХранилище = Результат[0].Адрес;
// Запускаем серверную процедуру чтения данных
ЗагрузитьФайлНаСервере(АдресФайлаВХранилище);
КонецЕсли;
КонецПроцедуры
&НаСервере
Процедура ЗагрузитьФайлНаСервере(АдресФайлаВХранилище)
// Создаем имя для временного файла на диске сервера
ИмяВременногоФайла = ПолучитьИмяВременногоФайла("xlsx");
// Извлекаем двоичные данные файла из хранилища и записываем во временный файл
ДвоичныеДанныеФайла = ПолучитьИзВременногоХранилища(АдресФайлаВХранилище);
ДвоичныеДанныеФайла.Записать(ИмяВременногоФайла);
// Читаем файл встроенным механизмом 1С без всякого Excel.Application
ТабДок = Новый ТабличныйДокумент;
Попытка
ТабДок.Прочитать(ИмяВременногоФайла, СпособЧтенияЗначенийТабличногоДокумента.Значение);
Исключение
ОбщегоНазначенияКлиентСервер.СообщитьПользователю("Не удалось прочитать файл! Ошибка: " + ОписаниеОшибки());
УдалитьФайлы(ИмяВременногоФайла);
Возврат;
КонецПопытки;
// Проанализируем содержимое табличного документа
ВсегоСтрок = ТабДок.ВысотаТаблицы;
Для НомерСтроки = 2 По ВсегоСтрок Цикл // Начинаем со второй строки (пропуская заголовок)
КодТовара = ТабДок.Область(НомерСтроки, 1).Текст;
Количество = ТабДок.Область(НомерСтроки, 2).Текст;
Цена = ТабДок.Область(НомерСтроки, 3).Текст;
Если ПустаяСтрока(КодТовара) Тогда
Продолжить;
КонецЕсли;
// Здесь мы пишем логику поиска номенклатуры и заполнения документа
// Например: ЗаполнитьСтрокуДокумента(КодТовара, Количество, Цена);
КонецЦикла;
// Обязательно удаляем за собой временный файл на сервере
УдалитьФайлы(ИмяВременногоФайла);
ОбщегоНазначенияКлиентСервер.СообщитьПользователю("Загрузка успешно завершена!");
КонецПроцедуры
Для работы этого алгоритма в безопасном режиме вам потребуется запросить только одно разрешение в СведенияОВнешнейОбработке() — на использование каталога временных файлов (РаботаВБезопасномРежиме.РазрешениеНаИспользованиеКаталогаВременныхФайлов(Истина, Истина)). Данный способ является наиболее стабильным, кроссплатформенным и безопасным с точки зрения администрирования 1С.