Как в 1С определить, что документ был создан путем копирования?

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

В практике разработки на платформе 1С:Предприятие 8 часто возникает задача определить, является ли создаваемый документ новым (пустым) или он был создан путем копирования существующего объекта. Это необходимо для очистки специфических реквизитов (например, серийных номеров, статусов, дат), проверки прав доступа или предотвращения ошибок при заполнении данных пользователями. Рассмотрим подробно все доступные механизмы решения этой задачи.

Метод 1. Анализ параметров формы в процедуре ПриСозданииНаСервере

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

Проанализируем программный код, который следует разместить в модуле формы документа:


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

Важный нюанс: Обратите внимание, что обращение к Параметры.ЗначениеКопирования напрямую может привести к ошибке «Поле объекта не обнаружено», если форма открывается в обычном режиме создания. Поэтому всегда используйте метод Свойство() для безопасного чтения.

Метод 2. Использование события модуля объекта ПриКопировании

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

Разберем пример реализации в модуле объекта:


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

Этот метод считается более «фундаментальным», так как он гарантирует выполнение кода даже при программном вызове метода Скопировать().

Метод 3. Обработка заполнения (самый ранний этап)

Проанализируем еще одну системную процедуру — ОбработкаЗаполнения. Она вызывается первой при создании любого объекта. Если документ копируется, в параметр ДанныеЗаполнения передается ссылка на исходный объект.


Процедура ОбработкаЗаполнения(ДанныеЗаполнения, ТекстЗаполнения, СтандартнаяОбработка)
    
    Если ТипЗнч(ДанныеЗаполнения) = Тип("ДокументСсылка.РеализацияТоваровУслуг") Тогда
        // Проверяем, не является ли это вводом на основании (через проверку параметра ТекстЗаполнения)
        // Если ТекстЗаполнения пустой, скорее всего, это копирование.
        // Однако метод ПриКопировании для этих целей подходит лучше.
    КонецЕсли;
    
КонецПроцедуры

Метод 4. Работа через расширения конфигурации

Если вы работаете в расширении и вам нужно изменить поведение типовой конфигурации, используйте аннотацию &После для процедуры ПриСозданииНаСервере. В некоторых релизах платформы или в зависимости от логики конкретной конфигурации (например, КА или ERP), параметры могут передаваться в структуру ПараметрыСоздания.


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

Как доказать факт копирования, если документ уже записан?

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

  1. Журнал регистрации: Проанализируем записи за период создания документа. Хотя записи «Создан копированием» там нет, можно увидеть последовательность событий: открытие списка, за которым мгновенно следует открытие формы нового документа и его запись.
  2. Версионирование объектов: Если в базе включена подсистема БСП «Версионирование объектов», сравним первую версию подозрительного документа с документом, который мог служить образцом. Если в табличных частях совпадают уникальные идентификаторы строк (GUID), которые обычно генерируются заново при ручном вводе, — это прямое доказательство копирования.
  3. Анализ ГУИД (UUID) строк: При стандартном копировании через F9 идентификаторы строк табличных частей часто переносятся «как есть». Проверка совпадения GUID строк в двух разных документах одного автора — весомый аргумент.

Различия между «Копированием» и «Вводом на основании»

Важно не путать эти два механизма. Для их разделения в ПриСозданииНаСервере проверяются разные параметры:

Особенности работы на клиенте

Выясним, можно ли определить факт копирования в процедуре ПриОткрытии на клиенте. Напрямую параметр ЗначениеКопирования в ЭтаФорма.Параметры на клиенте может быть недоступен (зависит от версии платформы и настроек формы).

Рекомендация: Если вам нужен этот признак на клиенте, создайте Реквизит формы (тип Булево, например, ЭтоКопия) и заполните его в ПриСозданииНаСервере. После этого вы сможете обращаться к нему в любом месте клиентского кода.

Подводя итог, можно сказать: для оперативного вмешательства в процесс создания используйте ЗначениеКопирования в форме, а для обеспечения целостности данных на уровне базы — процедуру ПриКопировании в модуле объекта. Для практического исследования последовательности вызова событий платформы пригодится инструмент для отслеживания событий 1С.

← На главную