К статье
Практический материал

Разработка и Конфигурация · 11 мин

Как программно добавить запись в регистр накопления 1С

Программное добавление записей в регистр накопления 1С: набор записей, движения документа, ручные корректировки, примеры кода на встроенном языке.

Регистр накопления в 1С хранит количественные и суммовые показатели: остатки товаров, взаиморасчёты, объёмы продаж. Почти всегда записи в него попадают при проведении документов, но в практике разработки регулярно возникают задачи, где запись нужно добавить программно: обработка загрузки начальных остатков, исправление ошибок учёта, интеграция с внешними системами, регламентные операции свёртки данных.

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

Ниже разобраны оба подхода с примерами кода на встроенном языке 1С, типичные ошибки и способы проверить результат. Примеры применимы к платформе 8.3 и управляемым приложениям; синтаксис в обычных формах идентичен.

Что нужно понять перед добавлением записи

Регистр накопления имеет структуру: измерения (разрезы учёта — номенклатура, склад, контрагент), ресурсы (числовые показатели — количество, сумма) и реквизиты (дополнительная аналитика). Каждая запись обязательно содержит период, признак активности и, для регистров остатков, вид движения — приход или расход.

Ключевое свойство — режим записи. Регистр может быть подчинён регистратору (стандартный случай: каждая запись ссылается на документ) или быть независимым. Для подчинённого регистра запись без регистратора невозможна: платформа потребует заполнить поле «Регистратор», иначе запись не сохранится. Это главное ограничение прямого способа.

Также важно понимать, что записи регистра, подчинённого регистратору, платформа считает «собственностью» документа. При перепроведении документа его движения полностью перезаписываются, а при отмене проведения — удаляются. Любые записи, добавленные «в обход» логики проведения, но с указанием этого документа как регистратора, будут потеряны.

Способ 1: добавить движение при проведении документа

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

Процедура ОбработкаПроведения(Отказ, РежимПроведения)

Движения.ОстаткиТоваров.Записывать = Истина;

Для Каждого СтрокаТовара Из Товары Цикл

Движение = Движения.ОстаткиТоваров.Добавить();

Движение.ВидДвижения = ВидДвиженияНакопления.Приход;

Движение.Период = Дата;

Движение.Номенклатура = СтрокаТовара.Номенклатура;

Движение.Склад = Склад;

Движение.Количество = СтрокаТовара.Количество;

КонецЦикла;

КонецПроцедуры

Обратите внимание на строку Записывать = Истина. Без неё, если документ уже проводился и набор движений был прочитан, платформа может не записать изменения. Установка этого свойства гарантирует, что коллекция будет записана даже при пустом наборе — это важно для очистки движений при изменении логики.

Если движение нужно добавить не из модуля документа, а из внешней обработки, документ сначала получают как объект (ДокументСсылка.ПолучитьОбъект()), затем работают с его коллекцией «Движения» и вызывают ДокументОбъект.Записать(РежимЗаписиДокумента.Проведение). Либо записывают набор движений отдельно, установив отбор по регистратору — об этом ниже.

Способ 2: прямая запись через набор записей

Когда документ-регистратор отсутствует или не нужен (независимый регистр, служебная загрузка), записи добавляют напрямую. Создают набор записей, при необходимости устанавливают отбор, добавляют строки и вызывают Записать().

НаборЗаписей = РегистрыНакопления.ОстаткиТоваров.СоздатьНаборЗаписей();

НаборЗаписей.Отбор.Регистратор.Установить(ДокументСсылка);

НаборЗаписей.Прочитать();

НоваяЗапись = НаборЗаписей.Добавить();

НоваяЗапись.ВидДвижения = ВидДвиженияНакопления.Приход;

НоваяЗапись.Период = ТекущаяДатаСеанса();

НоваяЗапись.Регистратор = ДокументСсылка;

НоваяЗапись.Номенклатура = НоменклатураСсылка;

НоваяЗапись.Склад = СкладСсылка;

НоваяЗапись.Количество = 10;

НаборЗаписей.Записать();

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

Если нужно именно добавить записи без предварительного чтения, используют НаборЗаписей.Записать(Ложь) — параметр «Ложь» отключает замещение. Но этот приём опасен: при повторном выполнении кода записи задвоятся, потому что платформа добавит их поверх существующих.

Как добавить запись из внешней обработки или регламентного задания

Типовой сценарий — обработка корректировки остатков. Правильный подход: создать (или найти) служебный документ, например «Корректировка регистров» или «Операция», и провести его с нужными движениями. Так корректировка остаётся видимой в журналах, отчётах и при аудите.

ДокОбъект = Документы.КорректировкаРегистров.СоздатьДокумент();

ДокОбъект.Дата = ТекущаяДатаСеанса();

ДокОбъект.Записать();

Набор = РегистрыНакопления.ОстаткиТоваров.СоздатьНаборЗаписей();

Набор.Отбор.Регистратор.Установить(ДокОбъект.Ссылка);

Запись = Набор.Добавить();

Запись.ВидДвижения = ВидДвиженияНакопления.Приход;

Запись.Период = ДокОбъект.Дата;

Запись.Номенклатура = НоменклатураСсылка;

Запись.Количество = РазницаОстатка;

Набор.Записать();

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

Порядок действий
  1. 1
    Определите, есть ли документ-регистратор: если да — работайте через Движения при проведении
  2. 2
    Для прямой записи создайте набор записей и установите отбор по регистратору
  3. 3
    Прочитайте набор, если нужно сохранить существующие записи
  4. 4
    Добавьте записи, заполнив ВидДвижения, Период, измерения и ресурсы
  5. 5
    Вызовите Записать() и проверьте результат отчётом или запросом

Сравнение подходов и выбор способа

Два подхода не взаимозаменяемы полностью. Проведение документа даёт целостность учёта и автоматическое управление движениями, но требует документа. Прямая запись гибче и быстрее для служебных задач, но перекладывает всю ответственность на разработчика.

Сравнение вариантов

Движения при проведении

Штатный учёт, отчёты и аудит. Движения автоматически очищаются при отмене проведения. Требует документа и обработчика проведения.

Набор записей с отбором по регистратору

Подходит для обработок исправления движений существующего документа. Риск: перепроведение документа затрёт ручные изменения.

Прямая запись без регистратора

Только для независимых регистров и служебных задач. Полный ручной контроль и полная ответственность за целостность данных.

Для загрузки начальных остатков при внедрении обычно используют типовой документ «Ввод начальных остатков» или аналог, создавая его программно и проводя. Это медленнее прямой записи, но остатки остаются «легальными» для всех механизмов конфигурации, включая расчёт итогов и последовательности.

Частые ошибки и как их избежать

Самая распространённая ошибка — потеря существующих движений из-за записи набора без предварительного чтения. Вторая по частоте — забытый ВидДвижения для регистра остатков: запись сохранится, но отчёт по остаткам покажет неверные данные, потому что платформа не сможет корректно рассчитать итог.

Третья группа ошибок связана с периодом. Запись с пустой датой или датой, не совпадающей с датой регистратора, искажает отчёты по периодам и может нарушить последовательность документов. Всегда заполняйте Период явно и сверяйте его с датой документа.

Типичные ошибки
01
Записать() без Прочитать() — стираются существующие движения регистратора
02
Записать(Ложь) в цикле загрузки — записи дублируются при повторном запуске
03
Не заполнен ВидДвижения для регистра остатков — некорректные итоги в отчётах
04
Пустой Период или дата, не совпадающая с регистратором — искажение отчётов по периодам
05
Ручные движения у проводимого документа — они исчезают при перепроведении

Как проверить, что запись добавлена корректно

После записи проверьте результат стандартным отчётом по регистру (например, «Остатки товаров» или универсальным отчётом) либо запросом в консоли запросов. Сверьте количество записей, значения измерений и итоговые ресурсы. Если запись добавлялась к документу, откройте его движения через «Ещё → Движения документа» в форме документа.

Дополнительно убедитесь, что итоги регистра рассчитаны на нужный период: если запись добавлена «задним числом» за пределами рассчитанных итогов, отчёты могут временно показывать устаревшие значения до пересчёта итогов. В файловой базе итоги пересчитываются при проведении, в клиент-серверной — обычно автоматически, но при массовых загрузках стоит проверить.

Контрольные точки

Как проверить результат

Движения документа
Норма

Новая запись видна в списке движений с верными измерениями

Тревожный признак

Записи нет или старые движения исчезли

Отчёт по регистру
Норма

Остаток/оборот изменился на ожидаемую величину

Тревожный признак

Итог не изменился или изменился вдвое

Повторный запуск обработки
Норма

Данные не дублируются

Тревожный признак

Каждый запуск добавляет копии записей

FAQ

Можно ли добавить запись в регистр накопления без документа?

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

Почему после Записать() пропали старые движения документа?

Метод Записать() по умолчанию работает в режиме замещения: он заменяет все записи по отбору содержимым набора. Чтобы сохранить существующие движения, вызовите Прочитать() перед добавлением новых строк — тогда в наборе окажутся и старые, и новые записи.

Чем отличается Записать() от Записать(Ложь)?

Параметр определяет режим замещения. Записать(Истина) — заменить записи по отбору (поведение по умолчанию). Записать(Ложь) — добавить записи поверх существующих без замещения. Второй вариант удобен для дозаписи, но при повторном выполнении приводит к дублям.

Как удалить программно добавленную запись?

Создайте набор записей, установите отбор (по регистратору или, для независимого регистра, по нужным полям), прочитайте его, удалите нужные строки методом Удалить() и вызовите Записать(). Для очистки всех движений документа достаточно записать пустой набор с отбором по регистратору.

Что произойдёт с ручными записями при перепроведении документа?

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

Нужно ли пересчитывать итоги после прямой записи?

Если записи добавлены в текущий период, платформа обычно поддерживает итоги актуальными автоматически. При массовой загрузке за прошлые периоды отчёты могут показывать устаревшие итоги до их пересчёта — в этом случае выполните пересчёт итогов через функции администрирования или метод УстановитьПериодРассчитанныхИтогов.

Итог

Что важно запомнить

Штатный путь — движения через коллекцию Движения при проведении документа; прямой путь — набор записей с отбором и Записать(). Всегда читайте набор перед дополнением, заполняйте ВидДвижения и Период, помните: перепроведение документа уничтожит ручные записи. Перед массовыми операциями делайте резервную копию и проверяйте результат отчётом.