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

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

Как изменить набор записей регистра сведений в 1С

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

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

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

Что такое набор записей и когда он нужен

Набор записей — это коллекция строк регистра сведений, объединённая общим отбором. Для независимого регистра отбор строится по измерениям и периоду, для подчинённого регистратору — по регистратору. Набор всегда записывается целиком: при записи платформа сначала удаляет существующие записи, попадающие под отбор (если замещение включено), а затем сохраняет содержимое набора.

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

Создание набора и установка отбора

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

НаборЗаписей = РегистрыСведений.КурсыВалют.СоздатьНаборЗаписей();

НаборЗаписей.Отбор.Валюта.Установить(ДолларСША);

НаборЗаписей.Отбор.Период.Установить(ТекущаяДатаСеанса());

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

Чтение и изменение существующих записей

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

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

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

Запись.Курс = Запись.Курс * 1.05;

КонецЦикла;

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

После изменения вызывается Записать(). Поскольку отбор не менялся и замещение включено по умолчанию, старые версии этих же записей будут замещены новыми — это корректный сценарий редактирования. Если нужно проверить, есть ли вообще данные по отбору, используют метод Выбран() после чтения или проверяют Количество() набора.

Альтернатива для точечного изменения одной строки — менеджер записи (СоздатьМенеджерЗаписи). Он читает и пишет ровно одну запись по полному ключу и не требует замещения, что безопаснее, когда меняется единственная строка.

Добавление новых записей через набор

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

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

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

НоваяЗапись = НаборЗаписей.Добавить();

НоваяЗапись.Номенклатура = Товар;

НоваяЗапись.ВидЦены = РозничнаяЦена;

НоваяЗапись.Цена = 1500;

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

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

Сравнение вариантов

Записать() с замещением

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

Записать(Ложь) без замещения

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

Менеджер записи

Подходит для точечного изменения одной строки по полному ключу. Не работает с массовыми операциями.

Удаление записей

Удаление через набор — это запись пустого набора с замещением. Устанавливается отбор по удаляемым данным, набор не заполняется (или очищается методом Очистить), после чего вызывается Записать(). Все записи под отбором будут удалены.

НаборЗаписей = РегистрыСведений.КурсыВалют.СоздатьНаборЗаписей();

НаборЗаписей.Отбор.Валюта.Установить(УстаревшаяВалюта);

НаборЗаписей.Записать(); // пустой набор = удаление по отбору

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

Типичные ошибки
01
Запись набора без отбора — при замещении очищается весь регистр, данные теряются безвозвратно.
02
Добавление записей с Записать() по умолчанию — существующие записи по отбору молча удаляются.
03
Удаление элементов набора в прямом цикле — из-за сдвига индексов часть строк пропускается.
04
Изменение значений измерений у прочитанной записи — фактически создаётся запись с другим ключом, старая при замещении исчезает.
05
Игнорирование ошибки уникальности при Записать(Ложь) — транзакция откатывается, данные не сохраняются.

Особенности периодических и подчинённых регистров

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

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

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

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

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

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

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

Количество записей по отбору после записи
Норма

Совпадает с количеством строк в записанном наборе

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

Меньше ожидаемого — часть записей не записалась или была замещена

Записи вне отбора
Норма

Количество записей по соседним ключам не изменилось

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

Уменьшилось — отбор был слишком широким, данные затёрты

Ключи записей
Норма

Измерения и период соответствуют задуманным

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

Появились дубли ключей или записи с пустыми измерениями

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

Чем набор записей отличается от менеджера записи?

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

Почему после Записать() пропали записи, которые я не трогал?

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

Можно ли установить отбор набора по ресурсу регистра?

Нет. Отбор набора записей возможен только по полям ключа: измерениям, периоду и регистратору. Для выборки по значениям ресурсов используйте запрос с условием ГДЕ, а затем обрабатывайте результат.

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

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

Ошибка «Запись с такими ключевыми полями существует» — что делать?

Ошибка возникает при Записать(Ложь), если в базе уже есть запись с тем же набором измерений и периода. Либо измените ключ добавляемой записи, либо сначала удалите/прочитайте существующую запись, либо используйте запись с замещением, если замена допустима.

Нужно ли вызывать Прочитать() перед добавлением новых записей?

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

Итог

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

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