Как реализовать подтверждение при копировании документа в управляемых формах 1С?

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

В процессе работы с документами в системе 1С пользователи часто сталкиваются с проблемой случайного нажатия кнопки «Скопировать» (или клавиши F9). Это приводит к созданию дублей документов или появлению в базе данных некорректных записей, заполненных на основе старых данных. В управляемых формах (УФ) реализация простого вопроса-подтверждения требует понимания асинхронности и особенностей жизненного цикла формы. В этой статье мы подробно разберем, как защитить систему от неосознанных действий пользователей.

Метод 1. Организационное решение через интерфейс

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

Разберем, как переместить команду в меню «Ещё» или вовсе отключить стандартное копирование:

  1. Откроем конфигуратор и перейдем в форму списка документа.
  2. В дереве элементов формы найдем командную панель (обычно это Автоматическая командная панель).
  3. Снимем флаг Автозаполнение, если мы хотим полностью контролировать состав кнопок.
  4. Если автозаполнение остается, мы можем программно или в свойствах команд найти стандартную команду Скопировать и изменить ее отображение на В командной панели и в меню Еще на Только в меню Еще.

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

Метод 2. Программный перехват в форме документа

Если бизнес-процесс требует именно подтверждения через диалоговое окно, нам необходимо вмешаться в логику открытия формы. Основная сложность заключается в том, что в управляемом приложении мы не можем просто вызвать функцию Вопрос() в процедуре ПриОткрытии, так как современные конфигурации работают в режиме синхронных вызовов, которые запрещены (или не рекомендуются).

Проанализируем алгоритм работы:

Шаг 1. Определение факта копирования на сервере.

В модуле формы документа используем обработчик ПриСозданииНаСервере. Нам нужно понять, что документ создается именно копированием. Для этого в параметрах формы существует специальное поле ЗначениеКопирования.


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    // Проверяем, заполнено ли значение копирования. 
    // Если там ссылка — значит, идет процесс создания копии.
    Если Параметры.Ключ.Пустая() И НЕ Параметры.ЗначениеКопирования.Пустая() Тогда
        // Устанавливаем флаг в переменной формы, чтобы обратиться к нему на клиенте
        Объект.ДополнительныеСвойства.Вставить("ЭтоКопирование", Истина);
        // Или используем реквизит формы (например, флаг Булево)
        ЭтоНоваяКопия = Истина; 
    КонецЕсли;
    
КонецПроцедуры

Шаг 2. Вызов диалога на клиенте.

Теперь рассмотрим процедуру ПриОткрытии. Здесь мы должны прервать стандартное открытие формы, если это копия, задать вопрос и, в случае согласия, продолжить работу.


&НаКлиенте
Процедура ПриОткрытии(Отказ)
    
    // Если это не копия или пользователь уже ответил "Да", выходим
    Если НЕ ЭтоНоваяКопия Или ПодтверждениеПолучено Тогда
        Возврат;
    КонецЕсли;
    
    // Отменяем текущее открытие
    Отказ = Истина;
    
    // Настраиваем оповещение для обработки ответа пользователя
    ОписаниеОповещения = Новый ОписаниеОповещения("ПослеВопросаОКопировании", ЭтотОбъект);
    ПоказатьВопрос(ОписаниеОповещения, "Вы действительно хотите создать копию документа?", РежимДиалогаВопрос.ДаНет);
    
КонецПроцедуры

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

Метод 3. Очистка критических данных при копировании

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

Выясним, как реализовать это в модуле объекта через процедуру ОбработкаЗаполнения:


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

Метод 4. Подмена стандартной команды в форме списка

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

  1. В форме списка документа создадим новую команду, назовем ее КомандаСкопироватьСПодтверждением.
  2. Назначим ей горячую клавишу F9.
  3. В свойствах стандартной команды списка снимем видимость.
  4. Напишем обработчик для нашей команды:

&НаКлиенте
Процедура КомандаСкопироватьСПодтверждением(Команда)
    
    ТекущиеДанные = Элементы.Список.ТекущиеДанные;
    Если ТекущиеДанные = Неопределено Тогда
        Возврат;
    КонецЕсли;
    
    ОписаниеОповещения = Новый ОписаниеОповещения("ПодтверждениеКопированияЗавершение", ЭтотОбъект, ТекущиеДанные.Ссылка);
    ПоказатьВопрос(ОписаниеОповещения, "Копировать выбранный документ?", РежимДиалогаВопрос.ДаНет);
    
КонецПроцедуры

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

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

Проанализировав все способы, можно сделать следующие выводы:

Помните, что избыточные вопросы могут раздражать опытных пользователей, поэтому старайтесь соблюдать баланс между безопасностью данных и удобством интерфейса. Использование ОписаниеОповещения является обязательным стандартом для современной разработки на платформе 1С:Предприятие 8.3, обеспечивающим работу кода в веб-клиенте и мобильных приложениях.

← На главную