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

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

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

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

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

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

Ниже разобраны рабочие способы: чтение и правка набора записей, замещение и добавление движений, корректировка через отдельный документ, а также проверка результата и типичные ошибки, которые приводят к расхождению остатков.

Как устроены записи регистра накопления

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

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

Способ 1. Изменение движений через набор записей

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

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

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

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

Для Каждого Запись Из НаборЗаписей Цикл

Если Запись.Номенклатура = НужнаяНоменклатура Тогда

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

КонецЕсли;

КонецЦикла;

НаборЗаписей.Записать(Истина); // Истина — замещение существующих движений

Параметр Истина в методе Записать() означает замещение: старые движения документа полностью заменяются содержимым набора. Если передать Ложь (или опустить параметр), новые строки добавятся к существующим, что почти наверняка создаст дубли. Для режима «добавить строки к чужим движениям» набор должен иметь другого регистратора — иначе логика замещения не позволит корректно смешивать строки.

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

Порядок изменения движений документа
  1. 1
    Создайте набор записей нужного регистра
  2. 2
    Установите отбор по регистратору (ссылка на документ)
  3. 3
    Прочитайте набор методом Прочитать()
  4. 4
    Измените, добавьте или удалите строки
  5. 5
    Запишите с параметром Замещение = Истина
  6. 6
    Проверьте остатки отчётом или запросом

Способ 2. Корректировка отдельным документом

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

Программно это выглядит как создание и проведение документа-регистратора с нужными строками. Для собственного документа в модуле объекта движения формируются через коллекцию Движения:

Движение = Движения.ТоварыНаСкладах.Добавить();

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

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

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

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

Движение.Количество = -1 * РазницаКоличество; // сторно

Движения.ТоварыНаСкладах.Записать();

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

Сравнение подходов

Правка набора записей регистратора

Подходит для свежих документов в открытом периоде. Быстро, но стирает историю изменений и может конфликтовать с перепроведением документа.

Корректировка отдельным документом

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

Перепроведение документа

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

Способ 3. Перепроведение документа после исправления данных

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

Это самый безопасный путь, потому что сохраняется целостность: движения всегда соответствуют данным документа, контроль остатков и прочие проверки модуля проведения срабатывают штатно. Ручная правка набора записей оправдана только тогда, когда логика проведения не позволяет получить нужный результат — например, требуется технологическая корректировка, которой нет в прикладной модели.

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

Запись набора выполняется в транзакции. Если вы массово правите движения многих документов в цикле, открывайте явную транзакцию вокруг разумной порции операций, а не вокруг всего пакета: длинная транзакция держит блокировки на таблицах итогов и мешает пользователям проводить документы по тем же регистрам.

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

Ещё одна деталь: метод Записать() набора записей по умолчанию не вызывает обработчики проведения документа — он пишет только движения. Это удобно для точечной правки, но означает, что контроль остатков и бизнес-проверки модуля проведения не сработают. Ответственность за корректность данных в этом случае полностью на вашем коде.

Проверка результата после изменения

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

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

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

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

Остаток по изменённой аналитике
Норма

Изменился ровно на величину корректировки

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

Остаток не изменился или съехал в другую сторону — проверьте знак и вид движения

Движения документа в отчёте по регистру
Норма

Видны только ожидаемые строки, без дублей

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

Строки задвоены — вероятно, запись выполнена без замещения

Отбор набора записей
Норма

Отбор строго по одному регистратору

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

Отбор не установлен — риск затронуть движения других документов

Типичные ошибки при программной правке

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

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

Типичные ошибки
01
Запись без замещения — движения документа задваиваются, остатки завышаются
02
Отбор по регистратору не установлен — риск повредить движения других документов
03
Сторно с одновременной сменой знака и вида движения — эффект удваивается вместо обнуления
04
Незаполненный Период у новой строки — корректировка попадает не в тот отчётный период
05
Правка движений документа, который потом перепроводят — ручные изменения теряются

FAQ

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

Технически нет: платформа оперирует наборами записей целиком в разрезе регистратора. Минимальный безопасный объём — прочитать набор по регистратору, изменить нужную строку и записать с замещением. Частичной записи отдельной строки в регистре накопления не существует.

Чем отличается Записать(Истина) от Записать(Ложь) у набора записей?

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

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

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

Сработает ли контроль остатков при ручной записи набора?

Нет. Контроль остатков и прочие проверки выполняются в обработке проведения документа, а прямая запись набора её не вызывает. Поэтому после ручной правки остатки могут уйти в минус без каких-либо сообщений — проверяйте результат запросом или отчётом самостоятельно.

Что делать, если период закрыт и документ править нельзя?

Используйте корректировку отдельным документом в открытом периоде: «Корректировка регистров» или собственный документ-регистратор со сторнирующими и правильными движениями. Так сохраняется аудит и не нарушается целостность закрытого периода.

Можно ли изменить записи регистра напрямую запросом к СУБД?

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

Итог

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

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