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

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

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

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

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

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

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

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

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

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

Добавление одной записи через менеджер записи

Менеджер записи подходит для независимых регистров сведений, когда нужно добавить или обновить одну строку. Порядок действий: создать менеджер, заполнить измерения и ресурсы, вызвать Записать().

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

МенеджерЗаписи.Период = ТекущаяДатаСеанса();

МенеджерЗаписи.Валюта = ВалютаСсылка;

МенеджерЗаписи.Курс = 92.5;

МенеджерЗаписи.Записать(Истина);

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

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

bsl
МенеджерЗаписи = РегистрыСведений.ОтветственныеЛица.СоздатьМенеджерЗаписи();
МенеджерЗаписи.Организация = ОрганизацияСсылка;
МенеджерЗаписи.Сотрудник = СотрудникСсылка;
МенеджерЗаписи.ДатаНачала = НачалоДня(ТекущаяДатаСеанса());
МенеджерЗаписи.Записать(Истина);

Массовое добавление записей через набор записей

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

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

Для Каждого СтрокаДанных Из ТаблицаДанных Цикл

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

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

НоваяЗапись.ВидЦены = ВидЦеныСсылка;

НоваяЗапись.Цена = СтрокаДанных.Цена;

КонецЦикла;

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

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

Запись в регистр, подчинённый регистратору

Если регистр подчинён регистратору, записи в него добавляет документ при проведении. Программно это делается через коллекцию движений документа в обработчике ОбработкаПроведения:

Движения.СтатусыЗаказов.Записывать = Истина;

Движение = Движения.СтатусыЗаказов.Добавить();

Движение.Период = Дата;

Движение.Заказ = ЗаказСсылка;

Движение.Статус = Перечисления.СтатусыЗаказа.ВРаботе;

Строка Записывать = Истина обязательна: без неё платформа не будет записывать движения этого регистра при проведении. Альтернатива — установить свойство «Записывать движения» в конфигураторе, но установка флага в коде надёжнее, так как гарантирует запись независимо от настроек.

Если требуется внести записи в подчинённый регистр вне проведения документа, создайте набор записей, установите отбор по регистратору и запишите его. Учтите, что при следующем перепроведении документа такие «ручные» движения будут перезаписаны.

Выбор метода: сравнение вариантов

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

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

Одна запись в независимый регистр. Простой код, встроенный контроль уникальности. Не подходит для массовой вставки — медленно.

Набор записей без отбора

Массовая загрузка в независимый регистр одной транзакцией. Требует аккуратности с параметром замещения — риск стереть регистр.

Набор записей с отбором

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

Движения документа

Регистр подчинён регистратору. Единственный корректный способ для проводимых документов.

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

Проверка результата и контроль ошибок

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

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

МенеджерЗаписи.Период = ДатаКурса;

МенеджерЗаписи.Валюта = ВалютаСсылка;

МенеджерЗаписи.Прочитать();

Если МенеджерЗаписи.Выбран() Тогда

Сообщить("Запись найдена, курс: " + МенеджерЗаписи.Курс);

КонецЕсли;

Метод Выбран() возвращает Истина, если запись с указанным ключом существует. Это стандартный способ проверить наличие записи перед добавлением, чтобы избежать дублей или наоборот — убедиться, что перезапись произошла.

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

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

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

Прочитать() + Выбран() возвращает Истина

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

Выбран() = Ложь — запись не сохранилась, проверьте транзакцию и исключения

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

Все измерения заполнены осмысленными значениями

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

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

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

Совпадает с количеством строк источника (с учётом дублей по ключу)

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

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

Типичные ошибки при программной записи

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

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

Маршрут решения

Как выбрать действие

Нужно добавить или обновить одну запись в независимом регистреИспользуйте СоздатьМенеджерЗаписи() с Записать(Истина)
Нужно загрузить много записей из файла или таблицыИспользуйте набор записей с Записать(Ложь) внутри явной транзакции
Регистр подчинён регистраторуДобавляйте записи через Движения в обработчике проведения документа
Нужно полностью заменить данные по одному измерениюУстановите отбор набора по этому измерению и вызовите Записать(Истина)

Производительность при массовой записи

При загрузке больших объёмов (десятки тысяч строк и более) даже набор записей стоит дробить на порции по несколько тысяч записей, фиксируя транзакцию после каждой порции. Это снижает нагрузку на СУБД, уменьшает размер журнала транзакций и позволяет возобновить загрузку с места сбоя.

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

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

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

Чем отличается Записать(Истина) от Записать(Ложь) у набора записей?

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

Как проверить, существует ли запись, перед добавлением?

Создайте менеджер записи, заполните измерения (и период для периодического регистра), вызовите Прочитать() и проверьте метод Выбран(). Если он вернул Истина — запись с таким ключом уже есть. Альтернатива — запрос с отбором по измерениям.

Можно ли добавить запись в регистр сведений из внешней обработки?

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

Почему запись не сохраняется и не выдаёт ошибку?

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

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

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

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

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

Итог

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

Одна запись в независимый регистр — менеджер записи с Записать(Истина). Массовая загрузка — набор записей с Записать(Ложь) в транзакции. Подчинённый регистр — только через движения документа. Никогда не вызывайте Записать(Истина) у набора без отбора на рабочей базе и всегда проверяйте результат методом Прочитать() или запросом.