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