При разработке внешних обработок для 1С программисты часто сталкиваются с ситуацией, когда созданная обработка заполнения прекрасно работает в новых документах, но становится недоступной (кнопка серая или неактивная), как только мы открываем документ из прошлого, уже закрытого периода. Разберемся, почему так происходит и как мы можем это исправить, используя различные подходы — от смены типа команды до архитектурных хитростей.
В современных конфигурациях, построенных на базе Библиотеки стандартных подсистем (БСП), поведение командных панелей жестко регламентировано. Когда документ попадает в период, закрытый датой запрета редактирования, или если у пользователя недостаточно прав для изменения объекта, платформа и программные механизмы БСП переводят форму в режим ТолькоПросмотр.
Система анализирует тип команды, которую мы зарегистрировали для нашей внешней обработки. Если указан тип ЗаполнениеОбъекта, БСП делает логичный вывод: раз это заполнение, значит, данные документа будут изменены. Поскольку изменять документ в закрытом периоде нельзя, система превентивно отключает кнопку, чтобы не вводить пользователя в заблуждение. Рассмотрим подробнее, как мы можем обойти это поведение, если наша обработка на самом деле не меняет данные или если нам жизненно необходимо запустить алгоритм даже для архивного документа.
Самый правильный технический способ — изменить описание команды в модуле объекта внешней обработки. Проанализируем структуру функции СведенияОВнешнейОбработке(). Обычно для обработок заполнения используется тип ЗаполнениеОбъекта. Нам же следует попробовать типы, которые не подразумевают модификацию данных «в темную».
Рассмотрим пример кода, где мы меняем тип команды на ОткрытиеФормы. В этом случае система позволит нажать на кнопку, так как открытие формы само по себе не является актом записи объекта.
Функция СведенияОВнешнейОбработке() Экспорт
ПараметрыРегистрации = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке("2.2.2.1");
ПараметрыРегистрации.Вид = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидОбработкиЗаполнениеОбъекта();
ПараметрыРегистрации.Назначение.Добавить("Документ.РеализацияТоваровУслуг");
НоваяКоманда = ПараметрыРегистрации.Команды.Добавить();
НоваяКоманда.Представление = "Обработать данные (открытие формы)";
НоваяКоманда.Идентификатор = "ОткрытьФормуДляАнализа";
// Вместо ТипКомандыЗаполнениеОбъекта используем ОткрытиеФормы
НоваяКоманда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыОткрытиеФормы();
НоваяКоманда.ПоказыватьОповещение = Истина;
Возврат ПараметрыРегистрации;
КонецФункции
При таком подходе кнопка в меню «Заполнить» останется активной. Выясним причину: система считает, что вы просто хотите посмотреть на дополнительные данные в интерфейсе обработки, а не перезаписать текущий документ.
Если специфика задачи позволяет, мы можем изменить Вид самой обработки при регистрации. Вместо ВидОбработкиЗаполнениеОбъекта() можно использовать ВидОбработкиДополнительнаяОбработка(). Разберем по шагам, что это изменит:
ОбъектыНазначения.Это классический прием, который часто использовался еще в эпоху обычных форм, но актуален и сейчас. Команды печати практически никогда не блокируются датой запрета редактирования, потому что печать — это чтение данных.
Мы можем зарегистрировать нашу обработку как Печатную форму. Выясним ситуацию: пользователю нужно увидеть результат обработки данных документа. Мы создаем команду печати, но вместо формирования стандартного табличного документа (ТабДок) программно открываем форму нашей обработки. Для системы это выглядит как процесс подготовки к печати, и она не препятствует вызову команды даже в документе десятилетней давности.
Посмотрим на пример реализации в модуле объекта:
Процедура Печать(МассивОбъектовНазначения, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода) Экспорт
// Здесь мы не формируем печатную форму, а вызываем нужную нам логику
// Например, открываем форму или выполняем расчет
ОткрытьФормуОбработки(МассивОбъектовНазначения);
КонецПроцедуры
Важно: При использовании этого метода стоит учитывать, что в некоторых жестко настроенных конфигурациях попытка изменения данных внутри «печатной формы» может привести к ошибке прав доступа или блокировке транзакции, если вы попытаетесь вызвать Объект.Записать().
Если мы не хотим менять тип команды и нам нужно оставить её именно в меню «Заполнить», мы можем прибегнуть к помощи расширений. Проанализируем процедуру ПриОпределенииКомандПодключенныхКОбъекту, которая находится в модуле менеджера документа или вызывается через общие модули БСП.
В этой процедуре можно переопределить свойство команды ИзменяетДанные. Если установить его в Ложь, БСП перестанет блокировать кнопку при включенном режиме «Только просмотр» для формы.
Рассмотрим, как это выглядит концептуально:
Команда.ИзменяетДанные = Ложь;.Это позволит кнопке быть активной, однако помните: если пользователь нажмет её и обработка попытается программно изменить и записать документ в закрытом периоде, платформа все равно выдаст ошибку «Объект заблокирован (Дата запрета изменения)». Поэтому данный метод хорош только в паре с логикой, которая не требует записи самого документа-владельца.
Подведем итог нашему анализу. Если ваша обработка служит для визуального контроля или получения данных на основании старого документа, используйте ТипКомандыОткрытиеФормы или регистрируйте её как Дополнительную обработку. Если же вам необходимо именно модифицировать старые документы, единственным легальным путем остается временное открытие периода (изменение даты запрета) администратором, так как любые программные обходы нарушают целостность данных и логику безопасности системы 1С.