Как исправить ошибку «Нельзя установить свойство Locked класса Range» при снятии защиты с ячеек Excel в 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При интеграции 1С с Microsoft Excel через COM-соединение разработчики нередко сталкиваются с задачей выборочной защиты листа: необходимо заблокировать формулы и структуру таблицы, оставив определенный диапазон ячеек доступным для редактирования пользователю. Однако при попытке массово снять флаг блокировки с диапазона строк или колонок часто возникает исключение: «Нельзя установить свойство Locked класса Range» (ошибка времени выполнения COM / ошибка 1004). При этом изменение свойства для одной отдельной ячейки через коллекцию Cells отрабатывает без сбоев. Проанализируем причины такого поведения и разберем надежные способы решения этой проблемы.

Почему возникает ошибка при установке свойства Locked для диапазона

Выясним причину, по которой Excel блокирует прямое присвоение значения свойству Locked у целого диапазона. Рассмотрим основные факторы:

  1. Наличие объединенных ячеек в диапазоне: это самая частая причина. Если в выбранную область попадают объединенные ячейки или диапазон пересекает их границы, внутренние механизмы Excel не позволяют пакетно изменить свойство Locked. Одиночная ячейка вне объединения меняется без проблем, но для диапазона возникает конфликт объектной модели.
  2. Фактически не снятая защита листа: вызов метода Unprotect() без передачи параметров не снимает защиту, если на листе установлен пароль. В режиме фоновой автоматизации через COM диалоговое окно ввода пароля не появляется, защита остается активной, и любая попытка изменить атрибут блокировки ячеек вызывает исключение.
  3. Особенности контекста и фокуса в COM-модели: в некоторых версиях Excel попытка прямой модификации свойств неактивного диапазона или листа без предварительной активации приводит к внутренней ошибке объектной модели.
  4. Пересечение со специальными объектами: если диапазон частично затрагивает «Умные таблицы» (ListObject), сводные таблицы или диапазоны со специальными правилами проверки данных, действуют ограничения структуры таблицы.

Способ 1. Корректная обработка объединенных ячеек

Если в вашем диапазоне присутствуют объединенные ячейки, разберем по шагам, как правильно обойти это ограничение. Мы можем либо временно отменить объединение, либо обращаться к объединенной области через свойство MergeArea.

Посмотрим на пример временного разъединения ячеек перед снятием защиты:


Лист = ЭксельКнига.Sheets(1);
Лист.Unprotect();

Область = Лист.Range("A1:B5");
Область.UnMerge();
Область.Locked = Ложь;

Если же структура документа требует сохранения объединения, применим поэлементный обход с обращением к MergeArea:


Лист = ЭксельКнига.Sheets(1);
Лист.Unprotect();

Для НомерСтроки = 1 По 5 Цикл
    Для НомерКолонки = 1 По 2 Цикл
        ТекущаяЯчейка = Лист.Cells(НомерСтроки, НомерКолонки);
        ТекущаяЯчейка.MergeArea.Locked = Ложь;
    КонецЦикла;
КонецЦикла;

Способ 2. Снятие защиты с явным указанием пароля

Проанализируем ситуацию, когда лист защищен паролем. Метод Unprotect() требует передачи правильной парольной строки. Если пароль не передан или передан неверно, лист остается заблокированным. Рассмотрим правильный синтаксис вызова:


ПарольЛиста = "МойПароль123";

Лист = ЭксельКнига.Sheets(1);
Лист.Unprotect(ПарольЛиста);

Лист.Range("A1:B5").Locked = Ложь;
Лист.Protect(ПарольЛиста);

Способ 3. Изменение свойства через выделение (Selection)

При записи макроса в Excel действия пользователя транслируются через объект выделения. В некоторых версиях MS Office модель COM требует явной активации листа и фокуса на диапазоне для корректного применения стилей и защитных свойств. Рассмотрим обходной путь через вызов Select():


Лист = ЭксельКнига.Sheets(1);
Лист.Activate();

Лист.Range("A1:B5").Select();
Лист.Application.Selection.Locked = Ложь;

Способ 4. Использование механизма AllowEditRanges

Вместо непосредственного изменения свойства Locked у каждой ячейки мы можем использовать штатный механизм диапазонов, разрешенных для редактирования. В объектной модели Excel за это отвечает коллекция AllowEditRanges. Это позволяет оставить ячейки заблокированными на системном уровне, но открыть доступ к их редактированию в рамках защищенного листа.

Посмотрим на пример добавления диапазона:


Лист = ЭксельКнига.Sheets(1);
Лист.Unprotect("ПарольЛиста");

// Добавляем диапазон в список разрешенных областей
Лист.Protection.AllowEditRanges.Add("РазрешеннаяОбласть", Лист.Range("A1:B5"));

Лист.Protect("ПарольЛиста");

Альтернатива: отказ от COM в пользу встроенного объекта ТабличныйДокумент

Рассмотрим подробнее ограничения COM-технологии. Использование COMОбъект("Excel.Application") жестко привязывает решение к операционной системе Windows и установленному пакету Microsoft Office. Это решение не будет работать на серверах под управлением Linux, а также создает риск зависания процессов EXCEL.EXE при сбоях фоновых заданий.

Платформа 1С:Предприятие умеет напрямую работать с файлами формата XLSX через объект ТабличныйДокумент. Разберем кроссплатформенный вариант установки защиты и разблокировки ячеек без привлечения сторонних приложений:


ТабДок = Новый ТабличныйДокумент;
ТабДок.Прочитать(ПутьКФайлу);

// Снимаем защиту с нужного диапазона ячеек
ОбластьРедактирования = ТабДок.Область("R1C1:R5C2");
ОбластьРедактирования.Защита = Ложь;

// Включаем общую защиту табличного документа
ТабДок.Защита = Истина;

// Сохраняем результат обратно в формат Excel
ТабДок.Записать(ПутьКФайлу, ТипФайлаТабличногоДокумента.XLSX);

Такой подход обеспечивает высокую скорость обработки данных, исключает утечки памяти COM-процессов и гарантирует стабильную работу как в файловом, так и в клиент-серверном варианте на любой операционной системе.

← На главную