При переносе программного кода, работающего с файлами Microsoft Excel, из файлового режима работы 1С в клиент-серверный (SQL) разработчики часто сталкиваются с неприятным исключением: «Ошибка при вызове конструктора (COMОбъект): -247024891 (0x80070005) Access is denied» (или «Отказано в доступе»). В файловой базе под управлением Windows всё работает корректно, но стоит запустить тот же код на сервере, как система выдает критический сбой.
В этой статье мы подробно разберем, почему возникает данная ошибка, проанализируем внутренние механизмы взаимодействия сервера 1С и Windows, а также рассмотрим три различных способа решения проблемы: от точечной настройки безопасности операционной системы до современного нативного метода работы с файлами Excel средствами самой платформы 1С:Предприятие.
Давайте проанализируем ситуацию изнутри. Когда мы запускаем код на стороне тонкого или толстого клиента в файловом режиме, процесс Microsoft Excel инициализируется от имени текущего авторизованного пользователя Windows. Этот пользователь обладает полноценным профилем, правами на запуск интерактивных приложений и доступом к собственному Рабочему столу.
В клиент-серверном режиме код выполняется на стороне сервера приложений 1С. По умолчанию служба Агента сервера 1С (1C:Enterprise 8.3 Server Agent) запускается от имени специальной системной учетной записи — обычно это локальный пользователь USR1CV8 или USR1CV83. Данный пользователь является сильно ограниченным в правах в целях безопасности. У него:
Desktop (Рабочий стол).Самый простой и быстрый способ, к которому прибегают многие администраторы (и который помог автору темы на форуме), — это добавление пользователя USR1CV8 в группу «Администраторы» операционной системы. Внимание! Это серьезный антипаттерн безопасности. Если злоумышленник сможет выполнить произвольный вредоносный код через уязвимость в платформе или конфигурации 1С, он мгновенно получит полные административные права на всем сервере. Ниже мы рассмотрим только безопасные и правильные способы решения проблемы.
---
Вместо предоставления пользователю службы 1С избыточных прав администратора, мы можем выдать ему точечное разрешение на запуск и активацию конкретно этого COM-объекта. Рассмотрим этот процесс по шагам:
dcomcnfg и нажмите Enter. Откроется оснастка «Службы компонентов».mmc comexp.msc /32
USR1CV8), и установите для него галочки напротив пунктов Локальный запуск и Локальная активация. Нажмите ОК.Если вы не обнаружили пункт «Microsoft Excel Application» в списке DCOM, это означает, что объект не зарегистрирован в реестре должным образом. Чтобы исправить это, откройте редактор реестра regedit, перейдите по пути HKEY_CLASSES_ROOT\AppID\EXCEL.EXE (если раздела нет, создайте его вручную) и добавьте строковый параметр с именем AppID и значением {00020812-0000-0000-C000-000000000046}.
---
Даже после успешной настройки прав в DCOM приложение Excel при инициализации в фоновом режиме может завершаться аварийно. Происходит это потому, что движок Microsoft Office при старте обязательно пытается проверить наличие папки Рабочего стола в профиле пользователя. Поскольку служба сервера 1С работает под системной учетной записью, такой папки физически не существует.
Для решения этой проблемы нам необходимо вручную создать директорию Desktop в системных профилях Windows и предоставить пользователю 1С полные права на чтение и запись в эту папку. Разберем, где именно нужно создать эту директорию:
C:\Windows\SysWOW64\config\systemprofile\Desktop
C:\Windows\System32\config\systemprofile\Desktop
После создания папки нажмите на нее правой кнопкой мыши, перейдите в свойства на вкладку Безопасность, добавьте пользователя службы сервера 1С (USR1CV8) и предоставьте ему Полный доступ. После выполнения этих шагов перезагрузите сервер приложений 1С для применения изменений.
---
Давайте проанализируем архитектуру использования COM-объектов. Использование MS Excel через COM на стороне сервера имеет колоссальное количество недостатков:
excel.exe часто зависают в оперативной памяти сервера, потребляя ресурсы.Начиная с версии платформы 8.3.6, в 1С встроен мощный и быстрый механизм работы с файлами .xlsx и .xls напрямую, без привлечения сторонних приложений. Мы можем использовать объект ТабличныйДокумент для чтения файлов на сервере. Посмотрим на пример программного кода, который полностью заменяет устаревший COM-объект:
// Создаем объект табличного документа для загрузки данных
ТабДок = Новый ТабличныйДокумент;
Попытка
// Чтение файла напрямую на сервере без участия Microsoft Excel
ТабДок.Прочитать(ПутьКФайлу, СпособЧтенияЗначенийТабличногоДокумента.Значение);
Исключение
ВызватьИсключение "Не удалось прочитать файл Excel. Ошибка: " + ОписаниеОшибки();
КонецПопытки;
// Используем ПостроительЗапроса для моментальной конвертации табличного документа в Таблицу Значений
Построитель = Новый ПостроительЗапроса;
Построитель.ИсточникДанных = Новый ОписаниеИсточникаДанных(ТабДок.Область());
Построитель.ЗаполнитьНастройки();
Построитель.Выполнить();
// Получаем готовую таблицу значений с данными из Excel
ТаблицаДанных = Построитель.Результат.Выгрузить();
// Теперь мы можем обойти полученную таблицу стандартным циклом
Для Каждого СтрокаДанных Из ТаблицаДанных Цикл
// Обрабатываем данные, например:
// КодНоменклатуры = СтрокаДанных.Колонка1;
// Наименование = СтрокаДанных.Колонка2;
КонецЦикла;
Рассмотрим подробнее преимущества этого подхода. Во-первых, скорость чтения файла через встроенный ТабличныйДокумент и ПостроительЗапроса превосходит скорость работы COM-соединения в десятки раз. Во-вторых, этот код будет абсолютно кроссплатформенным и запустится как на Windows, так и на Linux. В-третьих, вы навсегда застрахованы от зависших процессов в диспетчере задач сервера и проблем с правами доступа к DCOM.