Каталог решений - Порядок записи движений регистров при проведении документа

Порядок записи движений регистров при проведении документа

Порядок записи движений регистров при проведении документа

В наличии

Когда-то была программа 1С седьмой версии, и все программисты знали: если нужно проанализировать и/или исправить движения документа — смотри модуль документа, процедура ОбработкаПроведения(). В 1С 8 все гораздо сложнее. Кроме модуля проведения есть еще подписки на события, а также движения документа может "создавать" не сам документ. Эта статья о том, как происходит проведение и в какой момент записываются движения документа по регистрам.

Категория:

Описание

Алгоритм проведения документа с учетом подписок на события 

Настройки документа:

Если посмотреть свойства документа через палитру свойств, то можно увидеть два важных свойства: «Удаление движений» и «Запись движений при проведении», причем второе НЕ вынесено на закладку «Движения» окна редактирования документа.

 

 

 

1. Удаление движений.

Если свойство «Удаление движений» уставновлено в «Удалять автоматически», то ПЕРЕД началом проведения программа очищает все движения по регистрам. Фактически это означает запись пустого набора записей регистра с видом записи — замещение. А значит, программа выполняет код из процедур «ПередЗаписью» и «ПриЗаписи» модуля набора записей регистров.

Если для какого-либо регистра определена подписка на событие «При записи», то выполняется код из связанной процедуры.

 

2. Процедура «ОбработкаПроведения» модуля документа.

Обратим внимание: в начале обработки проведения у всех движений флаг модифицированности Ложь (значение возвращает метод Движения.Регистр.Модифицированность()).

При работе с набором записей регистра (например, Движения.Регистр.Очистить(), Движения.Регистр.Добавить() и т.д.) флаг модифицированности становится Истина.

После записи движения в базу Движения.Регистр.Записать() модифицированность снова ложь.

Если в модуле процедуры подписки происходит запись набора регистра в явном виде (.Записать()), то программа выполняет код из процедур «ПередЗаписью» и «ПриЗаписи» модуля набора записей регистров и процедуры из подписки на событие «При записи» регистра.

 

3. Подписки на событие «При проведении» документа

Важно понимать: если в обработке проведения документа или в подписках на событие, вызванных ранее, не происходила запись движений регистров в явном виде (Движения.Регистр.Записать()), то движения документа еще НЕ записаны в базу. Поэтому их нельзя получить с помощью запроса, но можно получить из коллекции движений источника.

Процедура ПриПроведенииДокумента(Источник, Отказ, РежимПроведения) Экспорт
          Регистр = Источник.Движения.Бухучет;
.....
КонецПроцедуры

Очередность подписок на одно и то же событие явным образом не определяется 1С, но на практике подписки вызываются в порядке следования в ветке «Подписки на события» окна редактирования конфигурации.

Если регистры записываются с помощь метода Записать(), то выполняются все связанные процедуры.

 

4. Запись движений.

 

Вспомним про свойство «Запись движений при проведении» из настроек документа.

Если оно равно «Записывать модифицированные», то в базу будут записаны все движения документа, у которых флаг «Модифицированность» Истина.

Если оно равно «Записывать выбранные», то в базу будут записаны движения регистров, для которых мы явным образом указали необходимость записи.

Движения.Регистр.Записывать = Истина;

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

 И в конце рассмотрим несколько примеров: 

Пусть свойство документа «Запись движений при проведении» равно «Записывать модифицированные», а «Удаление движений» — «Не удалять автоматически».

 

Пример 1.

Процедура ОбработкаПроведения(Отказ, РежимПроведения)
         НовЗапись = Движения.Регистр.Добавить();
....
         Движения.Регистр.Записать(Ложь); //***
КонецПроцедуры

При такой процедуре проведения документ при каждом перепроведении будет добавлять запись в регистр, записи будут множиться. Т.к. строка //*** добавляет записи в регистр, признак Модифицированности снимается.

Правильнее будет написать строку //*** как

Движения.Регистр.Записать()

или вообще ее опустить, и тогда программа сама запишет модифицированные движения.

 

Пример 2.

В 1С 8 движения документа могут формироваться не только в обработке проведения, но и извне, например, из некоторой служебной обработки (так реализовано допроведение документов, восстановление авансов и т.д.).

Приход = Документы.ПриходнаяНакладная.Выбрать();
Проводки = РегистрыБухгалтерии.Регистр.СоздатьНаборЗаписей();
Пока Приход.Следующий() Цикл
        ДокСсылка = Приход.Ссылка;
        Проводки.Отбор.Регистратор.Установить(ДокСсылка); 
        НоваяПроводка = Проводки.Добавить();
        НоваяПроводка.Период = ДокСсылка.Дата; 
        НоваяПроводка.Организация = ДокСсылка.Организация;
        НоваяПроводка.СчетДт = ПланыСчетов.ПланСчетов.Товары;
        НоваяПроводка.СчетКт = ПланыСчетов.ПланСчетов.Поставщики;
        НоваяПроводка.Сумма = ДокСсылка.Всего;
        Проводки.Записать(Ложь); 
КонецЦикла;

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


Пример 3.

Перед началом проведения документа все реквизиты документа записываются в базу данных (т.е. программист может их получить с помощью запроса). Во внутренней памяти создается Объект документа, и у этого объекта есть коллекция движений, которая будет записана после окончания процедуры проведения (см. этап 4).

Если в процессе проведения документа движения по регистрам формируются не с помощью коллекции Движения, принадлежащей внутреннему объекту, а другими способами (вручную в форме набора записей или как в примере 2 и т.д.), то на этапе 4 эти записи будут замещены!!! Чтобы избежать замещения в типовых базах, для документа «ОперацияБух» свойство документа «Проведение» устанавливается в «Запретить».

Если документ должен проводиться по другим регистрам и нельзя запретить проведение, тогда нужно внимательно настраивать свойства документа:          

     — выбрать вариант записи движений «Записывать выбранные» и убедиться, что Движения.Регистр.Записывать = Ложь

     — выбрать вариант записи движений «Записывать модифицированные» и контролировать признак Модифицированности для набора записей этого регистра.

Пример 4.

Нужно понимать, что объект, полученный по ссылке (назовем его «ОбъектДок»), и внутренний объект («ЭтотОбъект»), созданный в памяти в момент проведения, это два разных экземляра объектов.

ОбъектДок = ДокСсылка.ПолучитьОбъект();
ДвиженияДок = ОбъектДок.Движения;
НовДвижение = ДвиженияДок.Регистр.Добавить();
....
ДвиженияДок.Регистр.Записать();

Соответственно и коллекции движений у них будут разные. У «ОбъектаДок» коллекция движений будет включать только записанный в базу набор записей регистра, а у «ЭтогоОбъекта» — как записанные, так и добавленные и незаписанные записи. По окончании проведения (этап 4)  в базу будут записаны наборы записей «ЭтогоОбъекта», причем с признаком Замещать = Истина.

Если записи в набор записей добавляются по способу, описанному выше, то они могут быть замещены на этапе 4.

has been added to your cart:
Оформление заказа