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

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

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

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

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

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

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

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

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

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

Базовый код записи набора

Минимальный рабочий пример для непериодического регистра сведений с измерением «Номенклатура» и ресурсом «Цена»:

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

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

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

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

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

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

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

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

Отборы: главный элемент безопасности

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

Правила безопасной работы с отборами:

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

Режим замещения и чтение существующих данных

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

Если нужно изменить часть записей, сохранив остальные, сначала вызовите Набор.Прочитать(), затем модифицируйте строки набора и запишите его. Добавление записи в непрочитанный набор с замещением сотрёт всё, что было в базе по этому отбору раньше.

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

Записать(Истина)

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

Записать(Ложь)

Добавление без затирания существующих записей. Подходит для дозагрузки, но даёт ошибку при дублях ключей.

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

Запись одной строки без отборов. Оптимален для точечных изменений, не подходит для массовой обработки.

Массовая загрузка и транзакции

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

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

Порядок действий при массовой загрузке
  1. 1
    Создайте набор записей и установите отбор по ключевому измерению
  2. 2
    Начните транзакцию
  3. 3
    Заполните набор порцией записей через Добавить()
  4. 4
    Вызовите Записать() и очистите набор
  5. 5
    Повторяйте до конца данных, затем зафиксируйте транзакцию
  6. 6
    Проверьте количество записей запросом

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

После записи убедитесь, что данные легли корректно. Самый надёжный способ — запрос к регистру с тем же отбором: сравните количество и содержимое записей с ожидаемым. В режиме предприятия записи видны в стандартной форме списка регистра.

Контрольные точки

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

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

Совпадает с числом загруженных строк

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

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

Значения измерений в записях
Норма

Соответствуют отбору набора

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

Пустые или чужие значения — запись не заполнена корректно

Период в периодическом регистре
Норма

Даты заполнены и уникальны в рамках ключа

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

Пустые даты или ошибка дублирования ключа

Данные соседних отборов
Норма

Записи других объектов не изменились

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

Чужие записи исчезли — набор был записан без отбора

Типичные ошибки и ограничения

Большинство проблем при записи наборов связано с несколькими повторяющимися причинами. Их знание экономит часы отладки и защищает данные.

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

Дополнительное ограничение: записывать наборы регистров сведений в планах обмена с включённым распределением и в разделённых режимах следует с учётом прав и настроек разделителей — в сервисе запись чужих данных обычно заблокирована на уровне платформы.

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

Часто задаваемые вопросы

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

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

Как удалить все записи по конкретному значению измерения?

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

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

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

Можно ли записать набор в регистр, подчинённый регистратору?

Напрямую — нет. Такие регистры изменяются только через движения документа-регистратора: получите набор из коллекции движений документа, заполните его и запишите документ или его движения. Самостоятельный набор для подчинённого регистра платформа записать не даст.

Как записать записи с разными значениями измерений одним набором?

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

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

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

Итог

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

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