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