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

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

При разработке или доработке конфигураций на платформе 1С:Предприятие часто возникает задача изменить стандартное поведение системы. Одной из распространенных ситуаций является необходимость вмешаться в процесс создания документа методом копирования. Например, нам нужно очистить поле "Ответственный", сбросить "Статус" или заполнить определенный реквизит по особому алгоритму именно в тот момент, когда пользователь нажимает кнопку "Скопировать" в форме списка. Чтобы эффективно выявлять причины нестандартного поведения системы на этом этапе, полезно проводить анализ конфигураций и расширений на наличие ошибок.

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

Почему отладчик не показывает процедуру копирования?

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

Причина кроется в архитектуре платформы 1С. Стандартная команда "Скопировать" в командной панели формы списка (или формы документа) инициирует процесс, который выполняется на уровне ядра платформы (написанного на C++). Платформа самостоятельно:

  1. Создает в оперативной памяти новый объект типа ДокументОбъект.
  2. Считывает данные из документа-источника.
  3. Переносит значения всех реквизитов, совпадающих по имени и типу, в новый объект.
  4. Копирует табличные части.
  5. Открывает форму нового документа.

Поскольку этот код "зашит" в платформу, отладчик встроенного языка 1С его не видит. Мы можем перехватить управление только в том случае, если разработчик конфигурации (или мы сами) явно объявили специальные события-обработчики в модулях.

Решение 1: Использование события модуля объекта "ПриКопировании"

Самый правильный и методически верный способ изменить данные объекта при его копировании — использовать предопределенное событие модуля объекта ПриКопировании.

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

Как это сделать:

  1. Откройте модуль объекта нужного документа в Конфигураторе.
  2. В меню текстового редактора найдите список процедур и функций (обычно иконка с синей лупой или через меню "Текст").
  3. Найдите событие ПриКопировании и добавьте его.

Рассмотрим, как работает этот обработчик. В него передается параметр ОбъектКопирования — это ссылка на исходный документ, из которого мы делаем копию. В этот момент ЭтотОбъект уже содержит скопированные данные, но еще не записан в базу данных.

Пример кода в модуле объекта:


Процедура ПриКопировании(ОбъектКопирования)
    // ОбъектКопирования - это ссылка на документ-источник.
    // ЭтотОбъект - это уже созданная копия с заполненными полями.
    
    // Очищаем реквизиты, которые не должны переноситься
    ЭтотОбъект.Ответственный = Пользователи.ТекущийПользователь();
    ЭтотОбъект.Дата = ТекущаяДата();
    ЭтотОбъект.Проведен = Ложь; // Хотя при копировании пометка проведения и так сбрасывается
    
    // Реализуем условие автора: заполнение поля по условию
    Если ОбъектКопирования.СуммаДокумента > 10000 Тогда
        ЭтотОбъект.Комментарий = "Копия крупного заказа";
    Иначе
        ЭтотОбъект.Комментарий = "";
    КонецЕсли;
    
КонецПроцедуры

Важно отметить, что событие ПриКопировании доступно на сервере, в толстом клиенте и внешнем соединении. Это идеальное место для бизнес-логики, связанной с данными самого объекта.

Решение 2: Использование расширений конфигурации

В современных реалиях снимать конфигурацию с поддержки только ради добавления одной процедуры — плохая практика. Если вы работаете с типовой конфигурацией (ERP, Бухгалтерия, УТ), лучше использовать механизм расширений. Существуют разные способы добавления реквизитов и элементов на управляемые формы через расширения, которые позволяют сохранить типовую конфигурацию на поддержке.

Алгоритм действий:

  1. Создайте расширение конфигурации.
  2. Добавьте в расширение нужный документ.
  3. Откройте модуль объекта этого документа в расширении.
  4. Создайте обработчик ПриКопировании. Платформа предложит выбрать тип аннотации (Перед, После, Вместо).

Рекомендуется использовать аннотацию &После, чтобы ваш код выполнился после отработки стандартной логики (если она есть в основной конфигурации).


&После("ПриКопировании")
Процедура Расш1_ПриКопировании(ОбъектКопирования)
    // Ваша логика заполнения
    ЭтотОбъект.ДополнительныйРеквизит = "Значение по умолчанию";
КонецПроцедуры

Решение 3: Проверка на уровне формы (ПриСозданииНаСервере)

Иногда возникают ситуации, когда логику нужно реализовать не в модуле объекта, а непосредственно в форме. Например, если нам нужно изменить не данные объекта, а поведение интерфейса (скрыть элементы, изменить заголовок формы). Для реализации такой логики может пригодиться общий модуль для программного изменения форм или специализированный конструктор управляемых форм.

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

Обратим внимание на параметр Параметры.ЗначениеКопирования. Если форма открывается для нового документа, созданного копированием, этот параметр будет содержать ссылку на исходный документ. Если документ создается "с нуля", этот параметр будет Неопределено.

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


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

Также косвенным признаком копирования (или создания нового) является пустое значение ключа. У нового, еще не записанного объекта Параметры.Ключ будет пустым.

Частая ошибка: путаница с "ОбработкаЗаполнения"

В обсуждении темы часто всплывает совет использовать событие ОбработкаЗаполнения. Давайте разберем, почему это не совсем верно для кнопки "Скопировать".

Процедура ОбработкаЗаполнения предназначена в первую очередь для механизма "Ввод на основании". Она вызывается, когда мы программно выполняем метод Заполнить() или когда пользователь выбирает команду "Создать на основании".

Хотя технически в некоторых сценариях ОбработкаЗаполнения может отрабатывать, полагаться на нее при стандартном копировании нельзя. Приоритетным и специализированным событием для действия "Скопировать" является именно ПриКопировании.

Итоги и рекомендации

Подводя итог нашей проблемы с "неуловимой" кнопкой копирования:

  1. Не ищите код в отладчике, если его не писали. Стандартное копирование скрыто внутри платформы.
  2. Используйте событие ПриКопировании в модуле объекта для изменения данных (очистка, заполнение по умолчанию). Это самый надежный метод.
  3. Используйте расширения с аннотацией &После, чтобы не снимать конфигурацию с поддержки.
  4. Используйте ПриСозданииНаСервере и проверку Параметры.ЗначениеКопирования, если ваша задача касается поведения формы или UI.

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

← На главную