Как в 1С:УНФ определить, что Заказ покупателя проводится из документа Реализации?

Программист 1С v8.3 (Управляемые формы) 1С:Управление нашей фирмой Управленческий учет Торговля и дистрибуция
← На главную

В работе с 1С:УНФ часто встречается стандартная ситуация: проведение документа «Расходная накладная» (или «Реализация товаров и услуг») инициирует автоматическое перепроведение связанного с ним «Заказа покупателя». Это типовой механизм, предназначенный для корректного снятия товаров с резерва. Однако, что делать, если в модуле «Заказа покупателя», например, в процедуре ПриЗаписи, есть код, который должен выполняться только при интерактивных действиях пользователя, а не при системном перепроведении из другого документа?

Рассмотрим, как решить эту задачу и научить систему различать, откуда был запущен процесс записи или проведения заказа.

Решение: Передача флага через механизм «ДополнительныеСвойства»

Наиболее правильный и надежный способ передать информацию между объектами в рамках одной транзакции — это использовать свойство ДополнительныеСвойства. Это коллекция пар «Ключ и Значение», которая существует только во время жизни объекта в памяти и не сохраняется в базу данных. Она идеально подходит для нашей задачи.

Разберем реализацию по шагам.

  1. Модификация документа-инициатора («Реализация товаров и услуг»).
    Нам нужно «пометить» объект заказа перед тем, как его программно провести. Для этого в модуле объекта документа реализации, в процедуре ОбработкаПроведения, находим место, где получается и проводится заказ, и добавляем туда несколько строк.
  2. Посмотрим на пример:

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

    Что мы сделали? Перед тем как вызвать метод Записать() для объекта заказа, мы добавили в его временное хранилище ДополнительныеСвойства флаг с именем "ПроведениеИзРеализации". Теперь, пока этот объект существует в памяти, мы можем проверить наличие данного флага.

  3. Проверка флага в документе-приемнике («Заказ покупателя»).
    Теперь перейдем в модуль объекта документа «Заказ покупателя». Автор исходного вопроса уточнил, что код нужно пропустить в событии ПриЗаписи. Метод проверки будет одинаков как для ПриЗаписи, так и для ОбработкаПроведения.
  4. В нужной процедуре мы добавляем условие, которое проверяет существование нашего флага.

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

    Таким образом, если мы записываем заказ вручную, свойство "ПроведениеИзРеализации" не будет найдено, и код выполнится. Если же заказ перепроводится из реализации, условие сработает, и выполнение процедуры прервется до того, как дойдет до нежелательного блока кода.

Почему этот способ является предпочтительным?

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

Советы по отладке

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

  1. Поставьте точку останова в процедуре ПриЗаписи или ОбработкаПроведения в модуле объекта документа «Заказ покупателя».
  2. Запустите отладку и проведите документ «Расходная накладная».
  3. Когда выполнение остановится на точке останова, откройте панель «Стек вызовов». В ней вы увидите всю цепочку процедур, которая привела к выполнению текущего кода. Наверху стека будет ЗаказПокупателя.ПриЗаписи(), а ниже вы сможете найти вызов из процедуры РасходнаяНакладная.ОбработкаПроведения().

Этот анализ поможет вам точно убедиться в правильности ваших предположений о взаимодействии объектов и подтвердит, что предложенное решение с ДополнительныеСвойства подходит для вашей задачи.

← На главную