Перезапись регистра сведений в 1С 8.3: способы и нюансы
Содержание
Перезаписать запись регистра
сведений в 1С 8.3 — значит записать строку с тем же ключом поверх старой. Ключ складывается из измерений и, для периодического регистра, из периода. Совпал ключ — старое значение затирается новым, второй строки не появляется. На этом держатся все способы: и ручная правка через Все функции, и программная запись менеджером записи или набором.
Дальше — где это настраивается в конфигурации, как исправить одну строку руками, как перезаписать массово кодом, что делать со срезом последних и какие ошибки ловят новичков. Отдельно — поведение в распределённой базе (РИБ), где одна и та же запись живёт в нескольких узлах.
Из чего складывается ключ записи и почему это важно
Регистр сведений хранит не произвольные строки, а записи, однозначно адресуемые ключом. Пока вы не поняли, что входит в ключ конкретного регистра, перезапись будет давать неожиданный результат: то лишние строки, то затёртые данные.
В ключ входят:
- 🔑 все измерения регистра (например, «Номенклатура» и «Склад»);
- 📅 период — только если регистр периодический;
- 🧾 регистратор — только если регистр подчинён регистратору.
Ресурсы и реквизиты в ключ не входят — это как раз те значения, которые вы и меняете при перезаписи. Записали новую строку с тем же набором измерений (и периодом) — платформа нашла существующую и заменила её ресурсы. Изменили хотя бы одно измерение — получили новую, отдельную запись, а старая осталась на месте.
Если вы ждали обновления значения, а в списке появилась вторая строка — значит, отличается одно из измерений или период. Сверьте ключевые поля обеих записей.
Какие свойства регистра влияют на перезапись
Поведение при записи задаётся в конфигураторе, в свойствах объекта «Регистр сведений». Три свойства решают почти всё.
Периодичность. Варианты — «Непериодический», «По позиции регистратора», «В пределах секунды / дня / месяца / квартала / года». Для периодического регистра период становится частью ключа и округляется до выбранной детальности. При периодичности «в пределах дня» записи 05.03 10:00 и 05.03 18:00 схлопнутся в одну строку за 5 марта — вторая перезапишет первую.
Режим записи. «Независимый» — записью управляете вы: напрямую, менеджером или набором. «Подчинение регистратору» — запись существует только пока существует документ-регистратор, и перезаписывается при перепроведении этого документа.
Измерения и их флаги. Чем больше измерений, тем «уже» ключ и тем точнее адресуется строка. Флаг «Ведущее» у измерения влияет на удаление записей вслед за удалением ссылочного значения, но не на саму перезапись.
Менять периодичность или состав измерений на рабочей базе — серьёзное изменение структуры. Оно требует монопольного доступа при обновлении и может «схлопнуть» или, наоборот, размножить уже накопленные записи. Делайте это только на копии и с резервной копией базы.
Ручная правка одной записи через интерфейс
Большинство регистров сведений не выведены в обычный интерфейс — до них добираются через меню «Все функции».
- Включите команду:
Главное меню → Настройки → Параметры, поставьте галку «Отображать команду “Все функции”», нажмите «ОК». Главное меню — это кнопка со стрелкой вниз в левом верхнем углу. - Откройте
Главное меню → Все функции → Регистры сведенийи выберите нужный регистр по имени. - В открывшемся списке найдите строку (отфильтруйте список по значению измерения через
Ещё → Настроить списокили поиск по колонке). - Откройте запись двойным щелчком, измените ресурсы или реквизиты, нажмите «Записать и закрыть».
Запись с тем же ключом заместится автоматически. Если же вы хотите «перенести» значение на другую дату или другое измерение — не редактируйте старую строку, а создайте новую кнопкой «Создать»: изменение ключа через правку приведёт к появлению дубля.
Есть ограничение: записи регистра, подчинённого регистратору, через «Все функции» руками не редактируются. Форма списка покажет их только на чтение. Чтобы их перезаписать, исправьте и перепроведите документ-регистратор либо используйте код (см. ниже).
Программная перезапись: менеджер записи и набор записей
В коде есть два инструмента, и выбор между ними — это выбор между «одной строкой» и «пачкой».
Менеджер записи — когда нужно переписать одну конкретную запись по полному ключу:
Запись = РегистрыСведений.ЦеныНоменклатуры.СоздатьМенеджерЗаписи();
Запись.Период = ТекущаяДата(); // только для периодического регистра
Запись.Номенклатура = ВыбраннаяНоменклатура;
Запись.Цена = НоваяЦена;
Запись.Записать(); // замещает запись с тем же ключом
Метод Записать() у менеджера по умолчанию замещает существующую запись. Если передать Записать(Ложь), а строка с таким ключом уже есть, платформа вернёт ошибку «Запись с такими ключевыми полями уже существует». Поэтому для перезаписи оставляйте вызов без параметра или Записать(Истина).
Если перед перезаписью нужно взять текущее значение (например, чтобы изменить его, а не затереть), сначала прочитайте запись в тот же менеджер:
Запись.Период = ТекущаяДата();
Запись.Номенклатура = ВыбраннаяНоменклатура;
Запись.Прочитать(); // подтянули существующую запись в менеджер
Если Запись.Выбран() Тогда
Запись.Цена = Запись.Цена * 1.1; // меняем от текущего значения
Иначе
Запись.Цена = НоваяЦена; // записи не было — создаём
КонецЕсли;
Запись.Записать();
Свойство Выбран() показывает, нашлась ли запись с заданным ключом. Так вы не затрёте данные вслепую и корректно обработаете случай, когда строки ещё нет.
Набор записей — когда нужно перезаписать группу строк по отбору:
Набор = РегистрыСведений.ЦеныНоменклатуры.СоздатьНаборЗаписей();
Набор.Отбор.Номенклатура.Установить(ВыбраннаяНоменклатура);
Набор.Прочитать(); // читаем текущие строки по отбору
// ... меняем строки набора или очищаем и добавляем заново ...
Набор.Записать(Истина); // Истина = заместить всё по отбору
Ключевое отличие: Записать(Истина) сначала удаляет все записи, попадающие под отбор, и только потом пишет строки набора. Записать(Ложь) — дописывает к существующим.
Если записать набор с установленным флагом замещения, но с пустым отбором, вы сотрёте весь регистр. Всегда проверяйте, что отбор задан, прежде чем вызывать Записать(Истина) на наборе.
Для регистра, подчинённого регистратору, отбор ставится по регистратору:
Набор = РегистрыСведений.ИсторияСтатусов.СоздатьНаборЗаписей();
Набор.Отбор.Регистратор.Установить(ДокументСсылка);
Набор.Прочитать();
// ... правим строки ...
Набор.Записать(Истина);
Удалить одну запись из кода можно тем же менеджером: задайте ключ и вызовите Запись.Удалить(). Это удобно, когда «перезапись» на деле означает убрать устаревшую строку, а не заменить её значение. Полностью очистить регистр
по отбору — пустой набор записей с замещением: прочитать не нужно, достаточно установить отбор, не добавлять строк и вызвать Записать(Истина).
Массовую перезапись выполняйте в транзакции и с блокировкой изменяемых данных — иначе параллельный сеанс успеет вклиниться между чтением и записью. Для набора по одному отбору транзакция открывается автоматически; при обходе многих значений измерения оборачивайте цикл в НачатьТранзакцию() / ЗафиксироватьТранзакцию() сами.
Срез последних, срез первых и пересчёт итогов
У периодического регистра кроме таблицы записей есть виртуальные таблицы «Срез последних» и «Срез первых» — они отдают по одной записи на каждую комбинацию измерений: самую свежую или самую раннюю на заданную дату. При перезаписи строки срез пересчитывается автоматически, отдельного действия не требуется.
Платформа умеет хранить заранее рассчитанный срез последних как итоги — это ускоряет запросы к большим регистрам. Хранение включается в конфигураторе, в свойствах регистра. В норме итоги поддерживаются в актуальном состоянии сами.
Пересчёт вручную нужен в двух случаях: после сбоя базы или после массовой перезаписи напрямую в таблицах. Делается это через Конфигуратор → Администрирование → Тестирование и исправление, пункт «Пересчёт итогов».
«Тестирование и исправление» требует монопольного доступа к базе — все пользователи должны выйти. Запускайте в нерабочее время и только после резервной копии: при проблемах с итогами режим может пересобрать служебные таблицы заметное время.
В запросе срез последних берётся из виртуальной таблицы РегистрСведений.ИмяРегистра.СрезПоследних(&Дата, Условие). Параметр даты задаёт момент, на который нужна актуальная запись, условие — отбор по измерениям:
ВЫБРАТЬ Цена
ИЗ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(&Дата, Номенклатура = &Номенклатура)
Если после перезаписи в отчёте по срезу последних «висит» старое значение, первым делом убедитесь, что новая запись действительно легла с большим или равным периодом, чем старая. Срез последних берёт запись с максимальным периодом на указанную дату — запись «задним числом», более старым периодом, в срез на свежую дату не попадёт, хотя физически в регистре она есть. Это частая причина «отчёт не видит мою правку»: значение перезаписано на прошлую дату, а срез смотрит на сегодня.
Типичные ошибки при перезаписи и их причины
Большинство сбоев при перезаписи — это не баги платформы, а несовпадение ожиданий с тем, как устроен ключ. Разберём по симптомам.
Записать() без параметра или Записать(Истина).Отдельно про монопольный доступ: для обычной перезаписи записей он не нужен — пишите хоть при работающих пользователях, нужны лишь корректные блокировки. Монополия требуется только для изменения структуры регистра в конфигураторе и для «Тестирования и исправления».
Особенности перезаписи в распределённой базе (РИБ)
В распределённой базе одна и та же запись регистра физически существует в каждом узле. Если регистр входит в состав плана обмена, то при перезаписи в любом узле платформа регистрирует изменение к выгрузке — и при следующем сеансе обмена новое значение разъезжается по узлам.
Что держать в голове:
- 🔁 перезаписали запись в периферийном узле — изменение уедет в центральный и обратно к остальным по правилам плана обмена;
- ⚖️ при конфликте (одну и ту же запись изменили в двух узлах между обменами) побеждает узел с более высоким приоритетом, обычно центральный; изменение проигравшего узла затирается;
- 🚫 не перезаписывайте одну запись одновременно в двух узлах — дождитесь обмена, иначе потеряете одну из правок;
- 🧩 если регистр не включён в план обмена, перезапись останется локальной и в другие узлы не попадёт — это легко принять за «потерю данных».
Массовую перезапись регистра в РИБ лучше делать в одном узле (как правило, в центральном) и дать изменениям разойтись штатным обменом, а не править параллельно в нескольких узлах. После крупной правки проведите обмен сразу, не копите изменения: чем дольше узлы расходятся, тем выше шанс конфликта по одной и той же записи.