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