Как сделать внешнюю обработку доступной на форме документа при установленной дате запрета изменения

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

В практике разработчика 1С часто возникает ситуация, когда необходимо запустить внешнюю обработку из формы документа, который находится в «закрытом» периоде. Типичный пример: документ уже нельзя редактировать из-за установленной даты запрета, но пользователю все еще нужно выполнить действие, не меняющее данные самого документа, например, отправить СМС-уведомление или выгрузить данные во внешнюю систему. Разберем подробно, почему кнопка вызова обработки становится неактивной и как это исправить несколькими способами.

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

Проанализируем стандартное поведение Библиотеки стандартных подсистем (БСП). Когда в конфигурации установлена дата запрета изменения данных, подсистема «Даты запрета изменения» при открытии формы документа проверяет, попадает ли дата документа в закрытый период. Если попадает, форма переводится в режим ТолькоПросмотр = Истина.

Внешние обработки, зарегистрированные с видом ЗаполнениеОбъекта, по своей логике предназначены для модификации данных объекта. БСП автоматически отслеживает состояние формы: если документ доступен только для чтения, то все команды из группы «Заполнение» блокируются платформой или программным кодом БСП, чтобы пользователь не смог инициировать изменение данных. Это логичное поведение для защиты целостности учета, но оно мешает сервисным функциям.

Способ 1. Изменение вида обработки на «Дополнительную обработку»

Первый и самый корректный с точки зрения архитектуры БСП способ — изменить тип регистрации обработки. Если ваша обработка не меняет реквизиты документа, а лишь выполняет внешние действия (отправка почты, СМС, экспорт), ее не следует регистрировать как «Заполнение объекта».

Рассмотрим, как изменить функцию СведенияОВнешнейОбработке в модуле объекта:


Функция СведенияОВнешнейОбработке() Экспорт
    ПараметрыРегистрации = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке("3.1.2.0");
    
    // Вместо ВидОбработкиЗаполнениеОбъекта() используем ДополнительнаяОбработка
    ПараметрыРегистрации.Вид = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидОбработкиДополнительнаяОбработка();
    
    ПараметрыРегистрации.Наименование = "Отправка СМС из документа";
    ПараметрыРегистрации.Назначение.Добавить("Документ.РеализацияТоваровУслуг");
    
    // Добавляем команду
    НоваяКоманда = ПараметрыРегистрации.Команды.Добавить();
    НоваяКоманда.Представление = "Отправить СМС";
    НоваяКоманда.Идентификатор = "ОтправитьСМС";
    НоваяКоманда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипВызоваВызовСерверногоМетода();
    НоваяКоманда.ПоказыватьОповещение = Истина;
    
    Возврат ПараметрыРегистрации;
КонецФункции

После такого изменения кнопка вызова обработки переместится из меню «Заполнение» в меню «Дополнительные обработки» (или просто появится в списке доступных обработок для данного типа документа). Важно то, что меню «Дополнительные обработки» обычно не блокируется датой запрета изменения, так как система считает их безопасными для данных.

Способ 2. Использование свойства «ИзменяетДанные»

Если вы хотите оставить обработку именно в меню заполнения, можно попытаться «обмануть» механизм блокировки, указав системе, что конкретная команда не приводит к изменению данных объекта. В структуре команд, которую мы возвращаем в БСП, есть свойство ИзменяетДанные.

Проанализируем пример настройки команды:


Команда = ПараметрыРегистрации.Команды.Добавить();
Команда.Представление = "Отправить СМС (без изменения документа)";
Команда.Идентификатор = "ОтправитьСМС_БезИзменения";
Команда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипВызоваВызовКлиентскогоМетода();
// Указываем, что данные не меняются
Команда.ИзменяетДанные = Ложь; 

В некоторых версиях БСП этот флаг позволяет кнопке оставаться активной даже в режиме «Только просмотр». Однако стоит учитывать, что в последних версиях платформы и БСП приоритет отдается общему состоянию формы, поэтому этот метод может работать не во всех конфигурациях.

Способ 3. Использование вида «Печать»

Это «хитрый» способ, который часто используют разработчики, чтобы гарантированно обойти любые блокировки. Команды печати никогда не блокируются датой запрета, так как печать документа — это базовое право пользователя даже в закрытом периоде.

Выясним, как это реализовать:

  1. Устанавливаем ПараметрыРегистрации.Вид = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидОбработкиПечать();.
  2. В модуле объекта создаем процедуру Печать (вместо ВыполнитьКоманду).
  3. Внутри процедуры Печать вместо формирования табличного документа пишем код отправки СМС.

Пользователь увидит кнопку в меню «Печать». Это может быть не совсем логично с точки зрения интерфейса, но это самый надежный способ сделать функционал доступным без изменения кода самой конфигурации.

Способ 4. Реализация через расширение конфигурации

Если варианты с внешней обработкой не подходят и кнопка нужна на «видном месте», оптимальным решением будет использование расширения. В этом случае мы программно добавляем кнопку на форму и управляем ее доступностью независимо от стандартных механизмов БСП.

Разберем по шагам реализацию в расширении:

Шаг 1. Перехват события создания формы

В модуле формы документа (в расширении) добавим процедуру-обертку для ПриСозданииНаСервере:


&НаСервере
Процедура Расш1_ПриСозданииНаСервереПосле(Отказ, СтандартнаяОбработка)
    
    // Создаем команду формы
    ИмяКоманды = "Расш1_ОтправитьСМС";
    МояКоманда = Команды.Добавить(ИмяКоманды);
    МояКоманда.Действие = "Расш1_ОтправитьСМС_Клиент";
    МояКоманда.Заголовок = "Отправить СМС";
    
    // Важный момент: указываем, что команда не меняет сохраняемые данные
    МояКоманда.ИзменяетСохраняемыеДанные = Ложь;
    
    // Добавляем кнопку на форму
    НоваяКнопка = Элементы.Добавить("Расш1_КнопкаОтправитьСМС", Тип("КнопкаФормы"), Элементы.КоманднаяПанельФормы);
    НоваяКнопка.ИмяКоманды = ИмяКоманды;
    НоваяКнопка.Вид = ВидКнопкиФормы.ОбычнаяКнопка;
    
    // КЛЮЧЕВОЙ ПАРАМЕТР: разрешаем работу кнопки в режиме просмотра
    НоваяКнопка.ТолькоВоПросмотре = Истина;
    
КонецПроцедуры

Шаг 2. Обработка нажатия на клиенте


&НаКлиенте
Процедура Расш1_ОтправитьСМС_Клиент(Команда)
    // Здесь вызываем серверный метод отправки СМС
    Расш1_ОтправитьСМС_НаСервере(Объект.Ссылка);
    ПоказатьОповещениеПользователя("Успех", , "СМС отправлено успешно!");
КонецПроцедуры

Обратите внимание на свойство ТолькоВоПросмотре = Истина. Без него платформа автоматически сделает кнопку недоступной, как только ЭтаФорма.ТолькоПросмотр станет равным Истина. Использование расширения позволяет обойти ограничения БСП, сохраняя полный контроль над поведением интерфейса.

Способ 5. Регистрация как «Дополнительный отчет»

Если задача заключается исключительно в получении данных из документа и их обработке (без записи чего-либо в базу), можно зарегистрировать внешнюю обработку как «Дополнительный отчет». Отчеты по определению доступны для работы в любых периодах.

При регистрации отчета вы также можете указать «Назначение» (конкретные документы). В этом случае в меню «Отчеты» формы документа появится ссылка на ваш «отчет» (который на самом деле является обработкой отправки СМС). При нажатии откроется форма обработки, где пользователь сможет нажать кнопку «Выполнить».

Резюме и рекомендации

Мы проанализировали ситуацию и выяснили, что блокировка кнопок в закрытом периоде — это штатная работа системы защиты данных. Для решения задачи выберите наиболее подходящий вам путь:

Помните, что при использовании любого из этих методов вы берете на себя ответственность за то, что код обработки действительно не изменяет данные документа в закрытом периоде, чтобы не нарушить логику работы даты запрета редактирования.

← На главную