Как исправить ошибку использования модальных окон и настроить чтение Excel через COM в 1С?

Программист 1С v8.3 (Управляемые формы) 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← На главную

При разработке внешних обработок для современных конфигураций 1С (таких как УТ 11, БП 3.0, ERP) программисты часто сталкиваются с ситуацией, когда привычный код внезапно перестает работать. Одной из самых коварных является ошибка «Использование модальных окон в данном режиме запрещено». Часто она маскирует другую, более глубокую проблему, связанную с доступом к файлам или работой внешних компонентов. Разберем пошагово, как выявить истинную причину сбоя и правильно настроить чтение файлов Excel.

Причина 1: Режим использования модальности

Прежде всего, проанализируем ситуацию, описанную в теме. Автор получает сообщение о запрете модальных окон внутри блока Попытка...Исключение. Это происходит потому, что при возникновении любой ошибки в коде (например, не удалось найти файл) программа переходит в блок Исключение, где вызывается метод Предупреждение(). В управляемом приложении 1С 8.3 по умолчанию установлен режим «Запрещено» для модальных вызовов.

Для исправления именно этой визуальной ошибки нам необходимо заменить устаревший метод Предупреждение() на асинхронный аналог ПоказатьПредупреждение(). Рассмотрим правильный вариант написания кода:


ОписаниеОповещения = Новый ОписаниеОповещения("ЗавершитьРаботуСФайлом", ЭтотОбъект);
ПоказатьПредупреждение(ОписаниеОповещения, "Не удалось открыть документ Excel!");

Если же вы хотите быстро продолжить отладку и выяснить, какая именно ошибка скрывается за текстом о модальности, рекомендуем использовать метод Сообщить(), так как он не вызывает блокирующих окон и работает в любом режиме.

Причина 2: Ошибка COM-объекта (0x80080005)

Как мы видим из сообщений форума, после замены метода вывода сообщения всплыла реальная техническая проблема: Ошибка получения объекта COM: -2146959355(0x80080005): Ошибка при выполнении приложения-сервера. Это классическая проблема взаимодействия 1С и Microsoft Excel, особенно когда код выполняется на стороне сервера.

Рассмотрим подробнее, почему Excel отказывается запускаться как COM-объект:

  1. Отсутствие прав у пользователя службы 1С: Сервер 1С обычно работает под специальной учетной записью (например, USR1CV8). У этой учетной записи нет прав на интерактивный запуск приложений Office и, что более важно, у нее нет необходимых папок профиля.
  2. Разрядность систем: Если у вас установлен 64-битный сервер 1С и 32-битный Microsoft Office, они могут конфликтовать при попытке прямого вызова через Новый COMОбъект("Excel.Application").
  3. Отсутствие папок Desktop: Это «секретное» решение, которое помогает в 90% случаев при работе на сервере. Для работы Excel через COM-интерфейс в системе должны существовать определенные папки, даже если приложение запускается в невидимом режиме.

Для решения проблемы с папками Desktop создайте следующие директории вручную на сервере, где установлена 1С:

После создания папок перезагружать сервер обычно не требуется, Excel начнет открываться сразу.

Причина 3: Контекст выполнения (Клиент или Сервер)

Проанализируем еще один важный момент: где именно находится файл? Если пользователь выбрал файл на своем компьютере (на клиенте), а код ПолучитьCOMОбъект(ДокументExcel) выполняется на сервере, сервер просто «не увидит» этот путь.

Правильный алгоритм работы в управляемых формах должен быть следующим:

  1. Пользователь выбирает файл на клиенте.
  2. Файл помещается во временное хранилище через ПоместитьФайл().
  3. На сервере адрес из хранилища получается, файл сохраняется во временный каталог через ПолучитьИмяВременногоФайла("xlsx").
  4. И только после этого вызывается COM-объект для чтения данных из этого временного файла.

Рекомендуемое решение: Чтение через ТабличныйДокумент

Работа с COM-объектами считается нестабильной и медленной. Как справедливо заметили участники обсуждения в сообщении №10, в платформе 8.3 есть встроенный механизм, не требующий установки Excel на сервер. Это метод Прочитать() объекта ТабличныйДокумент.

Разберем пример кода, который работает быстрее и надежнее:


&НаСервере
Процедура ПрочитатьФайлExcelНаСервере(ПутьКФайлу)
    ТабДок = Новый ТабличныйДокумент;
    Попытка
        // Вторым параметром указываем способ чтения значений
        ТабДок.Прочитать(ПутьКФайлу, СпособЧтенияЗначенийТабличногоДокумента.Значение);
    Исключение
        Сообщить("Ошибка при чтении файла: " + ОписаниеОповещения());
        Возврат;
    КонецПопытки;

    // Теперь мы можем обходить строки и колонки как в обычной таблице 1С
    КоличествоСтрок = ТабДок.ВысотаТаблицы;
    Для НомерСтроки = 1 По КоличествоСтрок Цикл
        ЗначениеЯчейки = ТабДок.Область(НомерСтроки, 1).Текст;
        // Обработка данных...
    КонецЦикла;
КонецПроцедуры

Преимущества этого метода:

Как правильно закрывать COM-объект

Если же использование COM-объекта неизбежно (например, требуется сложное форматирование или запуск макросов), крайне важно гарантировать закрытие приложения Excel. Посмотрим на правильную структуру блока Попытка:


Попытка
    ExcelПриложение = Новый COMОбъект("Excel.Application");
    // Ваш код работы с файлом
    ExcelПриложение.Quit(); // Обязательное закрытие
Исключение
    Если ЗначениеЗаполнено(ExcelПриложение) Тогда
        ExcelПриложение.Quit();
    КонецЕсли;
    ЗаписьЖурналаРегистрации("Ошибка Excel", УровеньЖурналаРегистрации.Ошибка, , , ОписаниеОшибки());
КонецПопытки;

Подводя итог, отметим: если вы столкнулись с ошибкой модальности, первым делом проверьте, не пытаетесь ли вы вывести Предупреждение() или Вопрос() в коде, предназначенном для работы в управляемом режиме. А при возникновении «Неизвестной ошибки» при открытии Excel — проверьте наличие папок Desktop в системных профилях или переходите на использование встроенного объекта ТабличныйДокумент.

← На главную