Разработка и Конфигурация · 11 мин
Как программно изменить запись регистра накопления в 1С
Как программно изменить записи регистра накопления в 1С: набор записей, корректировка движений документа, обход изменением, типичные ошибки и проверка результата.
Регистры накопления в 1С хранят обороты и остатки: товары на складах, деньги на счетах, взаиморасчёты. Прямое редактирование записей вручную в типовой конфигурации недоступно, поэтому изменения выполняют программно — через набор записей регистра. Правильный способ зависит от того, кто является регистратором записи: документ, чьи движения нужно поправить, или служебный документ корректировки.
Главное правило: записи регистра накопления почти всегда подчинены регистратору. Это значит, что нельзя просто «поменять цифру» в таблице регистра — нужно либо изменить движения документа-регистратора, либо создать новый документ (например, «Корректировка регистров» или «Операция»), который внесёт исправительные движения. Попытка записать набор без регистратора в такой регистр завершится ошибкой.
Ниже разобраны рабочие способы: чтение и правка набора записей, замещение и добавление движений, корректировка через отдельный документ, а также проверка результата и типичные ошибки, которые приводят к расхождению остатков.
Как устроены записи регистра накопления
Каждая строка регистра накопления содержит обязательные системные поля: период, регистратор, вид движения (приход или расход), а также измерения, ресурсы и реквизиты, определённые в конфигурации. Уникальность строки обеспечивается комбинацией регистратора и номера строки, поэтому «найти одну запись и перезаписать её» на уровне СУБД нельзя — платформа работает только с наборами записей целиком.
Набор записей — это объект РегистрыНакопления.ИмяРегистра.СоздатьНаборЗаписей(). Он представляет собой коллекцию строк, связанных одним регистратором. Все операции чтения и записи выполняются в рамках этого набора: вы загружаете движения конкретного документа, меняете их и сохраняете обратно.
Способ 1. Изменение движений через набор записей
Это основной приём, когда нужно поправить движения существующего документа: исправить количество, сумму, склад или удалить лишнюю строку. Последовательность такая: создать набор записей, установить отбор по регистратору, прочитать набор, внести изменения, записать с замещением.
НаборЗаписей = РегистрыНакопления.ТоварыНаСкладах.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Регистратор.Установить(ДокументСсылка);
НаборЗаписей.Прочитать();
Для Каждого Запись Из НаборЗаписей Цикл
Если Запись.Номенклатура = НужнаяНоменклатура Тогда
Запись.Количество = НовоеКоличество;
КонецЕсли;
КонецЦикла;
НаборЗаписей.Записать(Истина); // Истина — замещение существующих движений
Параметр Истина в методе Записать() означает замещение: старые движения документа полностью заменяются содержимым набора. Если передать Ложь (или опустить параметр), новые строки добавятся к существующим, что почти наверняка создаст дубли. Для режима «добавить строки к чужим движениям» набор должен иметь другого регистратора — иначе логика замещения не позволит корректно смешивать строки.
Если нужно удалить одну запись, используйте НаборЗаписей.Удалить(Индекс) или удалите строку через поиск в цикле. Если требуется полностью очистить движения документа, достаточно вызвать НаборЗаписей.Записать(Истина) на пустом наборе с установленным отбором — это штатный способ «распровести» регистр по конкретному документу без пометки самого документа.
- 1Создайте набор записей нужного регистра
- 2Установите отбор по регистратору (ссылка на документ)
- 3Прочитайте набор методом Прочитать()
- 4Измените, добавьте или удалите строки
- 5Запишите с параметром Замещение = Истина
- 6Проверьте остатки отчётом или запросом
Способ 2. Корректировка отдельным документом
Когда чужой документ трогать нельзя (закрытый период, документ из другой подсистемы, требуется аудит изменений), правильное решение — внести исправление собственными движениями. В типовых конфигурациях для этого есть документ «Корректировка регистров» (в старых конфигурациях — «Корректировка записей регистров»), а в бухгалтерских — «Операция».
Программно это выглядит как создание и проведение документа-регистратора с нужными строками. Для собственного документа в модуле объекта движения формируются через коллекцию Движения:
Движение = Движения.ТоварыНаСкладах.Добавить();
Движение.ВидДвижения = ВидДвиженияНакопления.Расход;
Движение.Период = Дата;
Движение.Номенклатура = НоменклатураКорректировки;
Движение.Склад = СкладКорректировки;
Движение.Количество = -1 * РазницаКоличество; // сторно
Движения.ТоварыНаСкладах.Записать();
Важный нюанс: исправление обычно делают сторнирующей записью — той же аналитикой, но с противоположным знаком или видом движения, а затем при необходимости добавляют правильную строку. Так сохраняется история: по отчётам видно, что и когда было скорректировано, а не «тихо» перезаписано.
Сравнение подходов
Подходит для свежих документов в открытом периоде. Быстро, но стирает историю изменений и может конфликтовать с перепроведением документа.
Подходит для закрытых периодов и случаев, где нужен аудит. Требует отдельного документа-регистратора и аккуратного расчёта сторнирующих сумм.
Подходит, когда ошибка в данных самого документа: исправили табличную часть — перепровели, движения пересоздадутся штатно.
Способ 3. Перепроведение документа после исправления данных
Часто менять записи регистра напрямую вообще не нужно: ошибка находится в самом документе — неверное количество в табличной части, не тот склад, неправильная дата. В этом случае правильная последовательность — исправить реквизиты документа и перепровести его методом ДокументОбъект.Записать(РежимЗаписиДокумента.Проведение). Платформа сама очистит старые движения и сформирует новые по логике модуля проведения.
Это самый безопасный путь, потому что сохраняется целостность: движения всегда соответствуют данным документа, контроль остатков и прочие проверки модуля проведения срабатывают штатно. Ручная правка набора записей оправдана только тогда, когда логика проведения не позволяет получить нужный результат — например, требуется технологическая корректировка, которой нет в прикладной модели.
Транзакции, блокировки и производительность
Запись набора выполняется в транзакции. Если вы массово правите движения многих документов в цикле, открывайте явную транзакцию вокруг разумной порции операций, а не вокруг всего пакета: длинная транзакция держит блокировки на таблицах итогов и мешает пользователям проводить документы по тем же регистрам.
При записи набора платформа пересчитывает итоги регистра по затронутым периодам. Массовые изменения в «глубоком» прошлом при включённых итогах могут занять заметное время. Для разовых сервисных обработок имеет смысл выполнять их в монопольном или малонагруженном окне, а после завершения проверить актуальность итогов.
Ещё одна деталь: метод Записать() набора записей по умолчанию не вызывает обработчики проведения документа — он пишет только движения. Это удобно для точечной правки, но означает, что контроль остатков и бизнес-проверки модуля проведения не сработают. Ответственность за корректность данных в этом случае полностью на вашем коде.
Проверка результата после изменения
После записи набора обязательно сверьте результат независимым инструментом. Самый надёжный способ — запрос к виртуальной таблице остатков или оборотов регистра с отбором по изменённой аналитике до и после правки. Разница должна точно совпадать с внесённой корректировкой.
Также проверьте, что не «поплыли» связанные данные: если регистр участвует в расчёте себестоимости, взаиморасчётов или НДС, изменение его движений может потребовать перепроведения зависимых документов. В типовых конфигурациях полезно воспользоваться штатными отчётами («Остатки товаров на складах», оборотно-сальдовая ведомость) и сверкой с данными до правки.
Как проверить результат
Изменился ровно на величину корректировки
Остаток не изменился или съехал в другую сторону — проверьте знак и вид движения
Видны только ожидаемые строки, без дублей
Строки задвоены — вероятно, запись выполнена без замещения
Отбор строго по одному регистратору
Отбор не установлен — риск затронуть движения других документов
Типичные ошибки при программной правке
Самая частая ошибка — запись набора без установленного отбора по регистратору. В зависимости от режима это либо ошибка выполнения, либо попытка затронуть чужие движения. Всегда устанавливайте отбор до вызова Прочитать() и Записать().
Вторая группа ошибок — неверный знак или вид движения при сторнировании. Для регистра остатков сторно делают той же строкой с отрицательным количеством/суммой или противоположным видом движения — но не обоими сразу, иначе получите удвоенный эффект вместо обнуления. Третья типичная проблема — забытая периодичность: поле Период у новой строки должно попадать в нужный отчётный период, иначе корректировка «не увидится» в отчётах.
FAQ
Можно ли изменить одну запись регистра, не читая весь набор?
Технически нет: платформа оперирует наборами записей целиком в разрезе регистратора. Минимальный безопасный объём — прочитать набор по регистратору, изменить нужную строку и записать с замещением. Частичной записи отдельной строки в регистре накопления не существует.
Чем отличается Записать(Истина) от Записать(Ложь) у набора записей?
Параметр управляет замещением. Истина — старые движения регистратора полностью заменяются содержимым набора. Ложь — строки добавляются к существующим, что для одного регистратора приводит к дублям. Для правки движений документа почти всегда нужен режим замещения.
Как полностью удалить движения документа из регистра?
Создайте набор записей, установите отбор по регистратору и вызовите Записать(Истина) на пустом наборе. Движения будут очищены, а сам документ останется проведённым. Учтите: при следующем перепроведении документа движения сформируются заново по логике модуля проведения.
Сработает ли контроль остатков при ручной записи набора?
Нет. Контроль остатков и прочие проверки выполняются в обработке проведения документа, а прямая запись набора её не вызывает. Поэтому после ручной правки остатки могут уйти в минус без каких-либо сообщений — проверяйте результат запросом или отчётом самостоятельно.
Что делать, если период закрыт и документ править нельзя?
Используйте корректировку отдельным документом в открытом периоде: «Корректировка регистров» или собственный документ-регистратор со сторнирующими и правильными движениями. Так сохраняется аудит и не нарушается целостность закрытого периода.
Можно ли изменить записи регистра напрямую запросом к СУБД?
Категорически не рекомендуется. Прямая правка таблиц СУБД обходит механизмы платформы: не обновляются таблицы итогов, нарушается целостность служебных полей, а поддержка такой базы может быть снята. Все изменения выполняйте только средствами встроенного языка 1С.
Что важно запомнить
Записи регистра накопления меняют только через набор записей с отбором по регистратору и записью в режиме замещения. Для закрытых периодов и аудита используйте корректировку отдельным документом, а после любой правки сверяйте остатки независимым отчётом или запросом.