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

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

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

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

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

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

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

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

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

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

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

Запись одной строки через менеджер записи

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

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

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

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

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

МенеджерЗаписи.Кратность = 1;

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

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

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

Пакетная запись через набор записей

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

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

НаборЗаписей.Отбор.ТипЦен.Установить(ТипЦенСсылка);

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

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

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

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

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

КонецЦикла;

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

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

Критически важный момент: если вы установили отбор и вызвали Записать(Истина) на пустом наборе, все записи по этому отбору будут удалены. Это штатный способ очистки данных по отбору, но при ошибке в отборе можно удалить лишнее. Всегда проверяйте, что отбор установлен корректно и до записи.

Особенности периодических регистров и регистров с регистратором

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

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

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

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

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

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

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

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

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

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

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

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

Порядок действий при записи одной записи
  1. 1
    Определите структуру регистра: измерения, периодичность, подчинение регистратору
  2. 2
    Создайте менеджер записи через РегистрыСведений.ИмяРегистра.СоздатьМенеджерЗаписи()
  3. 3
    Заполните все измерения и период (для периодического регистра)
  4. 4
    Заполните ресурсы и нужные реквизиты
  5. 5
    Вызовите Записать() и перехватите возможное исключение
  6. 6
    Проверьте результат запросом или через форму списка регистра

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

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

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| КурсыВалют.Период,

| КурсыВалют.Курс

|ИЗ

| РегистрСведений.КурсыВалют КАК КурсыВалют

|ГДЕ

| КурсыВалют.Валюта = &Валюта";

Запрос.УстановитьПараметр("Валюта", ВалютаСсылка);

Результат = Запрос.Выполнить().Выгрузить();

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

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

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

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

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

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

Меньше ожидаемого или ноль — часть данных не записалась

Значения ключевых ресурсов
Норма

Соответствуют источнику данных

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

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

Данные вне отбора
Норма

Не изменились

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

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

Типичные ошибки и способы их избежать

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

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

Ещё одна группа проблем — права доступа. Код, выполняемый в контексте пользователя, может молча не записать данные, если у пользователя нет прав на изменение регистра. В серверных процедурах, где это осознанное решение, используйте УстановитьПривилегированныйРежим(Истина), но только там, где это действительно необходимо.

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

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

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

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

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

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

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

Напрямую — нет. Такие регистры изменяются только через движения документа: в обработке проведения заполните коллекцию Движения.ИмяРегистра и установите свойство Записывать = Истина. Альтернатива для служебных сценариев — создать набор записей с отбором по регистратору и записать его, но это должно быть согласовано с логикой проведения документа.

Как удалить все записи регистра сведений по условию?

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

Почему код выполняется без ошибок, но записи в регистре не появляются?

Чаще всего причины такие: исключение перехвачено пустым блоком Попытка/Исключение; у пользователя нет прав на изменение регистра; транзакция была отменена выше по стеку вызовов; запись выполняется, но сразу затирается другим кодом или обменом данными. Проверяйте журнал регистрации и добавляйте осмысленную обработку исключений с выводом текста ошибки.

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

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

Итог

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

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