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

Дата: 21.09.2026 09:56:52
Регистр сведений
Программирование 1С
Доработка 1С
Записи
Комментарий:
0
Платформа:
8.3
Конфигурация:
Любая
Формы:
Любые

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

Имена регистров в примерах условные, подставьте метаданные своей конфигурации:

  • КурсыВалют — независимый, периодический (День): измерение Валюта, ресурсы Курс и Кратность;
  • НастройкиИнтеграции — независимый, непериодический: измерения Организация и ИмяНастройки, ресурс Значение;
  • ЦеныНоменклатуры — периодический, подчинён регистратору (документ УстановкаЦен): измерение Номенклатура, ресурс Цена;
  • НомераЗаявок — независимый, непериодический: измерение Префикс, ресурс ПоследнийНомер.

Весь код серверный. В тонком и веб-клиенте РегистрыСведений недоступны, поэтому запись размещают в общем модуле с флагом «Сервер», в модуле объекта или в процедуре формы с директивой &НаСервере или &НаСервереБезКонтекста. Если общий модуль вызывается с клиента, ему нужен ещё флаг «Вызов сервера». Как создать регистр и выбрать периодичность, описано в статье о регистре сведений.

Запись в регистр сведений 1С: менеджер записи или набор

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

ЗадачаСпособ
Создать или заменить одну записьМенеджерЗаписи.Записать()
Прочитать запись и изменить ресурсПрочитать(), Выбран(), Записать()
Удалить одну записьМенеджерЗаписи.Удалить()
Заменить все записи по измерениюНабор с Отбор и Записать()
Удалить записи по отборуПустой набор с отбором и Записать()
Дописать строки, не трогая остальныеОтбор по всем измерениям или Записать(Ложь)
Записать данные документаДвижения в ОбработкаПроведения
Загрузить тысячи строкНабор записей порциями
Прочитать и изменить при параллельной работеТранзакция и БлокировкаДанных

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

МенеджерЗаписи: создать, изменить, удалить одну запись

Чтобы записать строку, достаточно заполнить ключ и ресурсы и вызвать Записать(). Удаление — через Прочитать(), Выбран() и Удалить().

// Общий модуль с флагом «Сервер», например РаботаСКурсамиСервер
Процедура ЗаписатьКурс(Валюта, ДатаКурса, Курс, Кратность = 1) Экспорт

    МенеджерЗаписи = РегистрыСведений.КурсыВалют.СоздатьМенеджерЗаписи();
    МенеджерЗаписи.Период    = НачалоДня(ДатаКурса);
    МенеджерЗаписи.Валюта    = Валюта;
    МенеджерЗаписи.Курс      = Курс;
    МенеджерЗаписи.Кратность = Кратность;
    МенеджерЗаписи.Записать(); // запись с тем же ключом будет заменена

КонецПроцедуры

// Возвращает Истина, если запись была и её удалили
Функция УдалитьКурс(Валюта, ДатаКурса) Экспорт

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

    Если Не МенеджерЗаписи.Выбран() Тогда
        Возврат Ложь;
    КонецЕсли;

    МенеджерЗаписи.Удалить();
    Возврат Истина;

КонецФункции

Период и Валюта образуют ключ. Записать() без параметра работает с замещением: если курс валюты на этот день уже есть, он перезаписывается, другие записи не затрагиваются. Записать(Ложь) на существующем ключе вызовет исключение. При периодичности «День» курсы, записанные в 10:00 и в 15:00, — одна запись: платформа приводит период к началу интервала. НачалоДня() делает это явно, чтобы ключ при чтении и удалении совпадал с записанным. Выбран() возвращает Истина, только если Прочитать() нашёл запись.

Чтобы изменить один ресурс и не затереть остальные, запись сначала читают. Пример для модуля формы обработки: клиентская команда вызывает серверную функцию.

// Модуль формы обработки. Реквизиты объекта: Валюта, ДатаКурса, Кратность
&НаКлиенте
Процедура ИзменитьКратность(Команда)

    Если ИзменитьКратностьНаСервере(Объект.Валюта, Объект.ДатаКурса, Объект.Кратность) Тогда
        ПоказатьОповещениеПользователя("Кратность изменена");
    Иначе
        ПоказатьПредупреждение(, "Курс на эту дату не найден");
    КонецЕсли;

КонецПроцедуры

&НаСервереБезКонтекста
Функция ИзменитьКратностьНаСервере(Валюта, ДатаКурса, Кратность)

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

    Если Не МенеджерЗаписи.Выбран() Тогда
        Возврат Ложь;
    КонецЕсли;

    МенеджерЗаписи.Кратность = Кратность; // Курс остаётся тем, что прочитан из базы
    МенеджерЗаписи.Записать();
    Возврат Истина;

КонецФункции

Без Прочитать() вызов Записать() заменил бы запись целиком, и Курс стал бы нулевым. Чтение идёт строго по ключу: курс, установленный 14-го, на 15-е число не прочитается. Значение «на дату» получают через РегистрыСведений.КурсыВалют.ПолучитьПоследнее(НаДату, Новый Структура("Валюта", Валюта)) или срезом последних в запросе. Директива &НаСервереБезКонтекста не передаёт на сервер данные формы, только параметры, поэтому вызов лёгкий.

НаборЗаписей: отбор и замещение

Набор записывает сразу группу строк, а Отбор определяет, какие записи он заменит.

// Общий модуль с флагом «Сервер».
// Настройки — Соответствие: ключ — имя настройки, значение — строка
Процедура СохранитьНастройкиОрганизации(Организация, Настройки) Экспорт

    НаборЗаписей = РегистрыСведений.НастройкиИнтеграции.СоздатьНаборЗаписей();
    НаборЗаписей.Отбор.Организация.Установить(Организация);

    Для Каждого КлючИЗначение Из Настройки Цикл
        Запись = НаборЗаписей.Добавить();
        Запись.Организация  = Организация;
        Запись.ИмяНастройки = КлючИЗначение.Ключ;
        Запись.Значение     = КлючИЗначение.Значение;
    КонецЦикла;

    // Все прежние записи организации удаляются, пишется содержимое набора
    НаборЗаписей.Записать();

КонецПроцедуры

Процедура УдалитьНастройкиОрганизации(Организация) Экспорт

    НаборЗаписей = РегистрыСведений.НастройкиИнтеграции.СоздатьНаборЗаписей();
    НаборЗаписей.Отбор.Организация.Установить(Организация);
    НаборЗаписей.Записать(); // пустой набор с отбором — удаление по отбору

КонецПроцедуры

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

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

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

// Общий модуль с флагом «Сервер».
// Вариант 1: отбор по всем измерениям — заменяется только одна запись
Процедура УстановитьНастройку(Организация, ИмяНастройки, Значение) Экспорт

    НаборЗаписей = РегистрыСведений.НастройкиИнтеграции.СоздатьНаборЗаписей();
    НаборЗаписей.Отбор.Организация.Установить(Организация);
    НаборЗаписей.Отбор.ИмяНастройки.Установить(ИмяНастройки);

    Запись = НаборЗаписей.Добавить();
    Запись.Организация  = Организация;
    Запись.ИмяНастройки = ИмяНастройки;
    Запись.Значение     = Значение;
    НаборЗаписей.Записать();

КонецПроцедуры

// Вариант 2: дописать записи, ничего не удаляя
Процедура ДобавитьНастройки(Организация, Настройки) Экспорт

    НаборЗаписей = РегистрыСведений.НастройкиИнтеграции.СоздатьНаборЗаписей();
    НаборЗаписей.Отбор.Организация.Установить(Организация); // страховка

    Для Каждого КлючИЗначение Из Настройки Цикл
        Запись = НаборЗаписей.Добавить();
        Запись.Организация  = Организация;
        Запись.ИмяНастройки = КлючИЗначение.Ключ;
        Запись.Значение     = КлючИЗначение.Значение;
    КонецЦикла;

    НаборЗаписей.Записать(Ложь); // ключ уже есть в базе — исключение

КонецПроцедуры

В первом варианте отбор стоит по всем измерениям, и замещается ровно одна запись — как у менеджера записи. Во втором Записать(Ложь) только добавляет строки; если такой ключ уже есть, будет исключение. Отбор во втором варианте — страховка: если кто-то уберёт Ложь, пострадают записи одной организации, а не весь регистр. На платформе 8.3.25 и новее у независимого регистра есть режим Записать(РежимЗамещения.Слияние): записи с совпадающим ключом обновляются, новые добавляются, остальные не трогаются.

Подчинённый регистр: запись через Движения

Записи регистра, подчинённого регистратору, принадлежат документу. Их формируют в обработчике ОбработкаПроведения модуля объекта, а сам регистр отмечают на закладке «Движения» документа.

// Модуль объекта документа УстановкаЦен, табличная часть Товары (Номенклатура, Цена)
Процедура ОбработкаПроведения(Отказ, РежимПроведения)

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

    Для Каждого СтрокаТовары Из Товары Цикл
        Движение = Движения.ЦеныНоменклатуры.Добавить();
        Движение.Период       = Дата;
        Движение.Номенклатура = СтрокаТовары.Номенклатура;
        Движение.Цена         = СтрокаТовары.Цена;
    КонецЦикла;

КонецПроцедуры

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

Поправить движения уже проведённого документа из обработки можно набором с отбором по регистратору:

// Общий модуль с флагом «Сервер»
Процедура ИсправитьЦенуВДвижениях(Документ, Номенклатура, НоваяЦена) Экспорт

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

    Для Каждого Запись Из НаборЗаписей Цикл
        Если Запись.Номенклатура = Номенклатура Тогда
            Запись.Цена = НоваяЦена;
        КонецЕсли;
    КонецЦикла;

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

КонецПроцедуры

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

Пакетная запись большого количества строк

Менеджер записи на каждую строку — медленный путь: каждый Записать() выполняется отдельной транзакцией. Набор записывает сотни и тысячи строк за один вызов Записать().

// Общий модуль с флагом «Сервер».
// Курсы на одну дату. ТаблицаКурсов: колонки Валюта, Курс, Кратность
Процедура ЗагрузитьКурсыНаДату(ДатаКурсов, ТаблицаКурсов) Экспорт

    Период = НачалоДня(ДатаКурсов);
    НаборЗаписей = РегистрыСведений.КурсыВалют.СоздатьНаборЗаписей();
    НаборЗаписей.Отбор.Период.Установить(Период);

    Для Каждого СтрокаТаблицы Из ТаблицаКурсов Цикл
        Запись = НаборЗаписей.Добавить();
        ЗаполнитьЗначенияСвойств(Запись, СтрокаТаблицы);
        Запись.Период = Период;
    КонецЦикла;

    НаборЗаписей.Записать(); // курсы на эту дату заменяются целиком

КонецПроцедуры

// Первичная загрузка истории: таких ключей в регистре ещё нет.
// ТаблицаКурсов: колонки Период, Валюта, Курс, Кратность
Процедура ЗагрузитьИсториюКурсов(ТаблицаКурсов, РазмерПорции = 5000) Экспорт

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

    Для Каждого СтрокаТаблицы Из ТаблицаКурсов Цикл
        ЗаполнитьЗначенияСвойств(НаборЗаписей.Добавить(), СтрокаТаблицы);
        Если НаборЗаписей.Количество() >= РазмерПорции Тогда
            НаборЗаписей.Записать(Ложь);
            НаборЗаписей.Очистить();
        КонецЕсли;
    КонецЦикла;

    Если НаборЗаписей.Количество() > 0 Тогда
        НаборЗаписей.Записать(Ложь);
    КонецЕсли;

КонецПроцедуры

Первая процедура идемпотентна: отбор по периоду заменяет все курсы на дату, и повторная загрузка того же файла не создаёт дублей. Вторая дописывает историю порциями через Записать(Ложь) и Очистить(): память не растёт, каждая порция держит блокировки недолго. Если порция упадёт на дубле ключа, предыдущие останутся в базе. Для атомарности «всё или ничего» цикл оборачивают в транзакцию, но тогда блокировки на весь объём держатся до фиксации. Дубли ключа во входной таблице убирают заранее: после приведения периода к дню их бывает больше, чем кажется.

Удаление записей по условию

Отбор набора умеет только «равно». Чтобы удалить записи по условию «меньше», «больше» или по значению ресурса, ключи выбирают запросом и удаляют по одному.

// Общий модуль с флагом «Сервер».
// Удаляет курсы, установленные раньше даты ДатаГраницы
Процедура УдалитьКурсыДоДаты(ДатаГраницы) Экспорт

    Запрос = Новый Запрос;
    Запрос.Текст =
    "ВЫБРАТЬ
    |    КурсыВалют.Период КАК Период,
    |    КурсыВалют.Валюта КАК Валюта
    |ИЗ
    |    РегистрСведений.КурсыВалют КАК КурсыВалют
    |ГДЕ
    |    КурсыВалют.Период < &ДатаГраницы";
    Запрос.УстановитьПараметр("ДатаГраницы", ДатаГраницы);
    Выборка = Запрос.Выполнить().Выбрать();

    НаборЗаписей = РегистрыСведений.КурсыВалют.СоздатьНаборЗаписей();
    Пока Выборка.Следующий() Цикл
        НаборЗаписей.Отбор.Период.Установить(Выборка.Период);
        НаборЗаписей.Отбор.Валюта.Установить(Выборка.Валюта);
        НаборЗаписей.Записать(); // набор пуст — удаляется одна запись
    КонецЦикла;

КонецПроцедуры

Каждая итерация ставит отбор по полному ключу и записывает пустой набор — удаляется одна запись. Объект набора создаётся один раз: Установить() перезаписывает значение отбора. Для сотен тысяч записей условие сужают, например, до одного года за запуск.

Запись в транзакции с управляемой блокировкой

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

// Общий модуль с флагом «Сервер».
// Регистр НомераЗаявок: измерение Префикс (Строка), ресурс ПоследнийНомер (Число)
Функция СледующийНомер(Префикс) Экспорт

    НачатьТранзакцию();
    Попытка
        Блокировка = Новый БлокировкаДанных;
        ЭлементБлокировки = Блокировка.Добавить("РегистрСведений.НомераЗаявок");
        ЭлементБлокировки.УстановитьЗначение("Префикс", Префикс);
        ЭлементБлокировки.Режим = РежимБлокировкиДанных.Исключительный;
        Блокировка.Заблокировать();

        МенеджерЗаписи = РегистрыСведений.НомераЗаявок.СоздатьМенеджерЗаписи();
        МенеджерЗаписи.Префикс = Префикс;
        МенеджерЗаписи.Прочитать();
        Если Не МенеджерЗаписи.Выбран() Тогда
            МенеджерЗаписи.Префикс = Префикс; // записи ещё нет: ключ заполняем заново
            МенеджерЗаписи.ПоследнийНомер = 0;
        КонецЕсли;

        МенеджерЗаписи.ПоследнийНомер = МенеджерЗаписи.ПоследнийНомер + 1;
        Номер = МенеджерЗаписи.ПоследнийНомер;
        МенеджерЗаписи.Записать();

        ЗафиксироватьТранзакцию();
    Исключение
        ОтменитьТранзакцию();
        ВызватьИсключение;
    КонецПопытки;

    Возврат Номер;

КонецФункции

Исключительная блокировка по полю Префикс ставится до чтения, поэтому второй сеанс ждёт, пока первый зафиксирует транзакцию. В управляемом режиме обычное чтение внутри транзакции ничего не блокирует, и без Блокировка.Заблокировать() два пользователя получат один номер. НачатьТранзакцию() стоит прямо перед Попытка, а в блоке Исключение первым вызывается ОтменитьТранзакцию() — так рекомендуют стандарты разработки 1С. После неудачного Прочитать() ключ заполняется заново: на прежние значения полей менеджера не полагайтесь.

Типичные ошибки

  • «Запись с такими ключевыми полями существует». Код пишет без замещения (Записать(Ложь)) ключ, который уже есть в регистре. Уберите Ложь, если запись нужно заменить, или проверьте ключ заранее. Дубли ключа внутри одного набора платформа тоже не запишет.
  • «Метод объекта не обнаружен (СоздатьМенеджерЗаписи)». Регистр подчинён регистратору, менеджера записи у него нет. Используйте набор с отбором по регистратору или движения документа.
  • Набор подчинённого регистра без регистратора. Записать() вызывает исключение, пока не установлен Отбор.Регистратор: записи такого регистра без документа-владельца не существуют.
  • «Поле объекта не обнаружено (ЦеныНоменклатуры)». Регистр не отмечен в списке движений документа, поэтому его нет в коллекции Движения.
  • «Поле объекта не обнаружено (Период)». Код от периодического регистра перенесли на непериодический: у того нет поля Период ни в записи, ни в отборе.
  • «Переменная не определена (РегистрыСведений)». Обращение к регистру в клиентской процедуре. Перенесите запись в серверную функцию.
  • Пропали записи после сохранения. Сообщения нет, но отбор установлен не по всем измерениям или не установлен вовсе, и Записать() удалил лишнее.
  • Правки подчинённого регистра исчезли. Документ перепровели, и он заменил движения. Исправляйте документ, а не регистр.

Частые вопросы

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

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

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

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

Нужна ли транзакция, чтобы записать одну строку?

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

Как очистить регистр сведений целиком?

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

Когда проще заказать

Загрузка данных из внешней системы, перенос истории между регистрами или поиск причины, по которой пропадают записи, упираются в особенности конкретной конфигурации. Опишите задачу в форме размещения задания или выберите услугу по доработке 1С — программист оценит работу по вашей базе.

По теме

Не хотите разбираться сами?

Адаптируем это решение под вашу базу. Оценка бесплатно.

Оставить задачу

Станьте частью сообщества!
Войдите или зарегистрируйтесь, и вы сможете участвовать в обсуждениях.


1С, 1С:Предприятие — товарные знаки ООО «1С». Сайт не является официальным представительством фирмы «1С» и не аффилирован с ней.