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

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

В практике разработки на платформе 1С:Предприятие 8.3 часто возникает задача: необходимо предотвратить случайную отмену проведения документа, если на его основании созданы другие документы. Сложность заключается в том, что сама проверка (поиск связей) должна выполняться на сервере, а интерактивный вопрос пользователю («У данного документа есть связанные записи. Вы уверены, что хотите отменить проведение?») можно задать только на клиенте. Рассмотрим подробнее, как реализовать этот механизм в формах документов и списках.

Реализация проверки в форме документа

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

В обработчике ПередЗаписью на клиенте нам доступен параметр ПараметрыЗаписи. Именно в нем платформа передает информацию о том, какое именно действие инициировал пользователь. Если ПараметрыЗаписи.РежимЗаписи равен РежимЗаписиДокумента.ОтменаПроведения, значит, пора запускать нашу проверку.

Рассмотрим пример кода для формы документа, который можно быстро подготовить, используя консоль кода с ИИ-помощником:


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

КонецПроцедуры

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


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

Перехват действий в динамическом списке

Ситуация усложняется, когда пользователь пытается отменить проведение или пометить документ на удаление прямо из списка документов (например, нажав клавишу Del). В этом случае событие формы документа не срабатывает. Выясним, как бороться с этой проблемой, применяя различные методы доработки динамических списков.

У элемента формы Таблица, отображающей динамический список, есть специфические события. Рассмотрим два эффективных пути:

  1. Событие «ПередУстановкойПометкиУдаления». Это событие расширения таблицы для динамического списка. Оно срабатывает при попытке изменения пометки удаления (клавиша Del или команда меню). Здесь также можно вызвать серверную проверку, установить Отказ = Истина и вывести ПоказатьВопрос.
  2. Подмена стандартных команд. Это самый надежный способ. Мы можем отключить видимость стандартных кнопок командной панели («Установить пометку удаления», «Отменить проведение») и создать свои собственные команды с теми же именами и горячими клавишами. В коде этих команд мы полностью контролируем логику: сначала ищем связи, потом спрашиваем пользователя, и только потом вызываем метод УстановитьПометкуУдаления() или Записать() для объекта.

Как эффективно искать связанные документы?

Для реализации серверной части проверки (функция ИмеютсяСвязанныеДокументыНаСервере) не стоит писать тяжелые запросы ко всем таблицам базы данных. Проанализируем использование метаданных. В 1С существует объект КритерииОтбора. Обычно в типовых и многих самописных конфигурациях уже есть критерий СвязанныеДокументы.

Посмотрим на пример эффективного поиска:


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

Важные нюансы при работе с цепочками документов

Разберем ситуацию, упомянутую опытными разработчиками: если менеджер отменяет «Заказ клиента», за которым тянется цепочка из «Перемещения», «Ордеров» и «Реализаций», простая отмена проведения одного документа может привести к нарушению логики учета.

Рекомендации по реализации:

Таким образом, комбинируя перехват событий в форме (ПередЗаписью) и в списке (ПередУстановкойПометкиУдаления), а также используя асинхронные вызовы и критерии отбора, мы создаем надежный механизм защиты целостности данных, который предупреждает пользователя о последствиях его действий.

← На главную