При автоматизации формирования отчетов в формате Excel из 1С через COM-объект разработчики нередко сталкиваются с неприятной «исключительной ошибкой» при вызове метода Protect. Чаще всего эта проблема проявляется не при простом сохранении одного листа, а при работе с книгами, содержащими несколько вкладок, особенно если файл формируется программно через ПакетОтображаемыхДокументов.
Давайте разберем, почему так происходит, и проанализируем эффективный способ обхода этого ограничения.
Основная сложность заключается в том, что Excel при взаимодействии с ним через COM «ожидает» визуального фокуса на листе, который подвергается защите. Когда вы создаете или наполняете данными несколько листов программно, внутренний контекст объекта Application или Workbook может не успевать или не «уметь» самостоятельно переключать активный фокус между ними. В результате метод Protect, вызываемый для объекта Worksheet, который в текущий момент не является «активным» для Excel, завершается ошибкой.
Чтобы метод Protect отработал корректно для каждого листа в книге, необходимо принудительно «активировать» их. Это имитирует ручное переключение вкладок пользователем, что заставляет COM-объект обновить внутреннее состояние и предоставить доступ к свойствам защиты.
Рассмотрим по шагам, как это реализовать в коде 1С:
Excel.Select.Protect с нужными параметрами.Давайте посмотрим на пример программной реализации такого подхода:
// Предположим, что объект Книга у нас уже инициализирован
Для Счетчик = 1 По Книга.WorkSheets.Count Цикл
// Принудительно выбираем лист, чтобы он стал активным
Книга.WorkSheets(Счетчик).Select();
// Теперь можно безопасно накладывать защиту
// 12345 - пароль, остальные параметры (1) включают защиту содержимого и объектов
Книга.WorkSheets(Счетчик).Protect("12345", 1, 1, 1);
КонецЦикла;
Помимо метода Select, стоит учитывать несколько практических советов, которые помогут сделать ваш код стабильнее:
1. Использование метода Unprotect
Если скрипт может запускаться повторно для одного и того же файла, всегда рекомендуется в начале блока обработки вызывать метод Unprotect(). Это позволит избежать ошибок, если на листе уже установлена защита, пароль от которой совпадает с заданным.
2. Использование всех аргументов метода Protect
Метод Protect имеет множество параметров: Password, DrawingObjects, Contents, Scenarios, UserInterfaceOnly и другие. Если вы используете параметр UserInterfaceOnly := True, это дает возможность программно изменять данные на листе из 1С, при этом ограничивая действия обычного пользователя в Excel. При возникновении проблем с типизацией аргументов рекомендуем передавать их все явно в порядке, определенном документацией Microsoft Excel.
3. Проблема структуры файла
Если вы формируете файл с помощью ТабличныйДокумент.Записать(ИмяФайла, ТипФайлаТабличногоДокумента.XLSX), структура файла может быть оптимизирована специфическим образом. В редких случаях конфликты прав доступа не дают применить защиту «на лету». В такой ситуации лучше сначала полностью сохранить книгу, закрыть COM-объект, а затем открыть этот же файл повторно исключительно для наложения защиты.
Заключение
Использование цикла с командой Select() является самым надежным и простым способом решения данной проблемы. Это заставляет COM-сервер Excel синхронизировать состояние листов с операциями автоматизации. Применяя этот подход, вы сможете успешно защищать паролем любые отчеты, формируемые из 1С, независимо от количества вкладок в книге.