Вводная: конфигурация УПП 1.3.153.1 с доработками.
Имеется типовой документ «Требование накладная" с типовыми же настройками УПП:
- Удаление движений: Не удалять автоматически.
- Запись движений при проведении: Записывать модифицированные.
Визуальное описание проблемы:
При первичном проведении документа движения по нетиповому (добавленному) регистру накопления выполняются успешно и корректно. При повторном проведении документа движения исчезают «загадочным образом». При последующем перепроведении документа движения опять появляются и т.д. То есть, то нет…
Доработок, связанных «непосредственно» с механизмом проведения в целом и конкретно по данному регистру накопления выполнено не было.
Анализ проблемы:
Анализ механизма проведения по добавленному регистру накопления показал, что разработчик данного механизма по уже неизвестным причинам решил выполнять движения НЕ обращаясь к коллекции движений документа, что было бы правильно, а выполняя запись движений посредством набора записей регистра накопления:
…
Однако же точно известно, что до недавнего времени перепроведение документа НЕ приводило к стиранию движений по этому регистру накопления.
Дальнейший анализ показал, что в модуль объекта документа в процедуру «ПередЗаписью()» недавно был добавлен код:
Именно строка чтения набора записей нашего регистра накопления из коллекции движений привела к возникновению данной ситуации, т.к. комментирование ее привело к исчезновению исходной проблемы.
Несмотря на то, что очевидно неправильное выполнение движений, написанное одним из разработчиков, очень хотелось разобраться с тем, почему одна, казалось бы, безобидная строчка кода, привела к таким «катастрофическим» последствиям, как затирание движений. Поиск информации в интернете не дал каких-либо ответов на поставленный вопрос, поэтому и было принято решение оформить небольшую статью – может кому поможет не совершать подобных ошибок.
В Обработчике «ОбработкаПроведения()» имеется типовой вызов процедуры «ОбщегоНазначения.УдалитьДвиженияРегистратора(), который очищает все движения регистратора:
Процедура «ОчисткаКоллекцийДвиженийДокумента()» общего модуля «ОбщегоНазначения» очищает те коллекции движения, в которых количество больше 0:
При проведении непроведенного документа очистка движений не происходит, т.к. набор записей нашего регистра накопления пуст.
Как результат мы видим, что вернувшись в обработку проведения модифицированность набора записей нашего регистра накопления осталась в значении «Ложь». Это значит, что движения выполнены НЕ будут типовым образом. Но мы уже выяснили, что разработчик внесет изменения в данные регистра накопления позже, используя метод «СоздатьНаборЗаписей()».
Теперь же перепроведем документ.
Перед выходом из процедуры «ПередЗаписью()» модифицированность набора записей стоит «Ложь»:
Теперь в процедуре ОчисткаКоллекцийДвиженийДокумента()» наш набор записей содержит количество больше 0 и очищается:
Абсолютно логично, что теперь модифицированность нашего набора записей взведена в положение «Истина»:
После этого мы до окончания транзакции проведения зайдем в отдельную процедуру, выполняющую движения по нашему регистру накопления «вручную», а не посредством набора движений, и произведем эти самые движения. Однако набор записей, содержащийся в объекте документа НЕ станет заполнен (мы его сами только что очистили на предыдущем скриншоте):
Результат теперь очевиден – мы запишем пустые движения, т.к. согласно настройкам должны записывать модифицированные наборы. А наши «ручные» усилия пропадут, т.к. будут стерты пустым набором записей…
После анализа всё становится логично и понятно, кроме одного момента – почему, если убрать конструкцию «Набор.Прочитать()» в процедуре «ПередЗаписью()», то проблема «исчезновения движений» отсутствует??
Ответ оказался следующим:
Если мы не читаем набор записей принудительно подобной конструкцией, то все движения в объекте документа у нас пустые:
Абсолютно все. Получается, что в отсутствие принудительного чтения мы как будто бы «первый раз проводим» наш девственно чистый документ. Действия по очистке движений в процедуре «Обработка проведения» в данном случае не выполняются, т.к. наборы не прочитаны (они пустые) и модифицированность не взводится. Движения заполнятся и модифицированность взведется дальше в логике ОбработкиПроведения.
Выводы:
- Движения в подчиненные регистраторам регистры нужно выполнять через движения объекта документа, а не «вручную».
- Мистики не бывает – на все есть причина – главное ее найти.
P.S.
Возможно, для большинства написанное покажется «детским садом», поэтому заранее прошу их реагировать поспокойнее. При написании данной статьи хотелось в первую очередь для себя уложить в голове причину «загадочного поведения» документа. Надеюсь, что кому-то это будет полезно.