При переходе с файлового варианта работы базы данных на клиент-серверный администраторы и разработчики часто сталкиваются со следующей проблемой: код, который без проблем формировал или читал файлы Excel на локальном компьютере пользователя, наотрез отказывается работать на сервере. При этом серверная служба выдает невнятные ошибки инициализации COM-объекта, зависает или просто аварийно завершает рабочий процесс rphost.
В этой статье мы подробно проанализируем, почему возникает этот классический конфликт разрядностей и контекстов безопасности Windows, а также разберем по шагам практические методы его устранения — как административными методами настройки операционной системы, так и путем перевода кода на современные нативные технологии 1С без использования сторонних приложений.
Для начала разберем по шагам механизм выполнения кода в разных режимах работы системы 1С:Предприятие:
Desktop), настроенные права на запуск приложений MS Office и одна разрядность с установленным Excel (чаще всего 32-битный клиент 1С работает с 32-битным Excel, либо операционная система сама прозрачно связывает их в рамках одной сессии).rphost. По умолчанию служба сервера 1С работает под специальной системной учетной записью (например, USR1CV8). У этого пользователя нет интерактивного профиля, нет рабочего стола, и он сильно ограничен в правах запуска внешних приложений через DCOM. Более того, наш сервер 1С имеет 32-разрядную архитектуру, а установленный на сервере Microsoft Excel — 64-разрядный. Прямой запуск 64-битного COM-сервера внутри 32-битного процесса невозможен без специальной прослойки-суррогата.Рассмотрим подробнее три основных способа решения этой проблемы, начиная с настройки операционной системы и заканчивая оптимизацией самого кода обработки.
Если код обработки защищен или его переписывание крайне нежелательно, мы можем заставить операционную систему корректно связывать 32-разрядный процесс сервера 1С с 64-разрядным Excel. Для этого нам понадобится выполнить три последовательных шага.
Шаг 1.1. Исправление ошибки отсутствия папок Desktop
Это самая распространенная скрытая проблема при запуске приложений пакета MS Office под системными учетными записями. Excel при старте через COM-интерфейс обязательно инициализирует базовые каталоги пользователя и пытается найти папку Рабочего стола. Если ее нет, процесс аварийно завершается.
Нам необходимо вручную создать эти папки на сервере, где установлен 1С:Предприятие:
C:\Windows\SysWOW64\config\systemprofile\Desktop (это папка для работы 32-разрядных приложений в 64-разрядной операционной системе).C:\Windows\System32\config\systemprofile\Desktop (для общего соответствия системных профилей).USR1CV8), полные права (чтение, запись, изменение).Шаг 1.2. Регистрация связи разрядностей в реестре (Wow6432Node)
Поскольку сервер 1С является 32-битным, он осуществляет поиск COM-классов в ветке реестра Wow6432Node. В то же время 64-битный Excel регистрирует свои интерфейсы в основной 64-битной ветке. Нам нужно явно связать их через общий идентификатор приложения (AppID).
regedit от имени Администратора.HKEY_CLASSES_ROOT\AppID.EXCEL.EXE (если его нет, создайте этот раздел вручную).EXCEL.EXE создайте новый Строковый параметр (String Value) с именем AppID и установите для него значение идентификатора класса Excel: {00020812-0000-0000-C000-000000000046}.Шаг 1.3. Настройка Служб компонентов (DCOM)
Теперь укажем операционной системе, с какими правами и в каком контексте разрешено запускать приложение Microsoft Excel:
mmc comexp.msc /32Microsoft Excel Application (или Приложение Microsoft Excel), нажмите на него правой кнопкой мыши и выберите «Свойства».USR1CV8). Установите для него флажки «Локальный запуск» и «Локальная активация».excel.exe в фоновом режиме.После выполнения этих шагов перезапустите службу сервера 1С:Предприятие и проверьте работу обработки. В большинстве случаев COM-объект начнет создаваться успешно.
Использование COM-соединения с приложениями Microsoft Office на стороне сервера официально не рекомендуется самой корпорацией Microsoft. В условиях интенсивной многопоточной работы сервера 1С это неизбежно приводит к утечкам оперативной памяти, зависаниям «фантомных» процессов excel.exe в диспетчере задач и снижению общей производительности системы.
Начиная с версии платформы 8.3.6, в 1С:Предприятие встроены мощные механизмы прямого чтения и записи файлов формата XLSX на уровне платформы. Этот метод работает на сервере любой разрядности, под любыми операционными системами (включая Linux) и выполняется в десятки раз быстрее, чем обращение к COM.
Рассмотрим пример того, как можно переписать код для нативной работы с файлом Excel.
Пример 1. Нативное чтение файла XLSX без использования Excel
Вместо создания объекта COMОбъект("Excel.Application") мы можем загрузить файл напрямую в объект ТабличныйДокумент:
&НаСервере
Процедура ПрочитатьФайлExcelНаСервере(ПутьКФайлу)
ТабДок = Новый ТабличныйДокумент;
Попытка
// Платформа сама определит структуру XLSX и прочитает данные
ТабДок.Прочитать(ПутьКФайлу, СпособСравненияСимволов.ТочноеСовпадение);
Исключение
ЗаписьЖурналаРегистрации("Чтение Excel", УровеньЖурналаРегистрации.Ошибка,,,
ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
ВызватьИсключение "Не удалось прочитать файл Excel: " + ОписаниеОшибки();
КонецПопытки;
// Теперь мы можем обойти строки и колонки табличного документа как обычную таблицу
КоличествоСтрок = ТабДок.ВысотаТаблицы;
КоличествоКолонок = ТабДок.ШиринаТаблицы;
Для НомерСтроки = 1 По КоличествоСтрок Цикл
// Пример получения значения из первой колонки
ЗначениеЯчейки = ТабДок.Область(НомерСтроки, 1).Текст;
// Обработка полученных данных...
КонецЦикла;
КонецПроцедуры
Пример 2. Нативная выгрузка данных в формат XLSX
Если вам нужно сформировать отчет или выгрузить таблицу значений в файл формата Excel на сервере, используйте следующий шаблон кода:
&НаСервере
Процедура ВыгрузитьДанныеВExcelНаСервере(ПутьКФайлу, ТаблицаДанных)
ТабДок = Новый ТабличныйДокумент;
// Заполняем шапку таблицы
Для НомерКолонки = 1 По ТаблицаДанных.Колонки.Количество() Цикл
ОбластьШапки = ТабДок.Область(1, НомерКолонки);
ОбластьШапки.Текст = ТаблицаДанных.Колонки[НомерКолонки - 1].Имя;
ОбластьШапки.Шрифт = Новый Шрифт(,,Истина); // Жирный шрифт для шапки
КонецЦикла;
// Заполняем строки данными
НомерСтрокиДокумента = 2;
Для Каждого СтрокаДанных Из ТаблицаДанных Цикл
Для НомерКолонки = 1 По ТаблицаДанных.Колонки.Количество() Цикл
ТабДок.Область(НомерСтрокиДокумента, НомерКолонки).Текст = СтрокаДанных[НомерКолонки - 1];
КонецЦикла;
НомерСтрокиДокумента = НомерСтрокиДокумента + 1;
КонецЦикла;
Попытка
// Записываем сформированный документ в формате XLSX
ТабДок.Записать(ПутьКФайлу, ТипФайлаТабличногоДокумента.XLSX);
Исключение
ЗаписьЖурналаРегистрации("Запись Excel", УровеньЖурналаРегистрации.Ошибка,,,
ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
ВызватьИсключение "Ошибка сохранения файла: " + ОписаниеОшибки();
КонецПопытки;
КонецПроцедуры
Использование встроенных платформенных методов 1С полностью снимает головную боль с настройкой разрядностей серверов, прав DCOM и лицензированием офисных продуктов на серверах компании.
Если бизнес-процессы компании завязаны на сложные алгоритмы COM-интеграции (например, использование специфических макросов Excel, сложное условное форматирование шаблонов, генерация графиков и диаграмм через VBA), то лучшим стратегическим решением будет переход на 64-разрядный сервер 1С.
Этот переход дает следующие преимущества:
rphost получают возможность адресовать более 4 ГБ оперативной памяти, что исключает падение сервера при обработке больших массивов данных.Для осуществления этого перехода потребуется приобрести лицензию на 64-разрядный сервер 1С:Предприятие и переустановить серверную часть платформы. Однако, если бюджет ограничен, детальное выполнение настроек из Способа 1 или перевод конфигурации на методы из Способа 2 позволят решить проблему без дополнительных затрат.