Перезапись регистра сведений в 1С 8.3: способы и нюансы

· 9 мин

Содержание

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

Дальше — где это настраивается в конфигурации, как исправить одну строку руками, как перезаписать массово кодом, что делать со срезом последних и какие ошибки ловят новичков. Отдельно — поведение в распределённой базе (РИБ), где одна и та же запись живёт в нескольких узлах.

Из чего складывается ключ записи и почему это важно

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

В ключ входят:

  • 🔑 все измерения регистра (например, «Номенклатура» и «Склад»);
  • 📅 период — только если регистр периодический;
  • 🧾 регистратор — только если регистр подчинён регистратору.

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

Если вы ждали обновления значения, а в списке появилась вторая строка — значит, отличается одно из измерений или период. Сверьте ключевые поля обеих записей.

Какие свойства регистра влияют на перезапись

Поведение при записи задаётся в конфигураторе, в свойствах объекта «Регистр сведений». Три свойства решают почти всё.

Периодичность. Варианты — «Непериодический», «По позиции регистратора», «В пределах секунды / дня / месяца / квартала / года». Для периодического регистра период становится частью ключа и округляется до выбранной детальности. При периодичности «в пределах дня» записи 05.03 10:00 и 05.03 18:00 схлопнутся в одну строку за 5 марта — вторая перезапишет первую.

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

Измерения и их флаги. Чем больше измерений, тем «уже» ключ и тем точнее адресуется строка. Флаг «Ведущее» у измерения влияет на удаление записей вслед за удалением ссылочного значения, но не на саму перезапись.

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

Ручная правка одной записи через интерфейс

Большинство регистров сведений не выведены в обычный интерфейс — до них добираются через меню «Все функции».

  1. Включите команду: Главное меню → Настройки → Параметры, поставьте галку «Отображать команду “Все функции”», нажмите «ОК». Главное меню — это кнопка со стрелкой вниз в левом верхнем углу.
  2. Откройте Главное меню → Все функции → Регистры сведений и выберите нужный регистр по имени.
  3. В открывшемся списке найдите строку (отфильтруйте список по значению измерения через Ещё → Настроить список или поиск по колонке).
  4. Откройте запись двойным щелчком, измените ресурсы или реквизиты, нажмите «Записать и закрыть».

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

Есть ограничение: записи регистра, подчинённого регистратору, через «Все функции» руками не редактируются. Форма списка покажет их только на чтение. Чтобы их перезаписать, исправьте и перепроведите документ-регистратор либо используйте код (см. ниже).

Перед ручной правкой записи регистра
Выполнено: 0 / 5

Программная перезапись: менеджер записи и набор записей

В коде есть два инструмента, и выбор между ними — это выбор между «одной строкой» и «пачкой».

Менеджер записи — когда нужно переписать одну конкретную запись по полному ключу:

Запись = РегистрыСведений.ЦеныНоменклатуры.СоздатьМенеджерЗаписи();
Запись.Период       = ТекущаяДата();   // только для периодического регистра
Запись.Номенклатура = ВыбраннаяНоменклатура;
Запись.Цена         = НоваяЦена;
Запись.Записать();                      // замещает запись с тем же ключом

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

Если перед перезаписью нужно взять текущее значение (например, чтобы изменить его, а не затереть), сначала прочитайте запись в тот же менеджер:

Запись.Период       = ТекущаяДата();
Запись.Номенклатура = ВыбраннаяНоменклатура;
Запись.Прочитать();                  // подтянули существующую запись в менеджер
Если Запись.Выбран() Тогда
    Запись.Цена = Запись.Цена * 1.1; // меняем от текущего значения
Иначе
    Запись.Цена = НоваяЦена;         // записи не было — создаём
КонецЕсли;
Запись.Записать();

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

Набор записей — когда нужно перезаписать группу строк по отбору:

Набор = РегистрыСведений.ЦеныНоменклатуры.СоздатьНаборЗаписей();
Набор.Отбор.Номенклатура.Установить(ВыбраннаяНоменклатура);
Набор.Прочитать();           // читаем текущие строки по отбору
// ... меняем строки набора или очищаем и добавляем заново ...
Набор.Записать(Истина);      // Истина = заместить всё по отбору

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

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

Для регистра, подчинённого регистратору, отбор ставится по регистратору:

Набор = РегистрыСведений.ИсторияСтатусов.СоздатьНаборЗаписей();
Набор.Отбор.Регистратор.Установить(ДокументСсылка);
Набор.Прочитать();
// ... правим строки ...
Набор.Записать(Истина);

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

Массовую перезапись выполняйте в транзакции и с блокировкой изменяемых данных — иначе параллельный сеанс успеет вклиниться между чтением и записью. Для набора по одному отбору транзакция открывается автоматически; при обходе многих значений измерения оборачивайте цикл в НачатьТранзакцию() / ЗафиксироватьТранзакцию() сами.

Срез последних, срез первых и пересчёт итогов

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

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

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

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

В запросе срез последних берётся из виртуальной таблицы РегистрСведений.ИмяРегистра.СрезПоследних(&Дата, Условие). Параметр даты задаёт момент, на который нужна актуальная запись, условие — отбор по измерениям:

ВЫБРАТЬ Цена
ИЗ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(&Дата, Номенклатура = &Номенклатура)

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

Типичные ошибки при перезаписи и их причины

Большинство сбоев при перезаписи — это не баги платформы, а несовпадение ожиданий с тем, как устроен ключ. Разберём по симптомам.

Диагностика: выберите симптом

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

Особенности перезаписи в распределённой базе (РИБ)

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

Что держать в голове:

  • 🔁 перезаписали запись в периферийном узле — изменение уедет в центральный и обратно к остальным по правилам плана обмена;
  • ⚖️ при конфликте (одну и ту же запись изменили в двух узлах между обменами) побеждает узел с более высоким приоритетом, обычно центральный; изменение проигравшего узла затирается;
  • 🚫 не перезаписывайте одну запись одновременно в двух узлах — дождитесь обмена, иначе потеряете одну из правок;
  • 🧩 если регистр не включён в план обмена, перезапись останется локальной и в другие узлы не попадёт — это легко принять за «потерю данных».

Массовую перезапись регистра в РИБ лучше делать в одном узле (как правило, в центральном) и дать изменениям разойтись штатным обменом, а не править параллельно в нескольких узлах. После крупной правки проведите обмен сразу, не копите изменения: чем дольше узлы расходятся, тем выше шанс конфликта по одной и той же записи.

Частые вопросы

Чем менеджер записи отличается от набора записей?
Менеджер работает с одной записью по полному ключу и всегда замещает её. Набор работает с группой строк по отбору: с флагом замещения он сначала удаляет всё под отбор, затем пишет новые строки.
Можно ли перезаписать запись, подчинённую регистратору, напрямую?
Руками в форме списка — нет, такие записи только на чтение. Программно — можно набором записей с отбором по регистратору, но обычно правильнее исправить и перепровести сам документ.
Почему при записи новой строки старая не исчезла?
Не совпал ключ: отличается измерение или период. В периодическом регистре период ещё и округляется до детальности периодичности — проверьте, в один ли интервал попали обе записи.
Нужен ли монопольный режим, чтобы перезаписать запись?
Нет. Для обычной перезаписи достаточно корректных блокировок. Монополия нужна только для изменения структуры регистра и для пересчёта итогов через «Тестирование и исправление».
Как перезаписать весь регистр с нуля, ничего не потеряв?
Выгрузите текущие данные (например, в табличный документ или запросом), очистите регистр набором записей, затем загрузите подготовленные строки. И обязательно сделайте резервную копию базы до начала.