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