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