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