Почему документ не формирует движения по регистру накопления в 1С?

Программист 1С v8.3 (Обычные формы) 1С:Розница Управленческий учет Торговля и дистрибуция
← На главную

При разработке новых документов в конфигурациях «1С:Предприятие 8» (например, в «Розница 1.0» или других решениях на обычных формах) программисты часто сталкиваются с ситуацией: программный код в процедуре ОбработкаПроведения написан верно, коллекция движений в отладчике заполняется, но после завершения транзакции в регистре накопления записи так и не появляются. Разберем детально, почему это происходит, как на это влияют свойства метаданных и какие методики проведения считаются актуальными.

Анализ программной установки флага записи

Рассмотрим ситуацию, с которой столкнулся автор темы. В одном документе («Заказ покупателя») движения записываются автоматически, а в другом («Снятие резерва») — нет, хотя код формирования набора записей идентичен. Решение, которое помогло автору, заключается в явной установке свойства Записывать для конкретного набора движений. Проанализируем пример кода:


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

Установка НаборДвижений.Записывать = Истина сообщает платформе, что по завершении процедуры проведения данный набор записей необходимо принудительно зафиксировать в базе данных. Но возникает резонный вопрос: почему в одном документе это работает без этой строки, а в другом — нет? Ответ кроется в настройках метаданных документа на вкладке «Движения».

Свойство «Запись движений при проведении»

В свойствах документа в дереве метаданных есть важный параметр — «Запись движений при проведении». Он может принимать два значения:

  1. Записывать модифицированные: Это старая методика. Платформа в ходе выполнения процедуры ОбработкаПроведения отслеживает, менялся ли набор записей (добавлялись ли строки, вызывался ли метод Загрузить). Если изменения были, платформа автоматически установит флаг записи в значение Истина и запишет данные в конце транзакции.
  2. Записывать выбранные: Это новая, более производительная методика. Платформа не отслеживает изменения в наборах записей. Программист обязан сам явно указать, какой набор нужно записать, установив Движения.ИмяРегистра.Записывать = Истина.

Выясним причину разного поведения документов: скорее всего, в «Заказе покупателя» по умолчанию стояло «Записывать модифицированные», а в новом документе «Снятие резерва» — «Записывать выбранные». Именно поэтому в первом случае движения появлялись «магическим» образом, а во втором требовали явной команды.

Различие методик проведения и производительность

Рассмотрим подробнее, почему разработчики фирмы «1С» рекомендуют использовать режим «Записывать выбранные». Это напрямую связано с оптимизацией работы базы данных и уменьшением количества блокировок.

При использовании старой методики («Записывать модифицированные») часто применяется свойство документа «Удаление движений» в режиме «Удалять автоматически». Это работает так: как только начинается проведение, платформа блокирует таблицы всех регистров, по которым документ может делать движения, и физически удаляет старые записи. Только после этого запускается ваш код. Если документ сложный, таблицы остаются заблокированными долгое время, что мешает другим пользователям.

Новая методика («Записывать выбранные») в сочетании с режимом «Не удалять автоматически» работает иначе:

Проанализируем преимущества новой методики: она позволяет избежать лишних операций DELETE в SQL, заменяя их более эффективным обновлением данных. Это существенно снижает риск возникновения Deadlocks (взаимных блокировок) при интенсивной работе пользователей.

Метод Записать() против флага Записывать = Истина

Важно различать момент физической записи данных. Выясним, что лучше использовать внутри ОбработкаПроведения.

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

Если же вы устанавливаете Движения.ЗаказыПокупателей.Записывать = Истина, физическая запись произойдет один раз в самом конце, после выполнения всего кода ОбработкаПроведения. Это рекомендуемый способ, так как он минимизирует время удержания транзакционных блокировок таблиц базы данных. Помните: чем меньше времени данные «записываются» в середине кода, тем стабильнее работает система.

Особенности работы в типовых конфигурациях (Розница, УПП)

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

Обычно это экспортные процедуры в модуле набора записей регистра, которые инкапсулируют логику заполнения колонок (Период, Регистратор, Активность). Внутри таких процедур разработчики часто забывают добавить установку флага Записывать = Истина. Поэтому, создавая новый документ «по образу и подобию» старого, всегда проверяйте не только код модулей, но и свойства объекта в дереве конфигурации.

Итоговые рекомендации

Чтобы избежать проблем с отсутствием движений, придерживайтесь следующего алгоритма при создании или изменении документов:

  1. Проверьте свойство «Запись движений при проведении» в метаданных документа. Если там стоит «Записывать выбранные», обязательно добавляйте Движения.ИмяРегистра.Записывать = Истина.
  2. Обратите внимание на свойство «Удаление движений». Для современных высоконагруженных систем рекомендуется режим «Не удалять автоматически» или «Удалять автоматически при отмене проведения».
  3. Не используйте метод Записать() без явной необходимости внутри транзакции проведения. Отдавайте предпочтение установке флага записи.
  4. Если вы используете типовые механизмы (как ВыполнитьПриход()), загляните внутрь этих процедур (F12), чтобы понять, управляют ли они флагом записи самостоятельно.

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

← На главную