Разработка и Конфигурация · 12 мин
Как программно добавить записи в регистр сведений 1С
Как программно добавить записи в регистр сведений 1С: менеджер записи, набор записей, периодические регистры, обход блокировок и проверка результата.
Регистр сведений в 1С хранит данные в виде строк с измерениями, ресурсами и реквизитами, и добавить записи в него можно несколькими способами: через менеджер записи, через набор записей или через документ-регистратор. Выбор зависит от того, подчинён ли регистр регистратору, сколько записей нужно вставить и важна ли скорость операции.
Для независимого регистра сведений чаще всего используют менеджер записи — это самый простой и читаемый способ. Для массовой загрузки или записи в подчинённый регистр применяют набор записей. Ошибки на этом этапе типичны: дублирование записей по ключу измерений, нарушение периодичности, потеря данных при неправильном вызове метода Записать().
Ниже разобраны оба подхода с готовыми примерами кода на встроенном языке, правила выбора метода, типичные ошибки и способы проверить, что данные действительно попали в базу.
Что нужно знать о структуре регистра перед записью
Прежде чем писать код, откройте регистр в конфигураторе и уточните три вещи: режим подчинения (независимый или подчинён регистратору), периодичность (непериодический, в пределах секунды, дня, месяца и т.д.) и состав измерений. От этого зависит, какой программный интерфейс доступен и какие поля обязательны.
У независимого регистра уникальность записи определяется набором значений измерений (плюс период для периодических). Если вы попытаетесь записать вторую строку с тем же ключом измерений, платформа либо перезапишет существующую запись, либо выдаст ошибку — в зависимости от способа записи. У подчинённого регистра ключом служит регистратор, и писать в него «в обход» документа напрямую нельзя без указания регистратора.
Добавление одной записи через менеджер записи
Менеджер записи подходит для независимых регистров сведений, когда нужно добавить или обновить одну строку. Порядок действий: создать менеджер, заполнить измерения и ресурсы, вызвать Записать().
МенеджерЗаписи = РегистрыСведений.КурсыВалют.СоздатьМенеджерЗаписи();
МенеджерЗаписи.Период = ТекущаяДатаСеанса();
МенеджерЗаписи.Валюта = ВалютаСсылка;
МенеджерЗаписи.Курс = 92.5;
МенеджерЗаписи.Записать(Истина);
Параметр Истина в методе Записать() означает разрешить замещение существующей записи с тем же ключом. Если передать Ложь и запись с таким ключом уже есть, платформа выдаст ошибку о нарушении уникальности. В большинстве сценариев обновления данных (курсы валют, цены, настройки) замещение — ожидаемое поведение, но осознавайте, что старое значение будет потеряно без предупреждения.
Для непериодического регистра поле Период отсутствует — заполняйте только измерения и ресурсы. Обязательно заполните все измерения: незаполненное измерение примет пустое значение, и запись сохранится с пустым ключом, что затруднит последующий поиск и отборы.
МенеджерЗаписи = РегистрыСведений.ОтветственныеЛица.СоздатьМенеджерЗаписи();
МенеджерЗаписи.Организация = ОрганизацияСсылка;
МенеджерЗаписи.Сотрудник = СотрудникСсылка;
МенеджерЗаписи.ДатаНачала = НачалоДня(ТекущаяДатаСеанса());
МенеджерЗаписи.Записать(Истина);Массовое добавление записей через набор записей
Когда нужно вставить десятки или тысячи строк, менеджер записи становится неэффективным: каждая запись записывается отдельной операцией. Набор записей позволяет сформировать пакет строк в памяти и записать его одной транзакцией.
НаборЗаписей = РегистрыСведений.ЦеныНоменклатуры.СоздатьНаборЗаписей();
Для Каждого СтрокаДанных Из ТаблицаДанных Цикл
НоваяЗапись = НаборЗаписей.Добавить();
НоваяЗапись.Номенклатура = СтрокаДанных.Номенклатура;
НоваяЗапись.ВидЦены = ВидЦеныСсылка;
НоваяЗапись.Цена = СтрокаДанных.Цена;
КонецЦикла;
НаборЗаписей.Записать(Ложь);
Здесь важен параметр Ложь в методе Записать(): он означает «не замещать, а добавлять». Если передать Истина без установленного отбора, набор записей сотрёт всё содержимое регистра и запишет только новые строки. Это одна из самых опасных ошибок при работе с наборами записей — подробнее она разобрана в разделе об ошибках.
Запись в регистр, подчинённый регистратору
Если регистр подчинён регистратору, записи в него добавляет документ при проведении. Программно это делается через коллекцию движений документа в обработчике ОбработкаПроведения:
Движения.СтатусыЗаказов.Записывать = Истина;
Движение = Движения.СтатусыЗаказов.Добавить();
Движение.Период = Дата;
Движение.Заказ = ЗаказСсылка;
Движение.Статус = Перечисления.СтатусыЗаказа.ВРаботе;
Строка Записывать = Истина обязательна: без неё платформа не будет записывать движения этого регистра при проведении. Альтернатива — установить свойство «Записывать движения» в конфигураторе, но установка флага в коде надёжнее, так как гарантирует запись независимо от настроек.
Если требуется внести записи в подчинённый регистр вне проведения документа, создайте набор записей, установите отбор по регистратору и запишите его. Учтите, что при следующем перепроведении документа такие «ручные» движения будут перезаписаны.
Выбор метода: сравнение вариантов
Сравнение вариантов
Одна запись в независимый регистр. Простой код, встроенный контроль уникальности. Не подходит для массовой вставки — медленно.
Массовая загрузка в независимый регистр одной транзакцией. Требует аккуратности с параметром замещения — риск стереть регистр.
Обновление группы записей по конкретному измерению или регистратору. Безопасная замена части данных.
Регистр подчинён регистратору. Единственный корректный способ для проводимых документов.
Правило выбора простое: одна запись в независимый регистр — менеджер записи; много записей — набор записей; подчинённый регистр — движения документа. Отклонение от этого правила обычно приводит либо к проблемам производительности, либо к потере данных.
Проверка результата и контроль ошибок
После записи убедитесь, что данные действительно в регистре. Самый быстрый способ — запрос или метод Прочитать() менеджера записи:
МенеджерЗаписи = РегистрыСведений.КурсыВалют.СоздатьМенеджерЗаписи();
МенеджерЗаписи.Период = ДатаКурса;
МенеджерЗаписи.Валюта = ВалютаСсылка;
МенеджерЗаписи.Прочитать();
Если МенеджерЗаписи.Выбран() Тогда
Сообщить("Запись найдена, курс: " + МенеджерЗаписи.Курс);
КонецЕсли;
Метод Выбран() возвращает Истина, если запись с указанным ключом существует. Это стандартный способ проверить наличие записи перед добавлением, чтобы избежать дублей или наоборот — убедиться, что перезапись произошла.
Как проверить результат
Прочитать() + Выбран() возвращает Истина
Выбран() = Ложь — запись не сохранилась, проверьте транзакцию и исключения
Все измерения заполнены осмысленными значениями
Пустые измерения — запись сохранена с пустым ключом
Совпадает с количеством строк источника (с учётом дублей по ключу)
Меньше ожидаемого — возможны дубли по ключу измерений, которые заместили друг друга
Типичные ошибки при программной записи
Для массовых операций оборачивайте запись в транзакцию (НачатьТранзакцию() / ЗафиксироватьТранзакцию() / ОтменитьТранзакцию()) — тогда при ошибке база останется в исходном состоянии. Для разовых вставок через менеджер записи платформа сама управляет транзакцией, но конструкция Попытка...Исключение всё равно полезна для логирования причины сбоя.
Как выбрать действие
Производительность при массовой записи
При загрузке больших объёмов (десятки тысяч строк и более) даже набор записей стоит дробить на порции по несколько тысяч записей, фиксируя транзакцию после каждой порции. Это снижает нагрузку на СУБД, уменьшает размер журнала транзакций и позволяет возобновить загрузку с места сбоя.
Дополнительно отключайте на время загрузку итоги и индексирование там, где это применимо, а в файловых базах избегайте параллельной работы пользователей с тем же регистром. После завершения проверьте количество записей запросом и сверьте контрольные суммы или итоговые значения с источником.
При загрузке данных из внешних источников сначала сворачивайте таблицу по ключу измерений (Свернуть() у таблицы значений). Это уберёт дубли до записи и покажет реальное количество уникальных строк — проще сверять результат с источником.
Часто задаваемые вопросы
Чем отличается Записать(Истина) от Записать(Ложь) у набора записей?
Параметр управляет замещением. Истина означает: удалить все записи, попадающие под текущий отбор набора (а без отбора — все записи регистра), и записать содержимое набора. Ложь — добавить записи набора к существующим без удаления. Для массового добавления почти всегда нужен вариант Ложь.
Как проверить, существует ли запись, перед добавлением?
Создайте менеджер записи, заполните измерения (и период для периодического регистра), вызовите Прочитать() и проверьте метод Выбран(). Если он вернул Истина — запись с таким ключом уже есть. Альтернатива — запрос с отбором по измерениям.
Можно ли добавить запись в регистр сведений из внешней обработки?
Да, код ничем не отличается: те же РегистрыСведений.ИмяРегистра.СоздатьМенеджерЗаписи() или СоздатьНаборЗаписей(). Ограничение одно — у пользователя, запускающего обработку, должны быть права на изменение этого регистра. В безопасном режиме внешних обработок доступ к данным может быть дополнительно ограничен настройками.
Почему запись не сохраняется и не выдаёт ошибку?
Частая причина — код выполняется внутри транзакции, которая затем откатывается (например, исключение перехвачено выше по стеку и транзакция отменена). Другая причина — запись выполняется в обработчике, где платформа сама перезаписывает набор после вашего кода. Проверьте логику транзакций и порядок вызова обработчиков.
Как добавить записи в периодический регистр за разные даты?
Используйте набор записей: для каждой даты добавляйте строку методом Добавить() и заполняйте поле Период нужной датой. Учтите точность периодичности регистра: если регистр периодичен в пределах дня, две записи с разным временем одного дня заместят друг друга — приводите период к началу дня через НачалоДня().
Что быстрее: менеджер записи или набор записей?
Для одной записи разница незаметна. Для массовой вставки набор записей быстрее на порядки: одна операция записи вместо тысяч отдельных. Если в цикле вы вызываете Записать() у менеджера записи, а загрузка идёт медленно — перепишите код на набор записей с порционной фиксацией транзакций.
Что важно запомнить
Одна запись в независимый регистр — менеджер записи с Записать(Истина). Массовая загрузка — набор записей с Записать(Ложь) в транзакции. Подчинённый регистр — только через движения документа. Никогда не вызывайте Записать(Истина) у набора без отбора на рабочей базе и всегда проверяйте результат методом Прочитать() или запросом.