При разработке внешних обработок для современных конфигураций 1С (таких как УТ 11, БП 3.0, ERP) программисты часто сталкиваются с ситуацией, когда привычный код внезапно перестает работать. Одной из самых коварных является ошибка «Использование модальных окон в данном режиме запрещено». Часто она маскирует другую, более глубокую проблему, связанную с доступом к файлам или работой внешних компонентов. Разберем пошагово, как выявить истинную причину сбоя и правильно настроить чтение файлов Excel.
Прежде всего, проанализируем ситуацию, описанную в теме. Автор получает сообщение о запрете модальных окон внутри блока Попытка...Исключение. Это происходит потому, что при возникновении любой ошибки в коде (например, не удалось найти файл) программа переходит в блок Исключение, где вызывается метод Предупреждение(). В управляемом приложении 1С 8.3 по умолчанию установлен режим «Запрещено» для модальных вызовов.
Для исправления именно этой визуальной ошибки нам необходимо заменить устаревший метод Предупреждение() на асинхронный аналог ПоказатьПредупреждение(). Рассмотрим правильный вариант написания кода:
ОписаниеОповещения = Новый ОписаниеОповещения("ЗавершитьРаботуСФайлом", ЭтотОбъект);
ПоказатьПредупреждение(ОписаниеОповещения, "Не удалось открыть документ Excel!");
Если же вы хотите быстро продолжить отладку и выяснить, какая именно ошибка скрывается за текстом о модальности, рекомендуем использовать метод Сообщить(), так как он не вызывает блокирующих окон и работает в любом режиме.
Как мы видим из сообщений форума, после замены метода вывода сообщения всплыла реальная техническая проблема: Ошибка получения объекта COM: -2146959355(0x80080005): Ошибка при выполнении приложения-сервера. Это классическая проблема взаимодействия 1С и Microsoft Excel, особенно когда код выполняется на стороне сервера.
Рассмотрим подробнее, почему Excel отказывается запускаться как COM-объект:
USR1CV8). У этой учетной записи нет прав на интерактивный запуск приложений Office и, что более важно, у нее нет необходимых папок профиля.Новый COMОбъект("Excel.Application").Для решения проблемы с папками Desktop создайте следующие директории вручную на сервере, где установлена 1С:
C:\Windows\SysWOW64\config\systemprofile\DesktopC:\Windows\System32\config\systemprofile\DesktopПосле создания папок перезагружать сервер обычно не требуется, Excel начнет открываться сразу.
Проанализируем еще один важный момент: где именно находится файл? Если пользователь выбрал файл на своем компьютере (на клиенте), а код ПолучитьCOMОбъект(ДокументExcel) выполняется на сервере, сервер просто «не увидит» этот путь.
Правильный алгоритм работы в управляемых формах должен быть следующим:
ПоместитьФайл().ПолучитьИмяВременногоФайла("xlsx").Работа с COM-объектами считается нестабильной и медленной. Как справедливо заметили участники обсуждения в сообщении №10, в платформе 8.3 есть встроенный механизм, не требующий установки Excel на сервер. Это метод Прочитать() объекта ТабличныйДокумент.
Разберем пример кода, который работает быстрее и надежнее:
&НаСервере
Процедура ПрочитатьФайлExcelНаСервере(ПутьКФайлу)
ТабДок = Новый ТабличныйДокумент;
Попытка
// Вторым параметром указываем способ чтения значений
ТабДок.Прочитать(ПутьКФайлу, СпособЧтенияЗначенийТабличногоДокумента.Значение);
Исключение
Сообщить("Ошибка при чтении файла: " + ОписаниеОповещения());
Возврат;
КонецПопытки;
// Теперь мы можем обходить строки и колонки как в обычной таблице 1С
КоличествоСтрок = ТабДок.ВысотаТаблицы;
Для НомерСтроки = 1 По КоличествоСтрок Цикл
ЗначениеЯчейки = ТабДок.Область(НомерСтроки, 1).Текст;
// Обработка данных...
КонецЦикла;
КонецПроцедуры
Преимущества этого метода:
EXCEL.EXE в диспетчере задач.Если же использование COM-объекта неизбежно (например, требуется сложное форматирование или запуск макросов), крайне важно гарантировать закрытие приложения Excel. Посмотрим на правильную структуру блока Попытка:
Попытка
ExcelПриложение = Новый COMОбъект("Excel.Application");
// Ваш код работы с файлом
ExcelПриложение.Quit(); // Обязательное закрытие
Исключение
Если ЗначениеЗаполнено(ExcelПриложение) Тогда
ExcelПриложение.Quit();
КонецЕсли;
ЗаписьЖурналаРегистрации("Ошибка Excel", УровеньЖурналаРегистрации.Ошибка, , , ОписаниеОшибки());
КонецПопытки;
Подводя итог, отметим: если вы столкнулись с ошибкой модальности, первым делом проверьте, не пытаетесь ли вы вывести Предупреждение() или Вопрос() в коде, предназначенном для работы в управляемом режиме. А при возникновении «Неизвестной ошибки» при открытии Excel — проверьте наличие папок Desktop в системных профилях или переходите на использование встроенного объекта ТабличныйДокумент.