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