Разработка и Конфигурация · 12 мин
Регистр накопления 1С: как правильно записывать движения
Как записывать данные в регистр накопления 1С: проведение документа, Движения.Записать(), ручные записи, виды движения Приход и Расход, типичные ошибки.
Регистр накопления в 1С — это объект, который хранит числовые показатели (остатки товаров, суммы взаиморасчётов, объёмы продаж) с привязкой к измерениям и ко времени. Записи в регистр почти всегда создаются не напрямую, а через документы-регистраторы: при проведении документ формирует набор движений, и платформа сохраняет его в таблицу регистра. Понимание того, как именно формируются и записываются эти движения, — базовый навык для разработчика и внедренца 1С.
Ошибки при записи в регистр накопления приводят к расхождению остатков, «минусам» на складе и неверным отчётам. Причины обычно одни и те же: неверно выбран вид движения, набор записей записан без замещения, движения сформированы после проверки остатков либо документ проведён, но регистр не указан в списке движений. Ниже разобраны рабочие способы записи, типовой код и контрольные точки для проверки результата.
Что такое регистр накопления и как устроены его записи
Регистр накопления состоит из измерений (разрезы учёта: склад, номенклатура, контрагент), ресурсов (числовые показатели: количество, сумма) и реквизитов (дополнительная информация строки). Каждая запись обязательно содержит период, регистратора и вид движения — для остаточных регистров это Приход или Расход.
Платформа различает два вида регистров накопления. Остаточные хранят приходы и расходы, а итоговый остаток вычисляется по измерениям — например, регистр «ТоварыНаСкладах». Оборотные не имеют видов движения и хранят только накапливаемые суммы за период — например, «Продажи». Вид регистра задаётся в конфигураторе и влияет на то, как вы пишете код: у оборотного регистра свойство ВидДвижения отсутствует.
Физически запись в регистр всегда принадлежит регистратору — документу, который её создал. Удаление или отмена проведения документа автоматически удаляет его движения. Поэтому «журнал» изменений остатков всегда можно восстановить через список движений документа.
Основной способ: запись движений при проведении документа
Стандартный сценарий — заполнение движений в обработчике ОбработкаПроведения модуля документа. В модуле доступна коллекция Движения, содержащая наборы записей всех регистров, по которым документ проводится. Каждая строка табличной части превращается в одну или несколько записей регистра.
Процедура ОбработкаПроведения(Отказ, РежимПроведения)
Движения.ТоварыНаСкладах.Записывать = Истина;
Для Каждого СтрокаТовара Из Товары Цикл
Движение = Движения.ТоварыНаСкладах.Добавить();
Движение.ВидДвижения = ВидДвиженияНакопления.Приход;
Движение.Период = Дата;
Движение.Склад = Склад;
Движение.Номенклатура = СтрокаТовара.Номенклатура;
Движение.Количество = СтрокаТовара.Количество;
КонецЦикла;
КонецПроцедуры
Строка Движения.ТоварыНаСкладах.Записывать = Истина; указывает платформе, что набор нужно сохранить в базу при завершении проведения. Если её опустить, платформа запишет набор автоматически, только если в него были добавлены записи, — но явная установка флага считается хорошей практикой и обязательна, когда набор может остаться пустым, а старые движения нужно стереть.
Проверьте, что документ включён в список регистраторов: в конфигураторе у регистра накопления на закладке «Регистраторы» должна стоять отметка напротив вашего документа, а в свойствах документа на закладке «Движения» — отметка напротив регистра. Без этого коллекция Движения не будет содержать нужного набора.
- 1В конфигураторе отметьте регистр в свойствах документа на закладке «Движения»
- 2Откройте модуль документа и создайте обработчик ОбработкаПроведения
- 3Установите Движения.<ИмяРегистра>.Записывать = Истина
- 4В цикле по табличной части добавьте записи методом Добавить() и заполните вид движения, период, измерения и ресурсы
- 5Проведите документ и откройте его движения по регистру для проверки
Как выбрать вид движения: Приход или Расход
Вид движения определяет, увеличивает запись остаток или уменьшает. Приход используют документы поступления: приходная накладная, оприходование, поступление оплаты. Расход — документы списания: расходная накладная, реализация, списание. Один документ может делать движения обоих видов по разным регистрам и даже по одному регистру (например, перемещение между складами — это Расход по складу-отправителю и Приход по складу-получателю).
Типичная ошибка — перепутать вид движения в документе корректировки или возврата. Возврат товара от покупателя должен делать Приход на склад, а не Расход с отрицательным количеством. Отрицательное количество в записи Прихода формально возможно, но ломает оборотные отчёты и контроль остатков: отчёт покажет завышенные приход и расход вместо честного уменьшения.
Приход и Расход: когда что использовать
Поступление товара, денег, задолженности нам. Увеличивает остаток. Не используйте отрицательное количество вместо Расхода.
Отгрузка, списание, оплата поставщику. Уменьшает остаток. Перед записью Расхода обычно выполняют контроль остатков.
Допустимо в оборотных регистрах для корректировок. В остаточных регистрах применяйте осторожно — возможны отрицательные промежуточные остатки.
Контроль остатков перед записью расхода
При записи расходных движений стандартная задача — не допустить отгрузку больше, чем есть на складе. Для этого до формирования движений выполняется запрос к виртуальной таблице остатков регистра с отбором по измерениям документа. Если остатка не хватает, устанавливается параметр Отказ = Истина, и проведение отменяется целиком вместе со всеми движениями.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ТоварыНаСкладахОстатки.Номенклатура,
| ТоварыНаСкладахОстатки.КоличествоОстаток
|ИЗ
| РегистрНакопления.ТоварыНаСкладах.Остатки(
| &МоментВремени, Склад = &Склад) КАК ТоварыНаСкладахОстатки";
Запрос.УстановитьПараметр("МоментВремени", МоментВремени());
Запрос.УстановитьПараметр("Склад", Склад);
Важно получать остатки на момент времени документа, а не на текущую дату: иначе документ, проводимый задним числом, будет контролироваться по неверным данным. Учитывайте и режим проведения — при оперативном проведении платформа сама следит за актуальностью итогов, при неоперативном ответственность за корректность момента лежит на разработчике.
Ручная запись через набор записей
Вне документа записи создают объектом НаборЗаписей. Сценарии применения: загрузка начальных остатков, служебная обработка переноса данных, исправление движений существующего документа без перепроведения. Набор всегда привязан к отбору по регистратору — записать «просто строки в регистр» без регистратора нельзя.
Набор = РегистрыНакопления.ТоварыНаСкладах.СоздатьНаборЗаписей();
Набор.Отбор.Регистратор.Установить(ДокументСсылка);
Запись = Набор.Добавить();
Запись.ВидДвижения = ВидДвиженияНакопления.Приход;
Запись.Период = ТекущаяДатаСеанса();
Запись.Регистратор = ДокументСсылка;
Запись.Склад = Склад;
Запись.Номенклатура = Номенклатура;
Запись.Количество = 10;
Набор.Записать();
Метод Записать() по умолчанию работает в режиме замещения: он полностью заменяет существующие движения указанного регистратора содержимым набора. Если нужно добавить записи к уже существующим, вызовите Набор.Записать(Ложь) — но помните, что тогда при повторном запуске обработки записи задвоятся. Безопасный шаблон: прочитать набор методом Прочитать(), изменить его и записать с замещением.
Запись движений без перепроведения документа
Иногда требуется подправить движения уже проведённого документа — например, после исправления ошибки в алгоритме проведения. Для этого в обработке получают набор записей через Движения документа либо через СоздатьНаборЗаписей с отбором по регистратору, вызывают Прочитать(), корректируют записи и сохраняют Записать(). Сам документ при этом не перепроводится, его состояние «проведён» сохраняется.
Ограничение подхода: движения перестают соответствовать коду ОбработкаПроведения. При следующем перепроведении документа (вручную или групповым перепроведением) ваши правки будут затёрты. Поэтому правильное исправление — чинить алгоритм проведения и перепроводить документы, а ручную корректировку использовать как временную меру.
Проверка результата и типичные ошибки
После записи движений проверьте результат штатными средствами: откройте документ и перейдите к его движениям (в управляемом приложении — «Ещё → Движения документа»), затем сформируйте отчёт по регистру — «Остатки и обороты» или универсальный отчёт. Остаток на нужную дату должен совпасть с ожидаемым, а обороты Прихода и Расхода — с суммами документов.
Как проверить результат
Записи присутствуют, вид движения и измерения заполнены верно
Список движений пуст или регистра нет в списке — проверьте настройки движений документа
Остаток соответствует документам, нет отрицательных значений
Минусовые остатки — нарушена последовательность проведения или не хватает контроля
Движения не меняются при перепроведении документа
Движения дублируются — набор не очищается или запись идёт без замещения
Отдельно стоит проблема производительности: если документ проводится медленно, проверьте, не выполняется ли запрос к остаткам внутри цикла по строкам табличной части. Правильный подход — один запрос по всей таблице товаров до цикла и сверка в памяти.
При отладке проведения удобно временно выводить сформированные движения в сообщения или табличный документ до вызова Записать(). Это позволяет увидеть, какие именно записи уйдут в регистр, без анализа базы после проведения.
Часто задаваемые вопросы
Можно ли записать данные в регистр накопления без документа?
Нет, каждая запись обязана иметь регистратора. Для загрузки начальных остатков создают специальный служебный документ (например, «Ввод начальных остатков») и записывают движения от его имени. Это сохраняет связь остатков с первичным основанием.
Чем отличается Записать() от Записать(Истина) и Записать(Ложь)?
Записать() и Записать(Истина) эквивалентны: набор замещает все существующие движения регистратора. Записать(Ложь) добавляет записи к существующим без удаления — это нужно редко и требует защиты от дублирования при повторном запуске.
Почему после проведения документа движения не появились?
Проверьте три вещи: отмечен ли регистр на закладке «Движения» в свойствах документа, заполняется ли набор в ОбработкаПроведения (возможно, цикл не выполняется из-за пустой табличной части), не установлен ли Отказ = Истина до формирования движений — тогда транзакция откатывается целиком.
Как удалить движения документа, не отменяя проведение?
Создайте набор записей с отбором по регистратору и вызовите Записать() без добавления строк: пустой набор с замещением очистит движения. Учтите, что остатки изменятся, а при следующем перепроведении документа движения будут созданы заново.
Что делать, если остатки в регистре ушли в минус?
Найдите документы расхода, проведённые раньше документов прихода по времени, и восстановите последовательность — перепроведите документы в хронологическом порядке. Дополнительно включите контроль остатков при проведении, чтобы ситуация не повторялась.
Нужно ли писать движения по оборотному регистру иначе, чем по остаточному?
Код почти идентичен, но у записи оборотного регистра нет свойства ВидДвижения — заполняются только период, измерения и ресурсы. Контроль остатков для оборотных регистров не применяется, так как итогов по ним не существует.
Что важно запомнить
Движения в регистр накопления записываются набором записей, привязанным к документу-регистратору: в ОбработкаПроведения заполняется коллекция Движения с указанием вида движения, периода, измерений и ресурсов. Всегда устанавливайте отбор по регистратору при ручной записи, контролируйте остатки до расходных движений и проверяйте результат отчётом «Остатки и обороты».