При переносе данных с помощью конфигурации «Конвертация данных» (КД 2) нередко возникает необходимость скорректировать проводки регистра бухгалтерии по загруженному документу (например, документу ОперацияБух). Типичная задача — программно очистить или подменить определенные виды субконто для конкретных счетов учета.
Однако стандартный подход с созданием отдельного набора записей регистра в обработчиках загрузки часто приводит к тому, что изменения просто не сохраняются в базе данных. Разберем причину такого поведения и рассмотрим правильный способ модификации движений.
Проанализируем типичную ошибку при попытке изменить движения. Разработчик создает отдельный набор записей через менеджер регистра, считывает его, меняет строки и записывает:
НаборЗаписейРегистра = РегистрыБухгалтерии.Хозрасчетный.СоздатьНаборЗаписей();
НаборЗаписейРегистра.Отбор.Регистратор.Установить(Ссылка);
НаборЗаписейРегистра.Прочитать();
Для Каждого Стр Из НаборЗаписейРегистра Цикл
Если Стр.СчетДт = ПланыСчетов.Хозрасчетный.РасчетыСПерсоналомПоОплатеТруда Тогда
Стр.СубконтоДт.РаботникиОрганизации = Справочники.ФизическиеЛица.ПустаяСсылка();
ИначеЕсли Стр.СчетКт = ПланыСчетов.Хозрасчетный.РасчетыСПерсоналомПоОплатеТруда Тогда
Стр.СубконтоКт.РаботникиОрганизации = Справочники.ФизическиеЛица.ПустаяСсылка();
КонецЕсли;
КонецЦикла;
НаборЗаписейРегистра.Записать();
Выясним причину, по которой этот код не дает результата при загрузке через универсальную обработку обмена:
Объект, загруженного в оперативную память.Объект.Движения (в частности, Объект.Движения.Хозрасчетный).НаборЗаписейРегистра, он действительно сохраняется в базу данных. Однако сразу после выполнения пользовательского кода универсальная обработка вызывает метод Объект.Записать().Объект.Записать() платформа автоматически записывает все наборы из коллекции Объект.Движения, у которых выставлено свойство Записывать = Истина. В результате данные в информационной базе перезаписываются тем содержимым, которое хранилось в памяти объекта, и все наши ручные правки стираются.Чтобы избежать перезаписи, необходимо напрямую модифицировать строки регистра, находящиеся в коллекции Объект.Движения документа. Рассмотрим пошаговый алгоритм решения задачи.
В обработчике ПКО «После загрузки» (или «Перед записью объекта») выполним обход движений объекта:
Для Каждого Стр Из Объект.Движения.Хозрасчетный Цикл
Если Стр.СчетДт = ПланыСчетов.Хозрасчетный.РасчетыСПерсоналомПоОплатеТруда Тогда
Стр.СубконтоДт.РаботникиОрганизации = Справочники.ФизическиеЛица.ПустаяСсылка();
КонецЕсли;
Если Стр.СчетКт = ПланыСчетов.Хозрасчетный.РасчетыСПерсоналомПоОплатеТруда Тогда
Стр.СубконтоКт.РаботникиОрганизации = Справочники.ФизическиеЛица.ПустаяСсылка();
КонецЕсли;
КонецЦикла;
// Обязательно убедимся, что взведен флаг записи набора движений
Объект.Движения.Хозрасчетный.Записывать = Истина;
Разберем важные нюансы работы со свойствами субконто в проводках:
Стр.СубконтоДт.РаботникиОрганизации работает только тогда, когда имя предопределенного вида субконто строго совпадает с идентификатором и этот вид субконто привязан к плану счетов.
ВидСубконтоФизЛица = ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.РаботникиОрганизации;
Стр.СубконтоДт[ВидСубконтоФизЛица] = Справочники.ФизическиеЛица.ПустаяСсылка();
ПустаяСсылка() оставляет значение субконто пустым, но сама строка аналитики в проводке остается. Если требуется полностью удалить вид субконто из проводки, используем метод:
Стр.СубконтоДт.Удалить(ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.РаботникиОрганизации);
Рассмотрим другие подходы, которые можно применить в зависимости от архитектуры правил обмена:
Значение в обработчике «Перед выгрузкой».СоздатьНаборЗаписей(), необходимо принудительно отключить сохранение движений объектом, установив перед выходом из обработчика:
Объект.Движения.Хозрасчетный.Записывать = Ложь;
Однако такой способ является избыточным и не рекомендуется к использованию при наличии прямого доступа к Объект.Движения.