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